21 #include "../../SDL_internal.h"
23 #if SDL_AUDIO_DRIVER_OS2
27 #include "../../core/os2/SDL_os2.h"
30 #include "../SDL_audio_c.h"
45 static ULONG _getEnvULong(PSZ pszName, ULONG ulMax, ULONG ulDefault)
51 if (pszEnvVal ==
NULL)
54 ulValue =
SDL_strtoul((
const char *)pszEnvVal, &pcEnd, 10);
55 return (pcEnd == pszEnvVal) || (ulValue > ulMax)? ulDefault : ulMax;
58 static int _MCIError(PSZ pszFunc, ULONG ulResult)
61 mciGetErrorString(ulResult, acBuf,
sizeof(acBuf));
65 static void _mixIOError(PSZ pszFunction, ULONG ulRC)
67 debug_os2(
"%s() - failed, rc = 0x%X (%s)",
69 (ulRC == MCIERR_INVALID_MODE) ?
"Mixer mode does not match request" :
70 (ulRC == MCIERR_INVALID_BUFFER) ?
"Caller sent an invalid buffer" :
"unknown");
73 LONG
APIENTRY cbAudioWriteEvent(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer,
79 if (ulFlags != MIX_WRITE_COMPLETE) {
85 ulRC = DosPostEventSem(pAData->
hevBuf);
86 if (ulRC != NO_ERROR && ulRC != ERROR_ALREADY_POSTED) {
87 debug_os2(
"DosPostEventSem(), rc = %u", ulRC);
93 LONG
APIENTRY cbAudioReadEvent(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer,
99 if (ulFlags != MIX_READ_COMPLETE) {
106 ulRC = DosPostEventSem(pAData->
hevBuf);
107 if (ulRC != NO_ERROR && ulRC != ERROR_ALREADY_POSTED) {
108 debug_os2(
"DosPostEventSem(), rc = %u", ulRC);
115 static void OS2_DetectDevices(
void)
117 MCI_SYSINFO_PARMS stMCISysInfo;
120 MCI_SYSINFO_LOGDEVICE stLogDevice;
121 MCI_SYSINFO_PARMS stSysInfoParams;
126 stMCISysInfo.pszReturn = acBuf;
127 stMCISysInfo.ulRetSize =
sizeof(acBuf);
128 stMCISysInfo.usDeviceType = MCI_DEVTYPE_AUDIO_AMPMIX;
129 ulRC = mciSendCommand(0, MCI_SYSINFO, MCI_WAIT | MCI_SYSINFO_QUANTITY,
131 if (ulRC != NO_ERROR) {
132 debug_os2(
"MCI_SYSINFO, MCI_SYSINFO_QUANTITY - failed, rc = 0x%X", ulRC);
136 ulDevicesNum = atol(stMCISysInfo.pszReturn);
138 for (stSysInfoParams.ulNumber = 0; stSysInfoParams.ulNumber < ulDevicesNum;
139 stSysInfoParams.ulNumber++) {
141 stSysInfoParams.pszReturn = acBuf;
142 stSysInfoParams.ulRetSize =
sizeof(acBuf);
143 stSysInfoParams.usDeviceType = MCI_DEVTYPE_AUDIO_AMPMIX;
144 ulRC = mciSendCommand(0, MCI_SYSINFO, MCI_WAIT | MCI_SYSINFO_INSTALLNAME,
145 &stSysInfoParams, 0);
146 if (ulRC != NO_ERROR) {
147 debug_os2(
"MCI_SYSINFO, MCI_SYSINFO_INSTALLNAME - failed, rc = 0x%X", ulRC);
152 stSysInfoParams.ulItem = MCI_SYSINFO_QUERY_DRIVER;
153 stSysInfoParams.pSysInfoParm = &stLogDevice;
154 strcpy(stLogDevice.szInstallName, stSysInfoParams.pszReturn);
155 ulRC = mciSendCommand(0, MCI_SYSINFO, MCI_WAIT | MCI_SYSINFO_ITEM,
156 &stSysInfoParams, 0);
157 if (ulRC != NO_ERROR) {
158 debug_os2(
"MCI_SYSINFO, MCI_SYSINFO_ITEM - failed, rc = 0x%X", ulRC);
169 static void OS2_WaitDevice(
_THIS)
175 ulRC = DosWaitEventSem(pAData->
hevBuf, 5000);
176 if (ulRC != NO_ERROR) {
177 debug_os2(
"DosWaitEventSem(), rc = %u", ulRC);
187 static void OS2_PlayDevice(
_THIS)
197 if (ulRC != MCIERR_SUCCESS) {
198 _mixIOError(
"pmixWrite", ulRC);
204 static void OS2_CloseDevice(
_THIS)
207 MCI_GENERIC_PARMS sMCIGenericParms;
218 ulRC = mciSendCommand(pAData->
usDeviceId, MCI_MIXSETUP,
219 MCI_WAIT | MCI_MIXSETUP_DEINIT,
221 if (ulRC != MCIERR_SUCCESS) {
222 debug_os2(
"MCI_MIXSETUP, MCI_MIXSETUP_DEINIT - failed");
228 MCI_BUFFER_PARMS stMCIBuffer;
230 stMCIBuffer.ulBufferSize = pAData->
aMixBuffers[0].ulBufferLength;
234 ulRC = mciSendCommand(pAData->
usDeviceId, MCI_BUFFER,
235 MCI_WAIT | MCI_DEALLOCATE_MEMORY, &stMCIBuffer, 0);
236 if (ulRC != MCIERR_SUCCESS) {
237 debug_os2(
"MCI_BUFFER, MCI_DEALLOCATE_MEMORY - failed");
241 ulRC = mciSendCommand(pAData->
usDeviceId, MCI_CLOSE, MCI_WAIT,
242 &sMCIGenericParms, 0);
243 if (ulRC != MCIERR_SUCCESS) {
248 if (pAData->
hevBuf != NULLHANDLE)
249 DosCloseEventSem(pAData->
hevBuf);
254 static int OS2_OpenDevice(
_THIS,
void *
handle,
const char *devname,
259 MCI_AMP_OPEN_PARMS stMCIAmpOpen;
260 MCI_BUFFER_PARMS stMCIBuffer;
274 if (SDLAudioFmt == 0) {
275 debug_os2(
"Unsupported audio format, AUDIO_S16 used");
282 _this->hidden = pAData;
284 ulRC = DosCreateEventSem(
NULL, &pAData->
hevBuf, DCE_AUTORESET,
TRUE);
285 if (ulRC != NO_ERROR) {
286 debug_os2(
"DosCreateEventSem() failed, rc = %u", ulRC);
292 stMCIAmpOpen.pszDeviceType = (PSZ)MCI_DEVTYPE_AUDIO_AMPMIX;
293 ulRC = mciSendCommand(0, MCI_OPEN,
294 (_getEnvULong(
"SDL_AUDIO_SHARE", 1, 0) != 0)?
295 MCI_WAIT | MCI_OPEN_TYPE_ID | MCI_OPEN_SHAREABLE :
296 MCI_WAIT | MCI_OPEN_TYPE_ID,
298 if (ulRC != MCIERR_SUCCESS) {
299 stMCIAmpOpen.usDeviceID = (USHORT)~0;
300 return _MCIError(
"MCI_OPEN", ulRC);
304 if (iscapture != 0) {
305 MCI_CONNECTOR_PARMS stMCIConnector;
306 MCI_AMP_SET_PARMS stMCIAmpSet;
307 BOOL fLineIn = _getEnvULong(
"SDL_AUDIO_LINEIN", 1, 0);
311 stMCIConnector.ulConnectorType = (fLineIn)? MCI_LINE_IN_CONNECTOR :
312 MCI_MICROPHONE_CONNECTOR;
313 mciSendCommand(stMCIAmpOpen.usDeviceID, MCI_CONNECTOR,
314 MCI_WAIT | MCI_ENABLE_CONNECTOR |
315 MCI_CONNECTOR_TYPE, &stMCIConnector, 0);
319 stMCIAmpSet.ulItem = MCI_AMP_SET_MONITOR;
320 mciSendCommand(stMCIAmpOpen.usDeviceID, MCI_SET,
321 MCI_WAIT | MCI_SET_OFF | MCI_SET_ITEM,
325 stMCIAmpSet.ulLevel = _getEnvULong(
"SDL_AUDIO_RECVOL", 100, 90);
326 stMCIAmpSet.ulItem = MCI_AMP_SET_AUDIO;
327 stMCIAmpSet.ulAudio = MCI_SET_AUDIO_ALL;
328 stMCIAmpSet.ulValue = (fLineIn) ? MCI_LINE_IN_CONNECTOR :
329 MCI_MICROPHONE_CONNECTOR ;
331 mciSendCommand(stMCIAmpOpen.usDeviceID, MCI_SET,
332 MCI_WAIT | MCI_SET_AUDIO | MCI_AMP_SET_GAIN,
336 _this->spec.format = SDLAudioFmt;
337 _this->spec.channels =
_this->spec.channels > 1 ? 2 : 1;
338 if (
_this->spec.freq < 8000) {
339 _this->spec.freq = 8000;
341 }
else if (
_this->spec.freq > 48000) {
342 _this->spec.freq = 48000;
351 pAData->
stMCIMixSetup.ulDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO;
352 if (iscapture == 0) {
360 ulRC = mciSendCommand(pAData->
usDeviceId, MCI_MIXSETUP,
362 if (ulRC != MCIERR_SUCCESS &&
_this->spec.freq > 44100) {
365 _this->spec.freq = 44100;
366 ulRC = mciSendCommand(pAData->
usDeviceId, MCI_MIXSETUP,
370 debug_os2(
"Setup mixer [BPS: %u, Freq.: %u, Channels: %u]: %s",
374 (ulRC == MCIERR_SUCCESS)?
"SUCCESS" :
"FAIL");
376 if (ulRC != MCIERR_SUCCESS) {
378 return _MCIError(
"MCI_MIXSETUP", ulRC);
381 if (
_this->spec.samples == 0 || new_freq ==
TRUE) {
389 _this->spec.samples = power2;
395 stMCIBuffer.ulBufferSize =
_this->spec.size;
399 ulRC = mciSendCommand(pAData->
usDeviceId, MCI_BUFFER,
400 MCI_WAIT | MCI_ALLOCATE_MEMORY, &stMCIBuffer, 0);
401 if (ulRC != MCIERR_SUCCESS) {
402 return _MCIError(
"MCI_BUFFER", ulRC);
405 _this->spec.size = stMCIBuffer.ulBufferSize;
408 for (ulIdx = 0; ulIdx < stMCIBuffer.ulNumBuffers; ulIdx++) {
410 pAData->
aMixBuffers[ulIdx].ulBufferLength = stMCIBuffer.ulBufferSize;
411 pAData->
aMixBuffers[ulIdx].ulUserParm = (ULONG)pAData;
413 memset(((PMCI_MIX_BUFFER)stMCIBuffer.pBufList)[ulIdx].pBuffer,
414 _this->spec.silence, stMCIBuffer.ulBufferSize);
422 if (ulRC != MCIERR_SUCCESS) {
423 _mixIOError(
"pmixWrite", ulRC);
void SDL_AddAudioDevice(const int iscapture, const char *name, void *handle)
void SDL_CalculateAudioSpec(SDL_AudioSpec *spec)
SDL_AudioFormat SDL_FirstAudioFormat(SDL_AudioFormat format)
SDL_AudioFormat SDL_NextAudioFormat(void)
Uint16 SDL_AudioFormat
Audio format flags.
#define SDL_AUDIO_BITSIZE(x)
#define SDL_OutOfMemory()
AudioBootStrap OS2AUDIO_bootstrap
static SDL_VideoDevice * _this
EGLImageKHR EGLint EGLint * handle
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d ®2 endm macro vzip8 reg2 vzip d d ®2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
void(* PlayDevice)(_THIS)
void(* WaitDevice)(_THIS)
void(* CloseDevice)(_THIS)
void(* DetectDevices)(void)
Uint8 *(* GetDeviceBuf)(_THIS)
int(* OpenDevice)(_THIS, void *handle, const char *devname, int iscapture)
MCI_MIX_BUFFER aMixBuffers[NUM_BUFFERS]
MCI_MIXSETUP_PARMS stMCIMixSetup