Mercurial > sdl-ios-xcode
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: */ |