Mercurial > sdl-ios-xcode
diff src/audio/mme/SDL_mmeaudio.c @ 2049:5f6550e5184f
Merged SDL-ryan-multiple-audio-device branch r2803:2871 into the trunk.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Tue, 17 Oct 2006 09:15:21 +0000 |
parents | b3741f227757 |
children | 866052b01ee5 |
line wrap: on
line diff
--- a/src/audio/mme/SDL_mmeaudio.c Sun Oct 01 16:10:41 2006 +0000 +++ b/src/audio/mme/SDL_mmeaudio.c Tue Oct 17 09:15:21 2006 +0000 @@ -31,70 +31,6 @@ static BOOL inUse[NUM_BUFFERS]; -/* Audio driver functions */ -static int MME_OpenAudio(_THIS, SDL_AudioSpec * spec); -static void MME_WaitAudio(_THIS); -static Uint8 *MME_GetAudioBuf(_THIS); -static void MME_PlayAudio(_THIS); -static void MME_WaitDone(_THIS); -static void MME_CloseAudio(_THIS); - -/* Audio driver bootstrap functions */ -static int -Audio_Available(void) -{ - return (1); -} - -static void -Audio_DeleteDevice(SDL_AudioDevice * device) -{ - if (device) { - if (device->hidden) { - SDL_free(device->hidden); - device->hidden = NULL; - } - SDL_free(device); - device = NULL; - } -} - -static SDL_AudioDevice * -Audio_CreateDevice(int devindex) -{ - SDL_AudioDevice *this; - -/* Initialize all variables that we clean on shutdown */ - this = SDL_malloc(sizeof(SDL_AudioDevice)); - if (this) { - SDL_memset(this, 0, (sizeof *this)); - this->hidden = SDL_malloc((sizeof *this->hidden)); - } - if ((this == NULL) || (this->hidden == NULL)) { - SDL_OutOfMemory(); - if (this) { - SDL_free(this); - } - return (0); - } - SDL_memset(this->hidden, 0, (sizeof *this->hidden)); - /* Set the function pointers */ - this->OpenAudio = MME_OpenAudio; - this->WaitAudio = MME_WaitAudio; - this->PlayAudio = MME_PlayAudio; - this->GetAudioBuf = MME_GetAudioBuf; - this->WaitDone = MME_WaitDone; - this->CloseAudio = MME_CloseAudio; - this->free = Audio_DeleteDevice; - - return this; -} - -AudioBootStrap MMEAUDIO_bootstrap = { - "waveout", "Tru64 MME WaveOut", - Audio_Available, Audio_CreateDevice -}; - static void SetMMerror(char *function, MMRESULT code) { @@ -108,7 +44,7 @@ } static void CALLBACK -MME_CALLBACK(HWAVEOUT hwo, +MME_Callback(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, LPARAM dwParam1, LPARAM dwParam2) { WAVEHDR *wp = (WAVEHDR *) dwParam1; @@ -118,116 +54,137 @@ } static int -MME_OpenAudio(_THIS, SDL_AudioSpec * spec) +MME_OpenDevice(_THIS, const char *devname, int iscapture) { + int valid_format = 0; MMRESULT result; + Uint8 *mixbuf = NULL; int i; - mixbuf = NULL; + /* Initialize all variables that we clean on shutdown */ + this->hidden = (struct SDL_PrivateAudioData *) + SDL_malloc((sizeof *this->hidden)); + if (this->hidden == NULL) { + SDL_OutOfMemory(); + return 0; + } + SDL_memset(this->hidden, 0, (sizeof *this->hidden)); /* Set basic WAVE format parameters */ - shm = mmeAllocMem(sizeof(*shm)); - if (shm == NULL) { - SDL_SetError("Out of memory: shm"); - return (-1); + this->hidden->shm = mmeAllocMem(sizeof(*this->hidden->shm)); + if (this->hidden->shm == NULL) { + MME_CloseDevice(this); + SDL_OutOfMemory(); + return 0; } - shm->sound = 0; - shm->wFmt.wf.wFormatTag = WAVE_FORMAT_PCM; + + SDL_memset(this->hidden->shm, '\0', sizeof (*this->hidden->shm)); + this->hidden->shm->sound = 0; + this->hidden->shm->wFmt.wf.wFormatTag = WAVE_FORMAT_PCM; /* Determine the audio parameters from the AudioSpec */ - switch (SDL_AUDIO_BITSIZE(spec->format)) { - case 8: - /* Unsigned 8 bit audio data */ - spec->format = AUDIO_U8; - shm->wFmt.wBitsPerSample = 8; - break; - case 16: - /* Signed 16 bit audio data */ - spec->format = AUDIO_S16; - shm->wFmt.wBitsPerSample = 16; - break; - case 32: - /* Signed 32 bit audio data */ - spec->format = AUDIO_S32; - shm->wFmt.wBitsPerSample = 32; - break; - default: + /* Try for a closest match on audio format */ + for (test_format = SDL_FirstAudioFormat(this->spec.format); + !valid_format && test_format;) { + valid_format = 1; + switch (test_format) { + case AUDIO_U8: + case AUDIO_S16: + case AUDIO_S32: + break; + default: + valid_format = 0; + test_format = SDL_NextAudioFormat(); + } + } + + if (!valid_format) { + MME_CloseDevice(this); SDL_SetError("Unsupported audio format"); - return (-1); + return 0; } + this->spec.format = test_format; + this->hidden->shm->wFmt.wBitsPerSample = SDL_AUDIO_BITSIZE(test_format); + /* !!! FIXME: Can this handle more than stereo? */ - shm->wFmt.wf.nChannels = spec->channels; - shm->wFmt.wf.nSamplesPerSec = spec->freq; - shm->wFmt.wf.nBlockAlign = - shm->wFmt.wf.nChannels * shm->wFmt.wBitsPerSample / 8; - shm->wFmt.wf.nAvgBytesPerSec = - shm->wFmt.wf.nSamplesPerSec * shm->wFmt.wf.nBlockAlign; + this->hidden->shm->wFmt.wf.nChannels = this->spec.channels; + this->hidden->shm->wFmt.wf.nSamplesPerSec = this->spec.freq; + this->hidden->shm->wFmt.wf.nBlockAlign = + this->hidden->shm->wFmt.wf.nChannels * + this->hidden->shm->wFmt.wBitsPerSample / 8; + this->hidden->shm->wFmt.wf.nAvgBytesPerSec = + this->hidden->shm->wFmt.wf.nSamplesPerSec * + this->hidden->shm->wFmt.wf.nBlockAlign; /* Check the buffer size -- minimum of 1/4 second (word aligned) */ - if (spec->samples < (spec->freq / 4)) - spec->samples = ((spec->freq / 4) + 3) & ~3; + if (this->spec.samples < (this->spec.freq / 4)) + this->spec.samples = ((this->spec.freq / 4) + 3) & ~3; /* Update the fragment size as size in bytes */ - SDL_CalculateAudioSpec(spec); + SDL_CalculateAudioSpec(&this->spec); /* Open the audio device */ - result = waveOutOpen(&(shm->sound), + result = waveOutOpen(&(this->hidden->shm->sound), WAVE_MAPPER, - &(shm->wFmt.wf), - MME_CALLBACK, + &(this->hidden->shm->wFmt.wf), + MME_Callback, NULL, (CALLBACK_FUNCTION | WAVE_OPEN_SHAREABLE)); if (result != MMSYSERR_NOERROR) { + MME_CloseDevice(this); SetMMerror("waveOutOpen()", result); - return (-1); + return 0; } /* Create the sound buffers */ - mixbuf = (Uint8 *) mmeAllocBuffer(NUM_BUFFERS * (spec->size)); + mixbuf = (Uint8 *) mmeAllocBuffer(NUM_BUFFERS * (this->spec.size)); if (mixbuf == NULL) { - SDL_SetError("Out of memory: mixbuf"); - return (-1); + MME_CloseDevice(this); + SDL_OutOfMemory(); + return 0; } + this->hidden->mixbuf = mixbuf; for (i = 0; i < NUM_BUFFERS; i++) { - shm->wHdr[i].lpData = &mixbuf[i * (spec->size)]; - shm->wHdr[i].dwBufferLength = spec->size; - shm->wHdr[i].dwFlags = 0; - shm->wHdr[i].dwUser = i; - shm->wHdr[i].dwLoops = 0; /* loop control counter */ - shm->wHdr[i].lpNext = NULL; /* reserved for driver */ - shm->wHdr[i].reserved = 0; + this->hidden->shm->wHdr[i].lpData = &mixbuf[i * (this->spec.size)]; + this->hidden->shm->wHdr[i].dwBufferLength = this->spec.size; + this->hidden->shm->wHdr[i].dwFlags = 0; + this->hidden->shm->wHdr[i].dwUser = i; + this->hidden->shm->wHdr[i].dwLoops = 0; /* loop control counter */ + this->hidden->shm->wHdr[i].lpNext = NULL; /* reserved for driver */ + this->hidden->shm->wHdr[i].reserved = 0; inUse[i] = FALSE; } - next_buffer = 0; - return 0; + this->hidden->next_buffer = 0; + + return 1; } static void -MME_WaitAudio(_THIS) +MME_WaitDevice(_THIS) { - while (inUse[next_buffer]) { + while (inUse[this->hidden->next_buffer]) { mmeWaitForCallbacks(); mmeProcessCallbacks(); } } static Uint8 * -MME_GetAudioBuf(_THIS) +MME_GetDeviceBuf(_THIS) { - Uint8 *retval; - - inUse[next_buffer] = TRUE; - retval = (Uint8 *) (shm->wHdr[next_buffer].lpData); - return retval; + void *retval = this->hidden->shm->wHdr[this->hidden->next_buffer].lpData; + inUse[this->hidden->next_buffer] = TRUE; + return (Uint8 *) retval; } static void -MME_PlayAudio(_THIS) +MME_PlayDevice(_THIS) { /* Queue it up */ - waveOutWrite(shm->sound, &(shm->wHdr[next_buffer]), sizeof(WAVEHDR)); - next_buffer = (next_buffer + 1) % NUM_BUFFERS; + waveOutWrite(this->hidden->shm->sound, + &(this->hidden->shm->wHdr[this->hidden->next_buffer]), + sizeof (WAVEHDR)); + this->hidden->next_buffer = (this->hidden->next_buffer + 1) % NUM_BUFFERS; } static void @@ -236,13 +193,13 @@ MMRESULT result; int i; - if (shm->sound) { + if (this->hidden->shm->sound) { for (i = 0; i < NUM_BUFFERS; i++) while (inUse[i]) { mmeWaitForCallbacks(); mmeProcessCallbacks(); } - result = waveOutReset(shm->sound); + result = waveOutReset(this->hidden->shm->sound); if (result != MMSYSERR_NOERROR) SetMMerror("waveOutReset()", result); mmeProcessCallbacks(); @@ -250,29 +207,54 @@ } static void -MME_CloseAudio(_THIS) +MME_CloseDevice(_THIS) { - MMRESULT result; + if (this->hidden != NULL) { + MMRESULT result; - if (mixbuf) { - result = mmeFreeBuffer(mixbuf); - if (result != MMSYSERR_NOERROR) - SetMMerror("mmeFreeBuffer", result); - mixbuf = NULL; - } + if (this->hidden->mixbuf) { + result = mmeFreeBuffer(this->hidden->mixbuf); + if (result != MMSYSERR_NOERROR) + SetMMerror("mmeFreeBuffer", result); + this->hidden->mixbuf = NULL; + } - if (shm) { - if (shm->sound) { - result = waveOutClose(shm->sound); + if (this->hidden->shm) { + if (this->hidden->shm->sound) { + result = waveOutClose(this->hidden->shm->sound); + if (result != MMSYSERR_NOERROR) + SetMMerror("waveOutClose()", result); + mmeProcessCallbacks(); + } + result = mmeFreeMem(this->hidden->shm); if (result != MMSYSERR_NOERROR) - SetMMerror("waveOutClose()", result); - mmeProcessCallbacks(); + SetMMerror("mmeFreeMem()", result); + this->hidden->shm = NULL; } - result = mmeFreeMem(shm); - if (result != MMSYSERR_NOERROR) - SetMMerror("mmeFreeMem()", result); - shm = NULL; + + SDL_free(this->hidden); + this->hidden = NULL; } } +static int +MME_Init(SDL_AudioDriverImpl *impl) +{ + /* Set the function pointers */ + impl->OpenDevice = MME_OpenDevice; + impl->WaitDevice = MME_WaitDevice; + impl->WaitDone = MME_WaitDone; + impl->PlayDevice = MME_PlayDevice; + impl->GetDeviceBuf = MME_GetDeviceBuf; + impl->CloseDevice = MME_CloseDevice; + impl->OnlyHasDefaultOutputDevice = 1; + + return 1; +} + +/* !!! FIXME: Windows "windib" driver is called waveout, too */ +AudioBootStrap MMEAUDIO_bootstrap = { + "waveout", "Tru64 MME WaveOut", MME_Init, 0 +}; + /* vi: set ts=4 sw=4 expandtab: */