comparison src/audio/dart/SDL_dart.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 adf732f1f016
children 866052b01ee5
comparison
equal deleted inserted replaced
2048:6067c7f9a672 2049:5f6550e5184f
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;
81 int iDeviceOrd = 0; // Default device to be used 80 int iDeviceOrd = 0; // Default device to be used
82 int bOpenShared = 1; // Try opening it shared 81 int bOpenShared = 1; // Try opening it shared
83 int iBits = 16; // Default is 16 bits signed 82 int iBits = 16; // Default is 16 bits signed
84 int iFreq = 44100; // Default is 44KHz 83 int iFreq = 44100; // Default is 44KHz
85 int iChannels = 2; // Default is 2 channels (Stereo) 84 int iChannels = 2; // Default is 2 channels (Stereo)
87 int iBufSize; 86 int iBufSize;
88 int iOpenMode; 87 int iOpenMode;
89 int iSilence; 88 int iSilence;
90 int rc; 89 int rc;
91 90
91 /* Initialize all variables that we clean on shutdown */
92 _this->hidden = (struct SDL_PrivateAudioData *)
93 SDL_malloc((sizeof *_this->hidden));
94 if (_this->hidden == NULL) {
95 SDL_OutOfMemory();
96 return 0;
97 }
98 SDL_memset(_this->hidden, 0, (sizeof *_this->hidden));
99
92 // First thing is to try to open a given DART device! 100 // First thing is to try to open a given DART device!
93 SDL_memset(&AmpOpenParms, 0, sizeof(MCI_AMP_OPEN_PARMS)); 101 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! 102 // pszDeviceType should contain the device type in low word, and device ordinal in high word!
95 AmpOpenParms.pszDeviceType = 103 AmpOpenParms.pszDeviceType =
96 (PSZ) (MCI_DEVTYPE_AUDIO_AMPMIX | (iDeviceOrd << 16)); 104 (PSZ) (MCI_DEVTYPE_AUDIO_AMPMIX | (iDeviceOrd << 16));
98 iOpenMode = MCI_WAIT | MCI_OPEN_TYPE_ID; 106 iOpenMode = MCI_WAIT | MCI_OPEN_TYPE_ID;
99 if (bOpenShared) 107 if (bOpenShared)
100 iOpenMode |= MCI_OPEN_SHAREABLE; 108 iOpenMode |= MCI_OPEN_SHAREABLE;
101 109
102 rc = mciSendCommand(0, MCI_OPEN, iOpenMode, (PVOID) & AmpOpenParms, 0); 110 rc = mciSendCommand(0, MCI_OPEN, iOpenMode, (PVOID) & AmpOpenParms, 0);
103 if (rc != MCIERR_SUCCESS) // No audio available?? 111 if (rc != MCIERR_SUCCESS) { // No audio available??
104 return (-1); 112 DART_CloseDevice(_this);
113 SDL_SetError("DART: Couldn't open audio device.");
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 > 2) 122 if (_this->spec.channels > 4)
111 spec->channels = 2; // !!! FIXME: more than stereo support in OS/2? 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 return; 265 /* Increase the priority of this thread to make sure that
266 the audio will be continuous all the time! */
267 #ifdef USE_DOSSETPRIORITY
268 if (SDL_getenv("SDL_USE_TIMECRITICAL_AUDIO")) {
269 #ifdef DEBUG_BUILD
270 printf
271 ("[DART_ThreadInit] : Setting priority to TimeCritical+0! (TID%d)\n",
272 SDL_ThreadID());
273 #endif
274 DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0);
275 } else {
276 #ifdef DEBUG_BUILD
277 printf
278 ("[DART_ThreadInit] : Setting priority to ForegroundServer+0! (TID%d)\n",
279 SDL_ThreadID());
280 #endif
281 DosSetPriority(PRTYS_THREAD, PRTYC_FOREGROUNDSERVER, 0, 0);
282 }
283 #endif
289 } 284 }
290 285
291 /* 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 */
292 void 287 static void
293 DART_WaitAudio(_THIS) 288 DART_WaitDevice(_THIS)
294 { 289 {
295 int i; 290 int i;
296 pMixBufferDesc pBufDesc; 291 pMixBufferDesc pBufDesc;
297 ULONG ulPostCount; 292 ULONG ulPostCount;
298 293
306 // 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!
307 DosWaitEventSem(_this->hidden->hevAudioBufferPlayed, 1000); // Wait max 1 sec!!! Important! 302 DosWaitEventSem(_this->hidden->hevAudioBufferPlayed, 1000); // Wait max 1 sec!!! Important!
308 return; 303 return;
309 } 304 }
310 305
311 void 306 static void
312 DART_PlayAudio(_THIS) 307 DART_PlayDevice(_THIS)
313 { 308 {
314 int iFreeBuf = _this->hidden->iNextFreeBuffer; 309 int iFreeBuf = _this->hidden->iNextFreeBuffer;
315 pMixBufferDesc pBufDesc; 310 pMixBufferDesc pBufDesc;
316 311
317 pBufDesc = 312 pBufDesc =
326 _this->hidden->iLastPlayedBuf = iFreeBuf; 321 _this->hidden->iLastPlayedBuf = iFreeBuf;
327 iFreeBuf = (iFreeBuf + 1) % _this->hidden->iCurrNumBufs; 322 iFreeBuf = (iFreeBuf + 1) % _this->hidden->iCurrNumBufs;
328 _this->hidden->iNextFreeBuffer = iFreeBuf; 323 _this->hidden->iNextFreeBuffer = iFreeBuf;
329 } 324 }
330 325
331 Uint8 * 326 static Uint8 *
332 DART_GetAudioBuf(_THIS) 327 DART_GetDeviceBuf(_THIS)
333 { 328 {
334 int iFreeBuf; 329 int iFreeBuf;
335 Uint8 *pResult; 330 Uint8 *pResult;
336 pMixBufferDesc pBufDesc; 331 pMixBufferDesc pBufDesc;
337 332
346 if (pBufDesc->iBufferUsage == BUFFER_EMPTY) { 341 if (pBufDesc->iBufferUsage == BUFFER_EMPTY) {
347 pResult = _this->hidden->pMixBuffers[iFreeBuf].pBuffer; 342 pResult = _this->hidden->pMixBuffers[iFreeBuf].pBuffer;
348 return pResult; 343 return pResult;
349 } 344 }
350 } else 345 } else
351 printf("[DART_GetAudioBuf] : ERROR! pBufDesc = %p\n", 346 printf("[DART_GetDeviceBuf] : ERROR! pBufDesc = %p\n",
352 pBufDesc); 347 pBufDesc);
353 } else 348 } else
354 printf("[DART_GetAudioBuf] : ERROR! _this->hidden = %p\n", 349 printf("[DART_GetDeviceBuf] : ERROR! _this->hidden = %p\n",
355 _this->hidden); 350 _this->hidden);
356 } else 351 } else
357 printf("[DART_GetAudioBuf] : ERROR! _this = %p\n", _this); 352 printf("[DART_GetDeviceBuf] : ERROR! _this = %p\n", _this);
358 return NULL; 353 return NULL;
359 } 354 }
360 355
361 void 356 static void
362 DART_WaitDone(_THIS) 357 DART_WaitDone(_THIS)
363 { 358 {
364 pMixBufferDesc pBufDesc; 359 pMixBufferDesc pBufDesc;
365 ULONG ulPostCount; 360 ULONG ulPostCount = 0;
366 APIRET rc; 361 APIRET rc = NO_ERROR;
367 362
368 pBufDesc = 363 pBufDesc = (pMixBufferDesc)
369 (pMixBufferDesc) _this->hidden->pMixBuffers[_this->hidden-> 364 _this->hidden->pMixBuffers[_this->hidden->iLastPlayedBuf].ulUserParm;
370 iLastPlayedBuf]. 365
371 ulUserParm;
372 rc = NO_ERROR;
373 while ((pBufDesc->iBufferUsage != BUFFER_EMPTY) && (rc == NO_ERROR)) { 366 while ((pBufDesc->iBufferUsage != BUFFER_EMPTY) && (rc == NO_ERROR)) {
374 DosResetEventSem(_this->hidden->hevAudioBufferPlayed, &ulPostCount); 367 DosResetEventSem(_this->hidden->hevAudioBufferPlayed, &ulPostCount);
375 rc = DosWaitEventSem(_this->hidden->hevAudioBufferPlayed, 1000); // 1 sec timeout! Important! 368 rc = DosWaitEventSem(_this->hidden->hevAudioBufferPlayed, 1000); // 1 sec timeout! Important!
376 } 369 }
377 } 370 }
378 371
379 void 372 static void
380 DART_CloseAudio(_THIS) 373 DART_CloseDevice(_THIS)
381 { 374 {
382 MCI_GENERIC_PARMS GenericParms; 375 MCI_GENERIC_PARMS GenericParms;
383 int rc; 376 int rc;
384 377 int i;
385 // Stop DART playback 378
386 rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_STOP, MCI_WAIT, 379 if (_this->hidden != NULL) {
387 &GenericParms, 0); 380 // Stop DART playback
388 if (rc != MCIERR_SUCCESS) { 381 if (_this->hidden->iCurrDeviceOrd) {
382 rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_STOP,
383 MCI_WAIT, &GenericParms, 0);
389 #ifdef SFX_DEBUG_BUILD 384 #ifdef SFX_DEBUG_BUILD
390 printf("Could not stop DART playback!\n"); 385 if (rc != MCIERR_SUCCESS) {
391 fflush(stdout); 386 printf("Could not stop DART playback!\n");
387 fflush(stdout);
388 }
392 #endif 389 #endif
393 } 390 }
394 // Close event semaphore 391
395 DosCloseEventSem(_this->hidden->hevAudioBufferPlayed); 392 // Close event semaphore
396 393 if (_this->hidden->hevAudioBufferPlayed) {
397 // Free memory of buffer descriptions 394 DosCloseEventSem(_this->hidden->hevAudioBufferPlayed);
398 { 395 _this->hidden->hevAudioBufferPlayed = 0;
399 int i; 396 }
400 for (i = 0; i < _this->hidden->iCurrNumBufs; i++) 397
398 // Free memory of buffer descriptions
399 for (i = 0; i < _this->hidden->iCurrNumBufs; i++) {
401 SDL_free((void *) (_this->hidden->pMixBuffers[i].ulUserParm)); 400 SDL_free((void *) (_this->hidden->pMixBuffers[i].ulUserParm));
402 } 401 _this->hidden->pMixBuffers[i].ulUserParm = 0;
403 402 }
404 // Deallocate buffers 403 _this->hidden->iCurrNumBufs = 0;
405 rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_BUFFER, 404
406 MCI_WAIT | MCI_DEALLOCATE_MEMORY, 405 // Deallocate buffers
407 &(_this->hidden->BufferParms), 0); 406 if (_this->hidden->iCurrDeviceOrd) {
408 407 rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_BUFFER,
409 // Free bufferlist 408 MCI_WAIT | MCI_DEALLOCATE_MEMORY,
410 SDL_free(_this->hidden->pMixBuffers); 409 &(_this->hidden->BufferParms), 0);
411 _this->hidden->pMixBuffers = NULL; 410 }
412 411
413 // Close dart 412 // Free bufferlist
414 rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_CLOSE, MCI_WAIT, 413 if (_this->hidden->pMixBuffers != NULL) {
415 &(GenericParms), 0); 414 SDL_free(_this->hidden->pMixBuffers);
416 } 415 _this->hidden->pMixBuffers = NULL;
417 416 }
418 /* Audio driver bootstrap functions */ 417
419 418 // Close dart
420 int 419 if (_this->hidden->iCurrDeviceOrd) {
421 Audio_Available(void) 420 rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_CLOSE,
422 { 421 MCI_WAIT, &(GenericParms), 0);
423 return (1); 422 }
424 } 423 _this->hidden->iCurrDeviceOrd = 0;
425 424
426 void 425 SDL_free(_this->hidden);
427 Audio_DeleteDevice(SDL_AudioDevice * device) 426 _this->hidden = NULL;
428 { 427 }
429 SDL_free(device->hidden); 428 }
430 SDL_free(device); 429
431 } 430
432 431 static int
433 SDL_AudioDevice * 432 DART_Init(SDL_AudioDriverImpl *impl)
434 Audio_CreateDevice(int devindex) 433 {
435 {
436 SDL_AudioDevice *this;
437
438 /* Initialize all variables that we clean on shutdown */
439 this = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice));
440 if (this) {
441 SDL_memset(this, 0, (sizeof *this));
442 this->hidden = (struct SDL_PrivateAudioData *)
443 SDL_malloc((sizeof *this->hidden));
444 }
445 if ((this == NULL) || (this->hidden == NULL)) {
446 SDL_OutOfMemory();
447 if (this)
448 SDL_free(this);
449 return (0);
450 }
451 SDL_memset(this->hidden, 0, (sizeof *this->hidden));
452
453 /* Set the function pointers */ 434 /* Set the function pointers */
454 this->OpenAudio = DART_OpenAudio; 435 impl->OpenDevice = DART_OpenDevice;
455 this->ThreadInit = DART_ThreadInit; 436 impl->ThreadInit = DART_ThreadInit;
456 this->WaitAudio = DART_WaitAudio; 437 impl->WaitDevice = DART_WaitDevice;
457 this->PlayAudio = DART_PlayAudio; 438 impl->GetDeviceBuf = DART_GetDeviceBuf;
458 this->GetAudioBuf = DART_GetAudioBuf; 439 impl->PlayDevice = DART_PlayDevice;
459 this->WaitDone = DART_WaitDone; 440 impl->WaitDone = DART_WaitDone;
460 this->CloseAudio = DART_CloseAudio; 441 impl->CloseDevice = DART_CloseDevice;
461 442 impl->OnlyHasDefaultOutputDevice = 1; /* !!! FIXME: is this right? */
462 this->free = Audio_DeleteDevice; 443
463 444 return 1;
464 return this; 445 }
465 } 446
466 447
467 AudioBootStrap DART_bootstrap = { 448 AudioBootStrap DART_bootstrap = {
468 "dart", "OS/2 Direct Audio RouTines (DART)", 449 "dart", "OS/2 Direct Audio RouTines (DART)", DART_Init, 0
469 Audio_Available, Audio_CreateDevice
470 }; 450 };
471 451
472 /* vi: set ts=4 sw=4 expandtab: */ 452 /* vi: set ts=4 sw=4 expandtab: */