mirror of
https://github.com/Ryujinx/SDL.git
synced 2024-12-22 19:45:40 +00:00
os2 audio refactoring and capture support
- Fixed audio device detection and usage. - Implemented audio capture support - Refactored buffer handling to separate pointers to fill and drain buffers. Based on patches by josch1710 and Lars Erdmann: https://github.com/bitwiseworks/SDL2-os2/pull/7
This commit is contained in:
parent
ba0c270c7a
commit
890bee64a4
|
@ -30,17 +30,12 @@
|
|||
#include "../SDL_audio_c.h"
|
||||
#include "SDL_os2audio.h"
|
||||
|
||||
/*
|
||||
void lockIncr(volatile int *piVal);
|
||||
#pragma aux lockIncr = \
|
||||
"lock add [eax], 1 "\
|
||||
parm [eax];
|
||||
|
||||
void lockDecr(volatile int *piVal);
|
||||
#pragma aux lockDecr = \
|
||||
"lock sub [eax], 1 "\
|
||||
parm [eax];
|
||||
*/
|
||||
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)
|
||||
{
|
||||
|
@ -64,7 +59,7 @@ static int _MCIError(const char *func, ULONG ulResult)
|
|||
|
||||
static void _mixIOError(const char *function, ULONG ulRC)
|
||||
{
|
||||
debug_os2("%s() - failed, rc = 0x%X (%s)",
|
||||
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");
|
||||
|
@ -73,18 +68,33 @@ static void _mixIOError(const char *function, ULONG ulRC)
|
|||
static LONG APIENTRY cbAudioWriteEvent(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer,
|
||||
ULONG ulFlags)
|
||||
{
|
||||
SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)pBuffer->ulUserParm;
|
||||
SDL_AudioDevice *_this = (SDL_AudioDevice *)pBuffer->ulUserParm;
|
||||
SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden;
|
||||
ULONG ulRC;
|
||||
|
||||
if (ulFlags != MIX_WRITE_COMPLETE) {
|
||||
debug_os2("flags = 0x%X", ulFlags);
|
||||
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;
|
||||
}
|
||||
|
||||
/*lockDecr((int *)&pAData->ulQueuedBuf);*/
|
||||
ulRC = DosPostEventSem(pAData->hevBuf);
|
||||
if (ulRC != NO_ERROR && ulRC != ERROR_ALREADY_POSTED) {
|
||||
debug_os2("DosPostEventSem(), rc = %u", ulRC);
|
||||
debug_os2("DosPostEventSem(), rc = %lu", ulRC);
|
||||
}
|
||||
|
||||
return 1; /* return value doesn't seem to matter. */
|
||||
|
@ -93,19 +103,36 @@ static LONG APIENTRY cbAudioWriteEvent(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer,
|
|||
static LONG APIENTRY cbAudioReadEvent(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer,
|
||||
ULONG ulFlags)
|
||||
{
|
||||
SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)pBuffer->ulUserParm;
|
||||
SDL_AudioDevice *_this = (SDL_AudioDevice *)pBuffer->ulUserParm;
|
||||
SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden;
|
||||
ULONG ulRC;
|
||||
|
||||
if (ulFlags != MIX_READ_COMPLETE) {
|
||||
debug_os2("flags = 0x%X", ulFlags);
|
||||
debug_os2("cbAudioReadEvent: ulStatus = %lu, pBuffer = %p, ulFlags = %#lX",ulStatus,pBuffer,ulFlags);
|
||||
|
||||
if (pAData->ulState == 2)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
pAData->stMCIMixSetup.pmixRead(pAData->stMCIMixSetup.ulMixHandle, pBuffer, 1);
|
||||
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 = %u", ulRC);
|
||||
debug_os2("DosPostEventSem(), rc = %lu", ulRC);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -120,31 +147,36 @@ static void OS2_DetectDevices(void)
|
|||
MCI_SYSINFO_LOGDEVICE stLogDevice;
|
||||
MCI_SYSINFO_PARMS stSysInfoParams;
|
||||
ULONG ulRC;
|
||||
ULONG ulHandle = 0;
|
||||
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 (ulRC != NO_ERROR) {
|
||||
debug_os2("MCI_SYSINFO, MCI_SYSINFO_QUANTITY - failed, rc = 0x%X", ulRC);
|
||||
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 (stSysInfoParams.ulNumber = 0; stSysInfoParams.ulNumber < ulDevicesNum;
|
||||
stSysInfoParams.ulNumber++) {
|
||||
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 (ulRC != NO_ERROR) {
|
||||
debug_os2("MCI_SYSINFO, MCI_SYSINFO_INSTALLNAME - failed, rc = 0x%X", ulRC);
|
||||
if (LOUSHORT(ulRC) != MCIERR_SUCCESS) {
|
||||
debug_os2("MCI_SYSINFO, MCI_SYSINFO_INSTALLNAME - failed, rc = 0x%hX", LOUSHORT(ulRC));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -154,15 +186,45 @@ static void OS2_DetectDevices(void)
|
|||
SDL_strlcpy(stLogDevice.szInstallName, stSysInfoParams.pszReturn, MAX_DEVICE_NAME);
|
||||
ulRC = mciSendCommand(0, MCI_SYSINFO, MCI_WAIT | MCI_SYSINFO_ITEM,
|
||||
&stSysInfoParams, 0);
|
||||
if (ulRC != NO_ERROR) {
|
||||
debug_os2("MCI_SYSINFO, MCI_SYSINFO_ITEM - failed, rc = 0x%X", ulRC);
|
||||
if (LOUSHORT(ulRC) != MCIERR_SUCCESS) {
|
||||
debug_os2("MCI_SYSINFO, MCI_SYSINFO_ITEM - failed, rc = 0x%hX", LOUSHORT(ulRC));
|
||||
continue;
|
||||
}
|
||||
|
||||
ulHandle++;
|
||||
SDL_AddAudioDevice(0, stLogDevice.szProductInfo, NULL, (void *)(ulHandle));
|
||||
ulHandle++;
|
||||
SDL_AddAudioDevice(1, stLogDevice.szProductInfo, NULL, (void *)(ulHandle));
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,52 +233,145 @@ 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 = %u", ulRC);
|
||||
debug_os2("DosWaitEventSem(), rc = %lu", ulRC);
|
||||
}
|
||||
}
|
||||
|
||||
static Uint8 *OS2_GetDeviceBuf(_THIS)
|
||||
{
|
||||
SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden;
|
||||
return (Uint8 *) pAData->aMixBuffers[pAData->ulNextBuf].pBuffer;
|
||||
|
||||
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 = &pAData->aMixBuffers[pAData->ulNextBuf];
|
||||
PMCI_MIX_BUFFER pMixBuffer = NULL;
|
||||
|
||||
/* Queue it up */
|
||||
/*lockIncr((int *)&pAData->ulQueuedBuf);*/
|
||||
ulRC = pAData->stMCIMixSetup.pmixWrite(pAData->stMCIMixSetup.ulMixHandle,
|
||||
pMixBuffer, 1);
|
||||
if (ulRC != MCIERR_SUCCESS) {
|
||||
_mixIOError("pmixWrite", ulRC);
|
||||
} else {
|
||||
pAData->ulNextBuf = (pAData->ulNextBuf + 1) % pAData->cMixBuffers;
|
||||
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 (ulRC != MCIERR_SUCCESS) {
|
||||
if (LOUSHORT(ulRC) != MCIERR_SUCCESS) {
|
||||
debug_os2("MCI_MIXSETUP, MCI_MIXSETUP_DEINIT - failed");
|
||||
}
|
||||
}
|
||||
|
@ -230,14 +385,14 @@ static void OS2_CloseDevice(_THIS)
|
|||
|
||||
ulRC = mciSendCommand(pAData->usDeviceId, MCI_BUFFER,
|
||||
MCI_WAIT | MCI_DEALLOCATE_MEMORY, &stMCIBuffer, 0);
|
||||
if (ulRC != MCIERR_SUCCESS) {
|
||||
if (LOUSHORT(ulRC) != MCIERR_SUCCESS) {
|
||||
debug_os2("MCI_BUFFER, MCI_DEALLOCATE_MEMORY - failed");
|
||||
}
|
||||
}
|
||||
|
||||
ulRC = mciSendCommand(pAData->usDeviceId, MCI_CLOSE, MCI_WAIT,
|
||||
&sMCIGenericParms, 0);
|
||||
if (ulRC != MCIERR_SUCCESS) {
|
||||
if (LOUSHORT(ulRC) != MCIERR_SUCCESS) {
|
||||
debug_os2("MCI_CLOSE - failed");
|
||||
}
|
||||
}
|
||||
|
@ -258,6 +413,7 @@ static int OS2_OpenDevice(_THIS, const char *devname)
|
|||
ULONG ulIdx;
|
||||
BOOL new_freq;
|
||||
SDL_bool iscapture = _this->iscapture;
|
||||
ULONG ulHandle = (ULONG)_this->handle;
|
||||
|
||||
new_freq = FALSE;
|
||||
SDL_zero(stMCIAmpOpen);
|
||||
|
@ -279,20 +435,21 @@ static int OS2_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
ulRC = DosCreateEventSem(NULL, &pAData->hevBuf, DCE_AUTORESET, TRUE);
|
||||
if (ulRC != NO_ERROR) {
|
||||
debug_os2("DosCreateEventSem() failed, rc = %u", ulRC);
|
||||
debug_os2("DosCreateEventSem() failed, rc = %lu", ulRC);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Open audio device */
|
||||
stMCIAmpOpen.usDeviceID = (_this->handle != NULL) ? ((ULONG)_this->handle - 1) : 0;
|
||||
stMCIAmpOpen.pszDeviceType = (PSZ)MCI_DEVTYPE_AUDIO_AMPMIX;
|
||||
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 (ulRC != MCIERR_SUCCESS) {
|
||||
stMCIAmpOpen.usDeviceID = (USHORT)~0;
|
||||
if (LOUSHORT(ulRC) != MCIERR_SUCCESS) {
|
||||
DosCloseEventSem(pAData->hevBuf);
|
||||
pAData->usDeviceId = (USHORT)~0;
|
||||
return _MCIError("MCI_OPEN", ulRC);
|
||||
}
|
||||
pAData->usDeviceId = stMCIAmpOpen.usDeviceID;
|
||||
|
@ -355,7 +512,7 @@ static int OS2_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
ulRC = mciSendCommand(pAData->usDeviceId, MCI_MIXSETUP,
|
||||
MCI_WAIT | MCI_MIXSETUP_INIT, &pAData->stMCIMixSetup, 0);
|
||||
if (ulRC != MCIERR_SUCCESS && _this->spec.freq > 44100) {
|
||||
if (LOUSHORT(ulRC) != MCIERR_SUCCESS && _this->spec.freq > 44100) {
|
||||
new_freq = TRUE;
|
||||
pAData->stMCIMixSetup.ulSamplesPerSec = 44100;
|
||||
_this->spec.freq = 44100;
|
||||
|
@ -363,7 +520,7 @@ static int OS2_OpenDevice(_THIS, const char *devname)
|
|||
MCI_WAIT | MCI_MIXSETUP_INIT, &pAData->stMCIMixSetup, 0);
|
||||
}
|
||||
|
||||
debug_os2("Setup mixer [BPS: %u, Freq.: %u, Channels: %u]: %s",
|
||||
debug_os2("Setup mixer [BPS: %lu, Freq.: %lu, Channels: %lu]: %s",
|
||||
pAData->stMCIMixSetup.ulBitsPerSample,
|
||||
pAData->stMCIMixSetup.ulSamplesPerSec,
|
||||
pAData->stMCIMixSetup.ulChannels,
|
||||
|
@ -394,29 +551,25 @@ static int OS2_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
ulRC = mciSendCommand(pAData->usDeviceId, MCI_BUFFER,
|
||||
MCI_WAIT | MCI_ALLOCATE_MEMORY, &stMCIBuffer, 0);
|
||||
if (ulRC != MCIERR_SUCCESS) {
|
||||
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)pAData;
|
||||
pAData->aMixBuffers[ulIdx].ulUserParm = (ULONG)_this;
|
||||
|
||||
SDL_memset(((PMCI_MIX_BUFFER)stMCIBuffer.pBufList)[ulIdx].pBuffer,
|
||||
_this->spec.silence, stMCIBuffer.ulBufferSize);
|
||||
}
|
||||
|
||||
/* Write buffers to kick off the amp mixer */
|
||||
ulRC = pAData->stMCIMixSetup.pmixWrite(pAData->stMCIMixSetup.ulMixHandle,
|
||||
pAData->aMixBuffers, 1);
|
||||
if (ulRC != MCIERR_SUCCESS) {
|
||||
_mixIOError("pmixWrite", ulRC);
|
||||
return -1;
|
||||
}
|
||||
pAData->pFillBuffer = pAData->aMixBuffers;
|
||||
pAData->pDrainBuffer = pAData->aMixBuffers;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -431,12 +584,10 @@ static SDL_bool OS2_Init(SDL_AudioDriverImpl * impl)
|
|||
impl->WaitDevice = OS2_WaitDevice;
|
||||
impl->GetDeviceBuf = OS2_GetDeviceBuf;
|
||||
impl->CloseDevice = OS2_CloseDevice;
|
||||
|
||||
/* TODO: IMPLEMENT CAPTURE SUPPORT:
|
||||
impl->CaptureFromDevice = ;
|
||||
impl->FlushCapture = ;
|
||||
impl->CaptureFromDevice = OS2_CaptureFromDevice ;
|
||||
impl->FlushCapture = OS2_FlushCapture;
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
*/
|
||||
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
|
|
|
@ -43,10 +43,11 @@ typedef struct SDL_PrivateAudioData
|
|||
BYTE _pad[2];
|
||||
MCI_MIXSETUP_PARMS stMCIMixSetup;
|
||||
HEV hevBuf;
|
||||
ULONG ulNextBuf;
|
||||
PMCI_MIX_BUFFER pFillBuffer;
|
||||
PMCI_MIX_BUFFER pDrainBuffer;
|
||||
ULONG ulState;
|
||||
ULONG cMixBuffers;
|
||||
MCI_MIX_BUFFER aMixBuffers[NUM_BUFFERS];
|
||||
/* ULONG ulQueuedBuf;*/
|
||||
} SDL_PrivateAudioData;
|
||||
|
||||
#endif /* SDL_os2mm_h_ */
|
||||
|
|
Loading…
Reference in a new issue