123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601 |
- /*
- Simple DirectMedia Layer
- Copyright (C) 1997-2023 Sam Lantinga <[email protected]>
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
- */
- #include "../../SDL_internal.h"
- #if SDL_AUDIO_DRIVER_OS2
- /* Allow access to a raw mixing buffer */
- #include "../../core/os2/SDL_os2.h"
- #include "SDL_audio.h"
- #include "../SDL_audio_c.h"
- #include "SDL_os2audio.h"
- static PMCI_MIX_BUFFER _getNextBuffer(SDL_PrivateAudioData *pAData, PMCI_MIX_BUFFER pBuffer)
- {
- PMCI_MIX_BUFFER pFirstBuffer = &pAData->aMixBuffers[0];
- PMCI_MIX_BUFFER pLastBuffer = &pAData->aMixBuffers[pAData->cMixBuffers -1];
- return (pBuffer == pLastBuffer ? pFirstBuffer : pBuffer+1);
- }
- static ULONG _getEnvULong(const char *name, ULONG ulMax, ULONG ulDefault)
- {
- ULONG ulValue;
- char* end;
- char* envval = SDL_getenv(name);
- if (envval == NULL)
- return ulDefault;
- ulValue = SDL_strtoul(envval, &end, 10);
- return (end == envval) || (ulValue > ulMax)? ulDefault : ulMax;
- }
- static int _MCIError(const char *func, ULONG ulResult)
- {
- CHAR acBuf[128];
- mciGetErrorString(ulResult, acBuf, sizeof(acBuf));
- return SDL_SetError("[%s] %s", func, acBuf);
- }
- static void _mixIOError(const char *function, ULONG ulRC)
- {
- debug_os2("%s() - failed, rc = 0x%lX (%s)",
- function, ulRC,
- (ulRC == MCIERR_INVALID_MODE) ? "Mixer mode does not match request" :
- (ulRC == MCIERR_INVALID_BUFFER) ? "Caller sent an invalid buffer" : "unknown");
- }
- static LONG APIENTRY cbAudioWriteEvent(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer,
- ULONG ulFlags)
- {
- SDL_AudioDevice *_this = (SDL_AudioDevice *)pBuffer->ulUserParm;
- SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden;
- ULONG ulRC;
- debug_os2("cbAudioWriteEvent: ulStatus = %lu, pBuffer = %p, ulFlags = %#lX",ulStatus,pBuffer,ulFlags);
- if (pAData->ulState == 2)
- {
- return 0;
- }
- if (ulFlags != MIX_WRITE_COMPLETE) {
- debug_os2("flags = 0x%lX", ulFlags);
- return 0;
- }
- pAData->pDrainBuffer = pBuffer;
- ulRC = pAData->stMCIMixSetup.pmixWrite(pAData->stMCIMixSetup.ulMixHandle,
- pAData->pDrainBuffer, 1);
- if (ulRC != MCIERR_SUCCESS) {
- _mixIOError("pmixWrite", ulRC);
- return 0;
- }
- ulRC = DosPostEventSem(pAData->hevBuf);
- if (ulRC != NO_ERROR && ulRC != ERROR_ALREADY_POSTED) {
- debug_os2("DosPostEventSem(), rc = %lu", ulRC);
- }
- return 1; /* return value doesn't seem to matter. */
- }
- static LONG APIENTRY cbAudioReadEvent(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer,
- ULONG ulFlags)
- {
- SDL_AudioDevice *_this = (SDL_AudioDevice *)pBuffer->ulUserParm;
- SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden;
- ULONG ulRC;
- debug_os2("cbAudioReadEvent: ulStatus = %lu, pBuffer = %p, ulFlags = %#lX",ulStatus,pBuffer,ulFlags);
- if (pAData->ulState == 2)
- {
- return 0;
- }
- if (ulFlags != MIX_READ_COMPLETE) {
- debug_os2("flags = 0x%lX", ulFlags);
- return 0;
- }
- pAData->pFillBuffer = pBuffer;
- if (pAData->pFillBuffer == pAData->aMixBuffers)
- {
- ulRC = pAData->stMCIMixSetup.pmixRead(pAData->stMCIMixSetup.ulMixHandle,
- pAData->pFillBuffer, pAData->cMixBuffers);
- if (ulRC != MCIERR_SUCCESS) {
- _mixIOError("pmixRead", ulRC);
- return 0;
- }
- }
- ulRC = DosPostEventSem(pAData->hevBuf);
- if (ulRC != NO_ERROR && ulRC != ERROR_ALREADY_POSTED) {
- debug_os2("DosPostEventSem(), rc = %lu", ulRC);
- }
- return 1;
- }
- static void OS2_DetectDevices(void)
- {
- MCI_SYSINFO_PARMS stMCISysInfo;
- CHAR acBuf[256];
- ULONG ulDevicesNum;
- MCI_SYSINFO_LOGDEVICE stLogDevice;
- MCI_SYSINFO_PARMS stSysInfoParams;
- ULONG ulRC;
- ULONG ulNumber;
- MCI_GETDEVCAPS_PARMS stDevCapsParams;
- MCI_OPEN_PARMS stMCIOpen;
- MCI_GENERIC_PARMS stMCIGenericParams;
- SDL_memset(&stMCISysInfo, 0, sizeof(stMCISysInfo));
- acBuf[0] = '\0';
- stMCISysInfo.pszReturn = acBuf;
- stMCISysInfo.ulRetSize = sizeof(acBuf);
- stMCISysInfo.usDeviceType = MCI_DEVTYPE_AUDIO_AMPMIX;
- ulRC = mciSendCommand(0, MCI_SYSINFO, MCI_WAIT | MCI_SYSINFO_QUANTITY,
- &stMCISysInfo, 0);
- if (LOUSHORT(ulRC) != MCIERR_SUCCESS) {
- debug_os2("MCI_SYSINFO, MCI_SYSINFO_QUANTITY - failed, rc = 0x%hX", LOUSHORT(ulRC));
- return;
- }
- ulDevicesNum = SDL_strtoul(stMCISysInfo.pszReturn, NULL, 10);
- for (ulNumber = 1; ulNumber <= ulDevicesNum;
- ulNumber++) {
- /* Get device install name. */
- stSysInfoParams.ulNumber = ulNumber;
- stSysInfoParams.pszReturn = acBuf;
- stSysInfoParams.ulRetSize = sizeof(acBuf);
- stSysInfoParams.usDeviceType = MCI_DEVTYPE_AUDIO_AMPMIX;
- ulRC = mciSendCommand(0, MCI_SYSINFO, MCI_WAIT | MCI_SYSINFO_INSTALLNAME,
- &stSysInfoParams, 0);
- if (LOUSHORT(ulRC) != MCIERR_SUCCESS) {
- debug_os2("MCI_SYSINFO, MCI_SYSINFO_INSTALLNAME - failed, rc = 0x%hX", LOUSHORT(ulRC));
- continue;
- }
- /* Get textual product description. */
- stSysInfoParams.ulItem = MCI_SYSINFO_QUERY_DRIVER;
- stSysInfoParams.pSysInfoParm = &stLogDevice;
- SDL_strlcpy(stLogDevice.szInstallName, stSysInfoParams.pszReturn, MAX_DEVICE_NAME);
- ulRC = mciSendCommand(0, MCI_SYSINFO, MCI_WAIT | MCI_SYSINFO_ITEM,
- &stSysInfoParams, 0);
- if (LOUSHORT(ulRC) != MCIERR_SUCCESS) {
- debug_os2("MCI_SYSINFO, MCI_SYSINFO_ITEM - failed, rc = 0x%hX", LOUSHORT(ulRC));
- continue;
- }
- SDL_AddAudioDevice(0, stLogDevice.szProductInfo, NULL, (void *)ulNumber);
- /* Open audio device for querying its capabilities */
- /* at this point we HAVE TO OPEN the waveaudio device and not the ampmix device */
- /* because only the waveaudio device (tied to the ampmix device) supports querying for playback/record capability */
- SDL_memset(&stMCIOpen, 0, sizeof(stMCIOpen));
- stMCIOpen.pszDeviceType = (PSZ)MAKEULONG(MCI_DEVTYPE_WAVEFORM_AUDIO,LOUSHORT(ulNumber));
- ulRC = mciSendCommand(0, MCI_OPEN,MCI_WAIT | MCI_OPEN_TYPE_ID | MCI_OPEN_SHAREABLE,&stMCIOpen, 0);
- if (LOUSHORT(ulRC) != MCIERR_SUCCESS) {
- debug_os2("MCI_OPEN (getDevCaps) - failed");
- continue;
- }
- /* check for recording capability */
- SDL_memset(&stDevCapsParams, 0, sizeof(stDevCapsParams));
- stDevCapsParams.ulItem = MCI_GETDEVCAPS_CAN_RECORD;
- ulRC = mciSendCommand(stMCIOpen.usDeviceID, MCI_GETDEVCAPS, MCI_WAIT | MCI_GETDEVCAPS_ITEM,
- &stDevCapsParams, 0);
- if (LOUSHORT(ulRC) != MCIERR_SUCCESS) {
- debug_os2("MCI_GETDEVCAPS, MCI_GETDEVCAPS_ITEM - failed, rc = 0x%hX", LOUSHORT(ulRC));
- }
- else {
- if (stDevCapsParams.ulReturn) {
- SDL_AddAudioDevice(1, stLogDevice.szProductInfo, NULL, (void *)(ulNumber | 0x80000000));
- }
- }
- /* close the audio device, we are done querying its capabilities */
- SDL_memset(&stMCIGenericParams, 0, sizeof(stMCIGenericParams));
- ulRC = mciSendCommand(stMCIOpen.usDeviceID, MCI_CLOSE, MCI_WAIT,
- &stMCIGenericParams, 0);
- if (LOUSHORT(ulRC) != MCIERR_SUCCESS) {
- debug_os2("MCI_CLOSE (getDevCaps) - failed");
- }
- }
- }
- static void OS2_WaitDevice(_THIS)
- {
- SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden;
- ULONG ulRC;
- debug_os2("Enter");
- /* Wait for an audio chunk to finish */
- ulRC = DosWaitEventSem(pAData->hevBuf, 5000);
- if (ulRC != NO_ERROR) {
- debug_os2("DosWaitEventSem(), rc = %lu", ulRC);
- }
- }
- static Uint8 *OS2_GetDeviceBuf(_THIS)
- {
- SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden;
- debug_os2("Enter");
- return (Uint8 *) pAData->pFillBuffer->pBuffer;
- }
- static void OS2_PlayDevice(_THIS)
- {
- SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden;
- ULONG ulRC;
- PMCI_MIX_BUFFER pMixBuffer = NULL;
- debug_os2("Enter");
- pMixBuffer = pAData->pDrainBuffer;
- pAData->pFillBuffer = _getNextBuffer(pAData, pAData->pFillBuffer);
- if (!pAData->ulState && pAData->pFillBuffer != pMixBuffer)
- {
- /*
- * this buffer was filled but we have not yet filled all buffers
- * so just signal event sem so that OS2_WaitDevice does not need
- * to block
- */
- ulRC = DosPostEventSem(pAData->hevBuf);
- }
- if (!pAData->ulState && (pAData->pFillBuffer == pMixBuffer) )
- {
- debug_os2("!hasStarted");
- pAData->ulState = 1;
- /* Write buffers to kick off the amp mixer */
- ulRC = pAData->stMCIMixSetup.pmixWrite(pAData->stMCIMixSetup.ulMixHandle,
- pMixBuffer, pAData->cMixBuffers);
- if (ulRC != MCIERR_SUCCESS) {
- _mixIOError("pmixWrite", ulRC);
- }
- }
- }
- static int OS2_CaptureFromDevice(_THIS,void *buffer,int buflen)
- {
- SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden;
- ULONG ulRC;
- PMCI_MIX_BUFFER pMixBuffer = NULL;
- int len = 0;
- if (!pAData->ulState)
- {
- pAData->ulState = 1;
- ulRC = pAData->stMCIMixSetup.pmixRead(pAData->stMCIMixSetup.ulMixHandle,
- pAData->aMixBuffers, pAData->cMixBuffers);
- if (ulRC != MCIERR_SUCCESS) {
- _mixIOError("pmixRead", ulRC);
- return -1;
- }
- }
- /* Wait for an audio chunk to finish */
- ulRC = DosWaitEventSem(pAData->hevBuf, 5000);
- if (ulRC != NO_ERROR)
- {
- debug_os2("DosWaitEventSem(), rc = %lu", ulRC);
- return -1;
- }
- pMixBuffer = pAData->pDrainBuffer;
- len = SDL_min((int)pMixBuffer->ulBufferLength, buflen);
- SDL_memcpy(buffer,pMixBuffer->pBuffer, len);
- pAData->pDrainBuffer = _getNextBuffer(pAData, pMixBuffer);
- debug_os2("buflen = %u, ulBufferLength = %lu",buflen,pMixBuffer->ulBufferLength);
- return len;
- }
- static void OS2_FlushCapture(_THIS)
- {
- SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden;
- ULONG ulIdx;
- debug_os2("Enter");
- /* Fill all device buffers with data */
- for (ulIdx = 0; ulIdx < pAData->cMixBuffers; ulIdx++) {
- pAData->aMixBuffers[ulIdx].ulFlags = 0;
- pAData->aMixBuffers[ulIdx].ulBufferLength = _this->spec.size;
- pAData->aMixBuffers[ulIdx].ulUserParm = (ULONG)_this;
- SDL_memset(((PMCI_MIX_BUFFER)pAData->aMixBuffers)[ulIdx].pBuffer,
- _this->spec.silence, _this->spec.size);
- }
- pAData->pFillBuffer = pAData->aMixBuffers;
- pAData->pDrainBuffer = pAData->aMixBuffers;
- }
- static void OS2_CloseDevice(_THIS)
- {
- SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden;
- MCI_GENERIC_PARMS sMCIGenericParms;
- ULONG ulRC;
- debug_os2("Enter");
- if (pAData == NULL)
- return;
- pAData->ulState = 2;
- /* Close up audio */
- if (pAData->usDeviceId != (USHORT)~0) { /* Device is open. */
- SDL_zero(sMCIGenericParms);
- ulRC = mciSendCommand(pAData->usDeviceId, MCI_STOP,
- MCI_WAIT,
- &sMCIGenericParms, 0);
- if (LOUSHORT(ulRC) != MCIERR_SUCCESS) {
- debug_os2("MCI_STOP - failed" );
- }
- if (pAData->stMCIMixSetup.ulBitsPerSample != 0) { /* Mixer was initialized. */
- ulRC = mciSendCommand(pAData->usDeviceId, MCI_MIXSETUP,
- MCI_WAIT | MCI_MIXSETUP_DEINIT,
- &pAData->stMCIMixSetup, 0);
- if (LOUSHORT(ulRC) != MCIERR_SUCCESS) {
- debug_os2("MCI_MIXSETUP, MCI_MIXSETUP_DEINIT - failed");
- }
- }
- if (pAData->cMixBuffers != 0) { /* Buffers was allocated. */
- MCI_BUFFER_PARMS stMCIBuffer;
- stMCIBuffer.ulBufferSize = pAData->aMixBuffers[0].ulBufferLength;
- stMCIBuffer.ulNumBuffers = pAData->cMixBuffers;
- stMCIBuffer.pBufList = pAData->aMixBuffers;
- ulRC = mciSendCommand(pAData->usDeviceId, MCI_BUFFER,
- MCI_WAIT | MCI_DEALLOCATE_MEMORY, &stMCIBuffer, 0);
- if (LOUSHORT(ulRC) != MCIERR_SUCCESS) {
- debug_os2("MCI_BUFFER, MCI_DEALLOCATE_MEMORY - failed");
- }
- }
- ulRC = mciSendCommand(pAData->usDeviceId, MCI_CLOSE, MCI_WAIT,
- &sMCIGenericParms, 0);
- if (LOUSHORT(ulRC) != MCIERR_SUCCESS) {
- debug_os2("MCI_CLOSE - failed");
- }
- }
- if (pAData->hevBuf != NULLHANDLE)
- DosCloseEventSem(pAData->hevBuf);
- SDL_free(pAData);
- }
- static int OS2_OpenDevice(_THIS, const char *devname)
- {
- SDL_PrivateAudioData *pAData;
- SDL_AudioFormat test_format;
- MCI_AMP_OPEN_PARMS stMCIAmpOpen;
- MCI_BUFFER_PARMS stMCIBuffer;
- ULONG ulRC;
- ULONG ulIdx;
- BOOL new_freq;
- SDL_bool iscapture = _this->iscapture;
- ULONG ulHandle = (ULONG)_this->handle;
- new_freq = FALSE;
- SDL_zero(stMCIAmpOpen);
- SDL_zero(stMCIBuffer);
- for (test_format = SDL_FirstAudioFormat(_this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
- if (test_format == AUDIO_U8 || test_format == AUDIO_S16)
- break;
- }
- if (!test_format) {
- debug_os2("Unsupported audio format, AUDIO_S16 used");
- test_format = AUDIO_S16;
- }
- pAData = (SDL_PrivateAudioData *) SDL_calloc(1, sizeof(struct SDL_PrivateAudioData));
- if (pAData == NULL)
- return SDL_OutOfMemory();
- _this->hidden = pAData;
- ulRC = DosCreateEventSem(NULL, &pAData->hevBuf, DCE_AUTORESET, TRUE);
- if (ulRC != NO_ERROR) {
- debug_os2("DosCreateEventSem() failed, rc = %lu", ulRC);
- return -1;
- }
- /* Open audio device */
- stMCIAmpOpen.usDeviceID = 0;
- stMCIAmpOpen.pszDeviceType = (PSZ)MAKEULONG(MCI_DEVTYPE_AUDIO_AMPMIX,LOUSHORT(ulHandle));
- ulRC = mciSendCommand(0, MCI_OPEN,
- (_getEnvULong("SDL_AUDIO_SHARE", 1, 0) != 0)?
- MCI_WAIT | MCI_OPEN_TYPE_ID | MCI_OPEN_SHAREABLE :
- MCI_WAIT | MCI_OPEN_TYPE_ID,
- &stMCIAmpOpen, 0);
- if (LOUSHORT(ulRC) != MCIERR_SUCCESS) {
- DosCloseEventSem(pAData->hevBuf);
- pAData->usDeviceId = (USHORT)~0;
- return _MCIError("MCI_OPEN", ulRC);
- }
- pAData->usDeviceId = stMCIAmpOpen.usDeviceID;
- if (iscapture) {
- MCI_CONNECTOR_PARMS stMCIConnector;
- MCI_AMP_SET_PARMS stMCIAmpSet;
- BOOL fLineIn = _getEnvULong("SDL_AUDIO_LINEIN", 1, 0);
- /* Set particular connector. */
- SDL_zero(stMCIConnector);
- stMCIConnector.ulConnectorType = (fLineIn)? MCI_LINE_IN_CONNECTOR :
- MCI_MICROPHONE_CONNECTOR;
- mciSendCommand(stMCIAmpOpen.usDeviceID, MCI_CONNECTOR,
- MCI_WAIT | MCI_ENABLE_CONNECTOR |
- MCI_CONNECTOR_TYPE, &stMCIConnector, 0);
- /* Disable monitor. */
- SDL_zero(stMCIAmpSet);
- stMCIAmpSet.ulItem = MCI_AMP_SET_MONITOR;
- mciSendCommand(stMCIAmpOpen.usDeviceID, MCI_SET,
- MCI_WAIT | MCI_SET_OFF | MCI_SET_ITEM,
- &stMCIAmpSet, 0);
- /* Set record volume. */
- stMCIAmpSet.ulLevel = _getEnvULong("SDL_AUDIO_RECVOL", 100, 90);
- stMCIAmpSet.ulItem = MCI_AMP_SET_AUDIO;
- stMCIAmpSet.ulAudio = MCI_SET_AUDIO_ALL; /* Both cnannels. */
- stMCIAmpSet.ulValue = (fLineIn) ? MCI_LINE_IN_CONNECTOR :
- MCI_MICROPHONE_CONNECTOR ;
- mciSendCommand(stMCIAmpOpen.usDeviceID, MCI_SET,
- MCI_WAIT | MCI_SET_AUDIO | MCI_AMP_SET_GAIN,
- &stMCIAmpSet, 0);
- }
- _this->spec.format = test_format;
- _this->spec.channels = _this->spec.channels > 1 ? 2 : 1;
- if (_this->spec.freq < 8000) {
- _this->spec.freq = 8000;
- new_freq = TRUE;
- } else if (_this->spec.freq > 48000) {
- _this->spec.freq = 48000;
- new_freq = TRUE;
- }
- /* Setup mixer. */
- pAData->stMCIMixSetup.ulFormatTag = MCI_WAVE_FORMAT_PCM;
- pAData->stMCIMixSetup.ulBitsPerSample = SDL_AUDIO_BITSIZE(test_format);
- pAData->stMCIMixSetup.ulSamplesPerSec = _this->spec.freq;
- pAData->stMCIMixSetup.ulChannels = _this->spec.channels;
- pAData->stMCIMixSetup.ulDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO;
- if (!iscapture) {
- pAData->stMCIMixSetup.ulFormatMode= MCI_PLAY;
- pAData->stMCIMixSetup.pmixEvent = cbAudioWriteEvent;
- } else {
- pAData->stMCIMixSetup.ulFormatMode= MCI_RECORD;
- pAData->stMCIMixSetup.pmixEvent = cbAudioReadEvent;
- }
- ulRC = mciSendCommand(pAData->usDeviceId, MCI_MIXSETUP,
- MCI_WAIT | MCI_MIXSETUP_INIT, &pAData->stMCIMixSetup, 0);
- if (LOUSHORT(ulRC) != MCIERR_SUCCESS && _this->spec.freq > 44100) {
- new_freq = TRUE;
- pAData->stMCIMixSetup.ulSamplesPerSec = 44100;
- _this->spec.freq = 44100;
- ulRC = mciSendCommand(pAData->usDeviceId, MCI_MIXSETUP,
- MCI_WAIT | MCI_MIXSETUP_INIT, &pAData->stMCIMixSetup, 0);
- }
- debug_os2("Setup mixer [BPS: %lu, Freq.: %lu, Channels: %lu]: %s",
- pAData->stMCIMixSetup.ulBitsPerSample,
- pAData->stMCIMixSetup.ulSamplesPerSec,
- pAData->stMCIMixSetup.ulChannels,
- (ulRC == MCIERR_SUCCESS)? "SUCCESS" : "FAIL");
- if (ulRC != MCIERR_SUCCESS) {
- pAData->stMCIMixSetup.ulBitsPerSample = 0;
- return _MCIError("MCI_MIXSETUP", ulRC);
- }
- if (_this->spec.samples == 0 || new_freq == TRUE) {
- /* also see SDL_audio.c:prepare_audiospec() */
- /* Pick a default of ~46 ms at desired frequency */
- Uint32 samples = (_this->spec.freq / 1000) * 46;
- Uint32 power2 = 1;
- while (power2 < samples) {
- power2 <<= 1;
- }
- _this->spec.samples = power2;
- }
- /* Update the fragment size as size in bytes */
- SDL_CalculateAudioSpec(&_this->spec);
- /* Allocate memory buffers */
- stMCIBuffer.ulBufferSize = _this->spec.size;/* (_this->spec.freq / 1000) * 100 */
- stMCIBuffer.ulNumBuffers = NUM_BUFFERS;
- stMCIBuffer.pBufList = pAData->aMixBuffers;
- ulRC = mciSendCommand(pAData->usDeviceId, MCI_BUFFER,
- MCI_WAIT | MCI_ALLOCATE_MEMORY, &stMCIBuffer, 0);
- if (LOUSHORT(ulRC) != MCIERR_SUCCESS) {
- return _MCIError("MCI_BUFFER", ulRC);
- }
- pAData->cMixBuffers = stMCIBuffer.ulNumBuffers;
- _this->spec.size = stMCIBuffer.ulBufferSize;
- debug_os2("%s, number of mix buffers: %lu",iscapture ? "capture": "play",pAData->cMixBuffers);
- /* Fill all device buffers with data */
- for (ulIdx = 0; ulIdx < stMCIBuffer.ulNumBuffers; ulIdx++) {
- pAData->aMixBuffers[ulIdx].ulFlags = 0;
- pAData->aMixBuffers[ulIdx].ulBufferLength = stMCIBuffer.ulBufferSize;
- pAData->aMixBuffers[ulIdx].ulUserParm = (ULONG)_this;
- SDL_memset(((PMCI_MIX_BUFFER)stMCIBuffer.pBufList)[ulIdx].pBuffer,
- _this->spec.silence, stMCIBuffer.ulBufferSize);
- }
- pAData->pFillBuffer = pAData->aMixBuffers;
- pAData->pDrainBuffer = pAData->aMixBuffers;
- return 0;
- }
- static SDL_bool OS2_Init(SDL_AudioDriverImpl * impl)
- {
- /* Set the function pointers */
- impl->DetectDevices = OS2_DetectDevices;
- impl->OpenDevice = OS2_OpenDevice;
- impl->PlayDevice = OS2_PlayDevice;
- impl->WaitDevice = OS2_WaitDevice;
- impl->GetDeviceBuf = OS2_GetDeviceBuf;
- impl->CloseDevice = OS2_CloseDevice;
- impl->CaptureFromDevice = OS2_CaptureFromDevice ;
- impl->FlushCapture = OS2_FlushCapture;
- impl->HasCaptureSupport = SDL_TRUE;
- return SDL_TRUE; /* this audio target is available. */
- }
- AudioBootStrap OS2AUDIO_bootstrap = {
- "DART", "OS/2 DART", OS2_Init, SDL_FALSE
- };
- #endif /* SDL_AUDIO_DRIVER_OS2 */
- /* vi: set ts=4 sw=4 expandtab: */
|