comparison src/audio/dart/SDL_dart.c @ 3819:b225d9820ee3 SDL-ryan-multiple-audio-device

Updated a bunch of audio backends to 1.3 API (Dreamcast, OS/2, ALSA, and BeOS). None are tested, so anyu could fail to compile.
author Ryan C. Gordon <icculus@icculus.org>
date Fri, 06 Oct 2006 20:36:23 +0000
parents da371472162f
children 506fc6ca82cb
comparison
equal deleted inserted replaced
3818:49eadd6e8962 3819:b225d9820ee3
40 40
41 41
42 //--------------------------------------------------------------------- 42 //---------------------------------------------------------------------
43 // DARTEventFunc 43 // DARTEventFunc
44 // 44 //
45 // This function is called by DART, when an event occures, like end of 45 // This function is called by DART, when an event occurs, like end of
46 // playback of a buffer, etc... 46 // playback of a buffer, etc...
47 //--------------------------------------------------------------------- 47 //---------------------------------------------------------------------
48 LONG APIENTRY 48 static LONG APIENTRY
49 DARTEventFunc(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, ULONG ulFlags) 49 DARTEventFunc(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, ULONG ulFlags)
50 { 50 {
51 if (ulFlags && MIX_WRITE_COMPLETE) { // Playback of buffer completed! 51 if (ulFlags && MIX_WRITE_COMPLETE) { // Playback of buffer completed!
52 52
53 // Get pointer to buffer description 53 // Get pointer to buffer description
69 } 69 }
70 return TRUE; 70 return TRUE;
71 } 71 }
72 72
73 73
74 int 74 static int
75 DART_OpenAudio(_THIS, SDL_AudioSpec * spec) 75 DART_OpenDevice(_THIS, const char *devname, int iscapture)
76 { 76 {
77 SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format); 77 SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
78 int valid_datatype = 0; 78 int valid_datatype = 0;
79 MCI_AMP_OPEN_PARMS AmpOpenParms; 79 MCI_AMP_OPEN_PARMS AmpOpenParms;
80 MCI_GENERIC_PARMS GenericParms; 80 MCI_GENERIC_PARMS GenericParms;
81 int iDeviceOrd = 0; // Default device to be used 81 int iDeviceOrd = 0; // Default device to be used
82 int bOpenShared = 1; // Try opening it shared 82 int bOpenShared = 1; // Try opening it shared
87 int iBufSize; 87 int iBufSize;
88 int iOpenMode; 88 int iOpenMode;
89 int iSilence; 89 int iSilence;
90 int rc; 90 int rc;
91 91
92 /* Initialize all variables that we clean on shutdown */
93 this->hidden = (struct SDL_PrivateAudioData *)
94 SDL_malloc((sizeof *this->hidden));
95 if (this->hidden == NULL) {
96 SDL_OutOfMemory();
97 return 0;
98 }
99 SDL_memset(this->hidden, 0, (sizeof *this->hidden));
100
92 // First thing is to try to open a given DART device! 101 // First thing is to try to open a given DART device!
93 SDL_memset(&AmpOpenParms, 0, sizeof(MCI_AMP_OPEN_PARMS)); 102 SDL_memset(&AmpOpenParms, 0, sizeof(MCI_AMP_OPEN_PARMS));
94 // pszDeviceType should contain the device type in low word, and device ordinal in high word! 103 // pszDeviceType should contain the device type in low word, and device ordinal in high word!
95 AmpOpenParms.pszDeviceType = 104 AmpOpenParms.pszDeviceType =
96 (PSZ) (MCI_DEVTYPE_AUDIO_AMPMIX | (iDeviceOrd << 16)); 105 (PSZ) (MCI_DEVTYPE_AUDIO_AMPMIX | (iDeviceOrd << 16));
98 iOpenMode = MCI_WAIT | MCI_OPEN_TYPE_ID; 107 iOpenMode = MCI_WAIT | MCI_OPEN_TYPE_ID;
99 if (bOpenShared) 108 if (bOpenShared)
100 iOpenMode |= MCI_OPEN_SHAREABLE; 109 iOpenMode |= MCI_OPEN_SHAREABLE;
101 110
102 rc = mciSendCommand(0, MCI_OPEN, iOpenMode, (PVOID) & AmpOpenParms, 0); 111 rc = mciSendCommand(0, MCI_OPEN, iOpenMode, (PVOID) & AmpOpenParms, 0);
103 if (rc != MCIERR_SUCCESS) // No audio available?? 112 if (rc != MCIERR_SUCCESS) { // No audio available??
104 return (-1); 113 DART_CloseDevice(this);
114 return 0;
115 }
116
105 // Save the device ID we got from DART! 117 // Save the device ID we got from DART!
106 // We will use this in the next calls! 118 // We will use this in the next calls!
107 iDeviceOrd = AmpOpenParms.usDeviceID; 119 _this->hidden->iCurrDeviceOrd = iDeviceOrd = AmpOpenParms.usDeviceID;
108 120
109 // Determine the audio parameters from the AudioSpec 121 // Determine the audio parameters from the AudioSpec
110 if (spec->channels > 4) 122 if (this->spec.channels > 4)
111 spec->channels = 4; 123 this->spec.channels = 4;
112 124
113 while ((!valid_datatype) && (test_format)) { 125 while ((!valid_datatype) && (test_format)) {
114 spec->format = test_format; 126 this->spec.format = test_format;
115 valid_datatype = 1; 127 valid_datatype = 1;
116 switch (test_format) { 128 switch (test_format) {
117 case AUDIO_U8: 129 case AUDIO_U8:
118 // Unsigned 8 bit audio data 130 // Unsigned 8 bit audio data
119 iSilence = 0x80; 131 iSilence = 0x80;
120 iBits = 8; 132 _this->hidden->iCurrBits = iBits = 8;
121 break; 133 break;
122 134
123 case AUDIO_S16LSB: 135 case AUDIO_S16LSB:
124 // Signed 16 bit audio data 136 // Signed 16 bit audio data
125 iSilence = 0x00; 137 iSilence = 0x00;
126 iBits = 16; 138 _this->hidden->iCurrBits = iBits = 16;
127 break; 139 break;
128 140
129 // !!! FIXME: int32? 141 // !!! FIXME: int32?
130 142
131 default: 143 default:
135 } 147 }
136 } 148 }
137 149
138 if (!valid_datatype) { // shouldn't happen, but just in case... 150 if (!valid_datatype) { // shouldn't happen, but just in case...
139 // Close DART, and exit with error code! 151 // Close DART, and exit with error code!
140 mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0); 152 DART_CloseDevice(this);
141 SDL_SetError("Unsupported audio format"); 153 SDL_SetError("Unsupported audio format");
142 return (-1); 154 return 0;
143 } 155 }
144 156
145 iFreq = spec->freq; 157 _this->hidden->iCurrFreq = iFreq = this->spec.freq;
146 iChannels = spec->channels; 158 _this->hidden->iCurrChannels = iChannels = this->spec.channels;
147 /* Update the fragment size as size in bytes */ 159 /* Update the fragment size as size in bytes */
148 SDL_CalculateAudioSpec(spec); 160 SDL_CalculateAudioSpec(&this->spec);
149 iBufSize = spec->size; 161 _this->hidden->iCurrBufSize = iBufSize = this->spec.size;
150 162
151 // Now query this device if it supports the given freq/bits/channels! 163 // Now query this device if it supports the given freq/bits/channels!
152 SDL_memset(&(_this->hidden->MixSetupParms), 0, 164 SDL_memset(&(_this->hidden->MixSetupParms), 0,
153 sizeof(MCI_MIXSETUP_PARMS)); 165 sizeof(MCI_MIXSETUP_PARMS));
154 _this->hidden->MixSetupParms.ulBitsPerSample = iBits; 166 _this->hidden->MixSetupParms.ulBitsPerSample = iBits;
161 rc = mciSendCommand(iDeviceOrd, MCI_MIXSETUP, 173 rc = mciSendCommand(iDeviceOrd, MCI_MIXSETUP,
162 MCI_WAIT | MCI_MIXSETUP_QUERYMODE, 174 MCI_WAIT | MCI_MIXSETUP_QUERYMODE,
163 &(_this->hidden->MixSetupParms), 0); 175 &(_this->hidden->MixSetupParms), 0);
164 if (rc != MCIERR_SUCCESS) { // The device cannot handle this format! 176 if (rc != MCIERR_SUCCESS) { // The device cannot handle this format!
165 // Close DART, and exit with error code! 177 // Close DART, and exit with error code!
166 mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0); 178 DART_CloseDevice(this);
167 SDL_SetError("Audio device doesn't support requested audio format"); 179 SDL_SetError("Audio device doesn't support requested audio format");
168 return (-1); 180 return 0;
169 } 181 }
170 // The device can handle this format, so initialize! 182 // The device can handle this format, so initialize!
171 rc = mciSendCommand(iDeviceOrd, MCI_MIXSETUP, 183 rc = mciSendCommand(iDeviceOrd, MCI_MIXSETUP,
172 MCI_WAIT | MCI_MIXSETUP_INIT, 184 MCI_WAIT | MCI_MIXSETUP_INIT,
173 &(_this->hidden->MixSetupParms), 0); 185 &(_this->hidden->MixSetupParms), 0);
174 if (rc != MCIERR_SUCCESS) { // The device could not be opened! 186 if (rc != MCIERR_SUCCESS) { // The device could not be opened!
175 // Close DART, and exit with error code! 187 // Close DART, and exit with error code!
176 mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0); 188 DART_CloseDevice(this);
177 SDL_SetError("Audio device could not be set up"); 189 SDL_SetError("Audio device could not be set up");
178 return (-1); 190 return 0;
179 } 191 }
180 // Ok, the device is initialized. 192 // Ok, the device is initialized.
181 // Now we should allocate buffers. For this, we need a place where 193 // Now we should allocate buffers. For this, we need a place where
182 // the buffer descriptors will be: 194 // the buffer descriptors will be:
183 _this->hidden->pMixBuffers = 195 _this->hidden->pMixBuffers =
184 (MCI_MIX_BUFFER *) SDL_malloc(sizeof(MCI_MIX_BUFFER) * iNumBufs); 196 (MCI_MIX_BUFFER *) SDL_malloc(sizeof(MCI_MIX_BUFFER) * iNumBufs);
185 if (!(_this->hidden->pMixBuffers)) { // Not enough memory! 197 if (!(_this->hidden->pMixBuffers)) { // Not enough memory!
186 // Close DART, and exit with error code! 198 // Close DART, and exit with error code!
187 mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0); 199 DART_CloseDevice(this);
188 SDL_SetError("Not enough memory for audio buffer descriptors"); 200 SDL_OutOfMemory();
189 return (-1); 201 return 0;
190 } 202 }
191 // Now that we have the place for buffer list, we can ask DART for the 203 // Now that we have the place for buffer list, we can ask DART for the
192 // buffers! 204 // buffers!
193 _this->hidden->BufferParms.ulNumBuffers = iNumBufs; // Number of buffers 205 _this->hidden->BufferParms.ulNumBuffers = iNumBufs; // Number of buffers
194 _this->hidden->BufferParms.ulBufferSize = iBufSize; // each with this size 206 _this->hidden->BufferParms.ulBufferSize = iBufSize; // each with this size
199 &(_this->hidden->BufferParms), 0); 211 &(_this->hidden->BufferParms), 0);
200 if ((rc != MCIERR_SUCCESS) 212 if ((rc != MCIERR_SUCCESS)
201 || (iNumBufs != _this->hidden->BufferParms.ulNumBuffers) 213 || (iNumBufs != _this->hidden->BufferParms.ulNumBuffers)
202 || (_this->hidden->BufferParms.ulBufferSize == 0)) { // Could not allocate memory! 214 || (_this->hidden->BufferParms.ulBufferSize == 0)) { // Could not allocate memory!
203 // Close DART, and exit with error code! 215 // Close DART, and exit with error code!
204 SDL_free(_this->hidden->pMixBuffers); 216 DART_CloseDevice(this);
205 _this->hidden->pMixBuffers = NULL;
206 mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0);
207 SDL_SetError("DART could not allocate buffers"); 217 SDL_SetError("DART could not allocate buffers");
208 return (-1); 218 return 0;
209 } 219 }
220 _this->hidden->iCurrNumBufs = iNumBufs;
221
210 // Ok, we have all the buffers allocated, let's mark them! 222 // Ok, we have all the buffers allocated, let's mark them!
211 { 223 {
212 int i; 224 int i;
213 for (i = 0; i < iNumBufs; i++) { 225 for (i = 0; i < iNumBufs; i++) {
214 pMixBufferDesc pBufferDesc = 226 pMixBufferDesc pBufferDesc =
215 (pMixBufferDesc) SDL_malloc(sizeof(tMixBufferDesc));; 227 (pMixBufferDesc) SDL_malloc(sizeof(tMixBufferDesc));;
216 // Check if this buffer was really allocated by DART 228 // Check if this buffer was really allocated by DART
217 if ((!(_this->hidden->pMixBuffers[i].pBuffer)) 229 if ((!(_this->hidden->pMixBuffers[i].pBuffer))
218 || (!pBufferDesc)) { // Wrong buffer! 230 || (!pBufferDesc)) { // Wrong buffer!
219 // Close DART, and exit with error code! 231 DART_CloseDevice(this);
220 // Free buffer descriptions
221 {
222 int j;
223 for (j = 0; j < i; j++)
224 SDL_free((void *) (_this->hidden->pMixBuffers[j].
225 ulUserParm));
226 }
227 // and cleanup
228 mciSendCommand(iDeviceOrd, MCI_BUFFER,
229 MCI_WAIT | MCI_DEALLOCATE_MEMORY,
230 &(_this->hidden->BufferParms), 0);
231 SDL_free(_this->hidden->pMixBuffers);
232 _this->hidden->pMixBuffers = NULL;
233 mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT,
234 &GenericParms, 0);
235 SDL_SetError("Error at internal buffer check"); 232 SDL_SetError("Error at internal buffer check");
236 return (-1); 233 return 0;
237 } 234 }
238 pBufferDesc->iBufferUsage = BUFFER_EMPTY; 235 pBufferDesc->iBufferUsage = BUFFER_EMPTY;
239 pBufferDesc->pSDLAudioDevice = _this; 236 pBufferDesc->pSDLAudioDevice = _this;
240 237
241 _this->hidden->pMixBuffers[i].ulBufferLength = 238 _this->hidden->pMixBuffers[i].ulBufferLength =
252 _this->hidden->iLastPlayedBuf = -1; 249 _this->hidden->iLastPlayedBuf = -1;
253 // Create event semaphore 250 // Create event semaphore
254 if (DosCreateEventSem 251 if (DosCreateEventSem
255 (NULL, &(_this->hidden->hevAudioBufferPlayed), 0, FALSE) != NO_ERROR) 252 (NULL, &(_this->hidden->hevAudioBufferPlayed), 0, FALSE) != NO_ERROR)
256 { 253 {
257 // Could not create event semaphore! 254 DART_CloseDevice(this);
258 {
259 int i;
260 for (i = 0; i < iNumBufs; i++)
261 SDL_free((void *) (_this->hidden->pMixBuffers[i].ulUserParm));
262 }
263 mciSendCommand(iDeviceOrd, MCI_BUFFER,
264 MCI_WAIT | MCI_DEALLOCATE_MEMORY,
265 &(_this->hidden->BufferParms), 0);
266 SDL_free(_this->hidden->pMixBuffers);
267 _this->hidden->pMixBuffers = NULL;
268 mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0);
269 SDL_SetError("Could not create event semaphore"); 255 SDL_SetError("Could not create event semaphore");
270 return (-1); 256 return 0;
271 } 257 }
272 // Store the new settings in global variables 258
273 _this->hidden->iCurrDeviceOrd = iDeviceOrd; 259 return 1;
274 _this->hidden->iCurrFreq = iFreq; 260 }
275 _this->hidden->iCurrBits = iBits; 261
276 _this->hidden->iCurrChannels = iChannels; 262 static void
277 _this->hidden->iCurrNumBufs = iNumBufs;
278 _this->hidden->iCurrBufSize = iBufSize;
279
280 return (0);
281 }
282
283
284
285 void
286 DART_ThreadInit(_THIS) 263 DART_ThreadInit(_THIS)
287 { 264 {
288 /* Increase the priority of this thread to make sure that 265 /* Increase the priority of this thread to make sure that
289 the audio will be continuous all the time! */ 266 the audio will be continuous all the time! */
290 #ifdef USE_DOSSETPRIORITY 267 #ifdef USE_DOSSETPRIORITY
291 if (SDL_getenv("SDL_USE_TIMECRITICAL_AUDIO")) { 268 if (SDL_getenv("SDL_USE_TIMECRITICAL_AUDIO")) {
292 #ifdef DEBUG_BUILD 269 #ifdef DEBUG_BUILD
293 printf 270 printf
294 ("[SDL_RunAudio] : Setting priority to TimeCritical+0! (TID%d)\n", 271 ("[DART_ThreadInit] : Setting priority to TimeCritical+0! (TID%d)\n",
295 SDL_ThreadID()); 272 SDL_ThreadID());
296 #endif 273 #endif
297 DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0); 274 DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0);
298 } else { 275 } else {
299 #ifdef DEBUG_BUILD 276 #ifdef DEBUG_BUILD
300 printf 277 printf
301 ("[SDL_RunAudio] : Setting priority to ForegroundServer+0! (TID%d)\n", 278 ("[DART_ThreadInit] : Setting priority to ForegroundServer+0! (TID%d)\n",
302 SDL_ThreadID()); 279 SDL_ThreadID());
303 #endif 280 #endif
304 DosSetPriority(PRTYS_THREAD, PRTYC_FOREGROUNDSERVER, 0, 0); 281 DosSetPriority(PRTYS_THREAD, PRTYC_FOREGROUNDSERVER, 0, 0);
305 } 282 }
306 #endif 283 #endif
307 } 284 }
308 285
309 /* This function waits until it is possible to write a full sound buffer */ 286 /* This function waits until it is possible to write a full sound buffer */
310 void 287 static void
311 DART_WaitAudio(_THIS) 288 DART_WaitDevice(_THIS)
312 { 289 {
313 int i; 290 int i;
314 pMixBufferDesc pBufDesc; 291 pMixBufferDesc pBufDesc;
315 ULONG ulPostCount; 292 ULONG ulPostCount;
316 293
324 // If there is no empty buffer, wait for one to be empty! 301 // If there is no empty buffer, wait for one to be empty!
325 DosWaitEventSem(_this->hidden->hevAudioBufferPlayed, 1000); // Wait max 1 sec!!! Important! 302 DosWaitEventSem(_this->hidden->hevAudioBufferPlayed, 1000); // Wait max 1 sec!!! Important!
326 return; 303 return;
327 } 304 }
328 305
329 void 306 static void
330 DART_PlayAudio(_THIS) 307 DART_PlayDevice(_THIS)
331 { 308 {
332 int iFreeBuf = _this->hidden->iNextFreeBuffer; 309 int iFreeBuf = _this->hidden->iNextFreeBuffer;
333 pMixBufferDesc pBufDesc; 310 pMixBufferDesc pBufDesc;
334 311
335 pBufDesc = 312 pBufDesc =
344 _this->hidden->iLastPlayedBuf = iFreeBuf; 321 _this->hidden->iLastPlayedBuf = iFreeBuf;
345 iFreeBuf = (iFreeBuf + 1) % _this->hidden->iCurrNumBufs; 322 iFreeBuf = (iFreeBuf + 1) % _this->hidden->iCurrNumBufs;
346 _this->hidden->iNextFreeBuffer = iFreeBuf; 323 _this->hidden->iNextFreeBuffer = iFreeBuf;
347 } 324 }
348 325
349 Uint8 * 326 static Uint8 *
350 DART_GetAudioBuf(_THIS) 327 DART_GetDeviceBuf(_THIS)
351 { 328 {
352 int iFreeBuf; 329 int iFreeBuf;
353 Uint8 *pResult; 330 Uint8 *pResult;
354 pMixBufferDesc pBufDesc; 331 pMixBufferDesc pBufDesc;
355 332
364 if (pBufDesc->iBufferUsage == BUFFER_EMPTY) { 341 if (pBufDesc->iBufferUsage == BUFFER_EMPTY) {
365 pResult = _this->hidden->pMixBuffers[iFreeBuf].pBuffer; 342 pResult = _this->hidden->pMixBuffers[iFreeBuf].pBuffer;
366 return pResult; 343 return pResult;
367 } 344 }
368 } else 345 } else
369 printf("[DART_GetAudioBuf] : ERROR! pBufDesc = %p\n", 346 printf("[DART_GetDeviceBuf] : ERROR! pBufDesc = %p\n",
370 pBufDesc); 347 pBufDesc);
371 } else 348 } else
372 printf("[DART_GetAudioBuf] : ERROR! _this->hidden = %p\n", 349 printf("[DART_GetDeviceBuf] : ERROR! _this->hidden = %p\n",
373 _this->hidden); 350 _this->hidden);
374 } else 351 } else
375 printf("[DART_GetAudioBuf] : ERROR! _this = %p\n", _this); 352 printf("[DART_GetDeviceBuf] : ERROR! _this = %p\n", _this);
376 return NULL; 353 return NULL;
377 } 354 }
378 355
379 void 356 static void
380 DART_WaitDone(_THIS) 357 DART_WaitDone(_THIS)
381 { 358 {
382 pMixBufferDesc pBufDesc; 359 pMixBufferDesc pBufDesc;
383 ULONG ulPostCount; 360 ULONG ulPostCount = 0;
384 APIRET rc; 361 APIRET rc = NO_ERROR;
385 362
386 pBufDesc = 363 pBufDesc = (pMixBufferDesc)
387 (pMixBufferDesc) _this->hidden->pMixBuffers[_this->hidden-> 364 _this->hidden->pMixBuffers[_this->hidden->iLastPlayedBuf].ulUserParm;
388 iLastPlayedBuf]. 365
389 ulUserParm;
390 rc = NO_ERROR;
391 while ((pBufDesc->iBufferUsage != BUFFER_EMPTY) && (rc == NO_ERROR)) { 366 while ((pBufDesc->iBufferUsage != BUFFER_EMPTY) && (rc == NO_ERROR)) {
392 DosResetEventSem(_this->hidden->hevAudioBufferPlayed, &ulPostCount); 367 DosResetEventSem(_this->hidden->hevAudioBufferPlayed, &ulPostCount);
393 rc = DosWaitEventSem(_this->hidden->hevAudioBufferPlayed, 1000); // 1 sec timeout! Important! 368 rc = DosWaitEventSem(_this->hidden->hevAudioBufferPlayed, 1000); // 1 sec timeout! Important!
394 } 369 }
395 } 370 }
396 371
397 void 372 static void
398 DART_CloseAudio(_THIS) 373 DART_CloseDevice(_THIS)
399 { 374 {
400 MCI_GENERIC_PARMS GenericParms; 375 MCI_GENERIC_PARMS GenericParms;
401 int rc; 376 int rc;
402 377 int i;
403 // Stop DART playback 378
404 rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_STOP, MCI_WAIT, 379 if (_this->hidden != NULL) {
405 &GenericParms, 0); 380 // Stop DART playback
406 if (rc != MCIERR_SUCCESS) { 381 if (_this->hidden->iCurrDeviceOrd) {
382 rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_STOP,
383 MCI_WAIT, &GenericParms, 0);
407 #ifdef SFX_DEBUG_BUILD 384 #ifdef SFX_DEBUG_BUILD
408 printf("Could not stop DART playback!\n"); 385 if (rc != MCIERR_SUCCESS) {
409 fflush(stdout); 386 printf("Could not stop DART playback!\n");
387 fflush(stdout);
388 }
410 #endif 389 #endif
411 } 390 }
412 // Close event semaphore 391
413 DosCloseEventSem(_this->hidden->hevAudioBufferPlayed); 392 // Close event semaphore
414 393 if (_this->hidden->hevAudioBufferPlayed) {
415 // Free memory of buffer descriptions 394 DosCloseEventSem(_this->hidden->hevAudioBufferPlayed);
416 { 395 _this->hidden->hevAudioBufferPlayed = 0;
417 int i; 396 }
418 for (i = 0; i < _this->hidden->iCurrNumBufs; i++) 397
398 // Free memory of buffer descriptions
399 for (i = 0; i < _this->hidden->iCurrNumBufs; i++) {
419 SDL_free((void *) (_this->hidden->pMixBuffers[i].ulUserParm)); 400 SDL_free((void *) (_this->hidden->pMixBuffers[i].ulUserParm));
420 } 401 _this->hidden->pMixBuffers[i].ulUserParm = 0;
421 402 }
422 // Deallocate buffers 403 _this->hidden->iCurrNumBufs = 0;
423 rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_BUFFER, 404
424 MCI_WAIT | MCI_DEALLOCATE_MEMORY, 405 // Deallocate buffers
425 &(_this->hidden->BufferParms), 0); 406 if (_this->hidden->iCurrDeviceOrd) {
426 407 rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_BUFFER,
427 // Free bufferlist 408 MCI_WAIT | MCI_DEALLOCATE_MEMORY,
428 SDL_free(_this->hidden->pMixBuffers); 409 &(_this->hidden->BufferParms), 0);
429 _this->hidden->pMixBuffers = NULL; 410 }
430 411
431 // Close dart 412 // Free bufferlist
432 rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_CLOSE, MCI_WAIT, 413 if (_this->hidden->pMixBuffers != NULL) {
433 &(GenericParms), 0); 414 SDL_free(_this->hidden->pMixBuffers);
434 } 415 _this->hidden->pMixBuffers = NULL;
435 416 }
436 /* Audio driver bootstrap functions */ 417
437 418 // Close dart
438 int 419 if (_this->hidden->iCurrDeviceOrd) {
439 Audio_Available(void) 420 rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_CLOSE,
440 { 421 MCI_WAIT, &(GenericParms), 0);
441 return (1); 422 }
442 } 423 _this->hidden->iCurrDeviceOrd = 0;
443 424
444 void 425 SDL_free(_this->hidden);
445 Audio_DeleteDevice(SDL_AudioDevice * device) 426 _this->hidden = NULL;
446 { 427 }
447 SDL_free(device->hidden); 428 }
448 SDL_free(device); 429
449 } 430 static int
450 431 DART_Available(void)
451 SDL_AudioDevice * 432 {
452 Audio_CreateDevice(int devindex) 433 return 1; /* Always available on OS/2 Warp */
453 { 434 }
454 SDL_AudioDevice *this; 435
455 436 static int
456 /* Initialize all variables that we clean on shutdown */ 437 DART_Init(SDL_AudioDriverImpl *impl)
457 this = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice)); 438 {
458 if (this) {
459 SDL_memset(this, 0, (sizeof *this));
460 this->hidden = (struct SDL_PrivateAudioData *)
461 SDL_malloc((sizeof *this->hidden));
462 }
463 if ((this == NULL) || (this->hidden == NULL)) {
464 SDL_OutOfMemory();
465 if (this)
466 SDL_free(this);
467 return (0);
468 }
469 SDL_memset(this->hidden, 0, (sizeof *this->hidden));
470
471 /* Set the function pointers */ 439 /* Set the function pointers */
472 this->OpenAudio = DART_OpenAudio; 440 impl->OpenDevice = DART_OpenDevice;
473 this->ThreadInit = DART_ThreadInit; 441 impl->ThreadInit = DART_ThreadInit;
474 this->WaitAudio = DART_WaitAudio; 442 impl->WaitDevice = DART_WaitDevice;
475 this->PlayAudio = DART_PlayAudio; 443 impl->GetDeviceBuf = DART_GetDeviceBuf;
476 this->GetAudioBuf = DART_GetAudioBuf; 444 impl->PlayDevice = DART_PlayDevice;
477 this->WaitDone = DART_WaitDone; 445 impl->WaitDone = DART_WaitDone;
478 this->CloseAudio = DART_CloseAudio; 446 impl->CloseDevice = DART_CloseDevice;
479 447 impl->OnlyHasDefaultOutputDevice = 1; /* !!! FIXME: is this right? */
480 this->free = Audio_DeleteDevice; 448
481 449 return 1;
482 return this; 450 }
483 } 451
484 452
485 AudioBootStrap DART_bootstrap = { 453 AudioBootStrap DART_bootstrap = {
486 "dart", "OS/2 Direct Audio RouTines (DART)", 454 "dart", "OS/2 Direct Audio RouTines (DART)",
487 Audio_Available, Audio_CreateDevice, 0 455 DART_Available, DART_Init, 0
488 }; 456 };
489 457
490 /* vi: set ts=4 sw=4 expandtab: */ 458 /* vi: set ts=4 sw=4 expandtab: */