Mercurial > sdl-ios-xcode
annotate src/audio/dart/SDL_dart.c @ 3851:405a192b68e7 SDL-1.2
Backport from 1.3: most of the audio drivers can now handle data
conversion at a higher level when they can't open the hardware in the
exact format requested.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Fri, 01 Sep 2006 22:50:24 +0000 |
parents | d910939febfa |
children | 5b5e549382b3 |
rev | line source |
---|---|
1190 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1190
diff
changeset
|
3 Copyright (C) 1997-2006 Sam Lantinga |
1190 | 4 |
5 This library is free software; you can redistribute it and/or | |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1190
diff
changeset
|
6 modify it under the terms of the GNU Lesser General Public |
1190 | 7 License as published by the Free Software Foundation; either |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1190
diff
changeset
|
8 version 2.1 of the License, or (at your option) any later version. |
1190 | 9 |
10 This library is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1190
diff
changeset
|
13 Lesser General Public License for more details. |
1190 | 14 |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1190
diff
changeset
|
15 You should have received a copy of the GNU Lesser General Public |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1190
diff
changeset
|
16 License along with this library; if not, write to the Free Software |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1190
diff
changeset
|
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
1190 | 18 |
19 Sam Lantinga | |
20 slouken@libsdl.org | |
21 */ | |
1402
d910939febfa
Use consistent identifiers for the various platforms we support.
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
22 #include "SDL_config.h" |
1190 | 23 |
24 /* Allow access to a raw mixing buffer */ | |
25 | |
26 #include "SDL_timer.h" | |
27 #include "SDL_audio.h" | |
1361
19418e4422cb
New configure-based build system. Still work in progress, but much improved
Sam Lantinga <slouken@libsdl.org>
parents:
1358
diff
changeset
|
28 #include "../SDL_audio_c.h" |
1190 | 29 #include "SDL_dart.h" |
30 | |
31 // Buffer states: | |
32 #define BUFFER_EMPTY 0 | |
33 #define BUFFER_USED 1 | |
34 | |
35 typedef struct _tMixBufferDesc { | |
36 int iBufferUsage; // BUFFER_EMPTY or BUFFER_USED | |
37 SDL_AudioDevice *pSDLAudioDevice; | |
38 } tMixBufferDesc, *pMixBufferDesc; | |
39 | |
40 | |
41 //--------------------------------------------------------------------- | |
42 // DARTEventFunc | |
43 // | |
44 // This function is called by DART, when an event occures, like end of | |
45 // playback of a buffer, etc... | |
46 //--------------------------------------------------------------------- | |
47 LONG APIENTRY DARTEventFunc(ULONG ulStatus, | |
48 PMCI_MIX_BUFFER pBuffer, | |
49 ULONG ulFlags) | |
50 { | |
51 if (ulFlags && MIX_WRITE_COMPLETE) | |
52 { // Playback of buffer completed! | |
53 | |
54 // Get pointer to buffer description | |
55 pMixBufferDesc pBufDesc; | |
56 | |
57 if (pBuffer) | |
58 { | |
59 pBufDesc = (pMixBufferDesc) (*pBuffer).ulUserParm; | |
60 | |
61 if (pBufDesc) | |
62 { | |
63 SDL_AudioDevice *pSDLAudioDevice = pBufDesc->pSDLAudioDevice; | |
64 // Set the buffer to be empty | |
65 pBufDesc->iBufferUsage = BUFFER_EMPTY; | |
66 // And notify DART feeder thread that it will have to work a bit. | |
67 if (pSDLAudioDevice) | |
68 DosPostEventSem(pSDLAudioDevice->hidden->hevAudioBufferPlayed); | |
69 } | |
70 } | |
71 } | |
72 return TRUE; | |
73 } | |
74 | |
75 | |
76 int DART_OpenAudio(_THIS, SDL_AudioSpec *spec) | |
77 { | |
3851
405a192b68e7
Backport from 1.3: most of the audio drivers can now handle data
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
78 SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format); |
405a192b68e7
Backport from 1.3: most of the audio drivers can now handle data
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
79 int valid_datatype = 0; |
1190 | 80 MCI_AMP_OPEN_PARMS AmpOpenParms; |
81 MCI_GENERIC_PARMS GenericParms; | |
82 int iDeviceOrd = 0; // Default device to be used | |
83 int bOpenShared = 1; // Try opening it shared | |
84 int iBits = 16; // Default is 16 bits signed | |
85 int iFreq = 44100; // Default is 44KHz | |
86 int iChannels = 2; // Default is 2 channels (Stereo) | |
87 int iNumBufs = 2; // Number of audio buffers: 2 | |
88 int iBufSize; | |
89 int iOpenMode; | |
90 int iSilence; | |
91 int rc; | |
92 | |
93 // First thing is to try to open a given DART device! | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
94 SDL_memset(&AmpOpenParms, 0, sizeof(MCI_AMP_OPEN_PARMS)); |
1190 | 95 // pszDeviceType should contain the device type in low word, and device ordinal in high word! |
96 AmpOpenParms.pszDeviceType = (PSZ) (MCI_DEVTYPE_AUDIO_AMPMIX | (iDeviceOrd << 16)); | |
97 | |
98 iOpenMode = MCI_WAIT | MCI_OPEN_TYPE_ID; | |
99 if (bOpenShared) iOpenMode |= MCI_OPEN_SHAREABLE; | |
100 | |
101 rc = mciSendCommand( 0, MCI_OPEN, | |
102 iOpenMode, | |
103 (PVOID) &AmpOpenParms, 0); | |
104 if (rc!=MCIERR_SUCCESS) // No audio available?? | |
105 return (-1); | |
106 // Save the device ID we got from DART! | |
107 // We will use this in the next calls! | |
108 iDeviceOrd = AmpOpenParms.usDeviceID; | |
109 | |
110 // Determine the audio parameters from the AudioSpec | |
3851
405a192b68e7
Backport from 1.3: most of the audio drivers can now handle data
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
111 if (spec->channels > 2) |
405a192b68e7
Backport from 1.3: most of the audio drivers can now handle data
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
112 spec->channels = 2; // !!! FIXME: more than stereo support in OS/2? |
405a192b68e7
Backport from 1.3: most of the audio drivers can now handle data
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
113 |
405a192b68e7
Backport from 1.3: most of the audio drivers can now handle data
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
114 while ((!valid_datatype) && (test_format)) { |
405a192b68e7
Backport from 1.3: most of the audio drivers can now handle data
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
115 spec->format = test_format; |
405a192b68e7
Backport from 1.3: most of the audio drivers can now handle data
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
116 valid_datatype = 1; |
405a192b68e7
Backport from 1.3: most of the audio drivers can now handle data
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
117 switch (test_format) { |
405a192b68e7
Backport from 1.3: most of the audio drivers can now handle data
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
118 case AUDIO_U8: |
405a192b68e7
Backport from 1.3: most of the audio drivers can now handle data
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
119 // Unsigned 8 bit audio data |
1190 | 120 iSilence = 0x80; |
121 iBits = 8; | |
122 break; | |
3851
405a192b68e7
Backport from 1.3: most of the audio drivers can now handle data
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
123 |
405a192b68e7
Backport from 1.3: most of the audio drivers can now handle data
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
124 case AUDIO_S16LSB: |
405a192b68e7
Backport from 1.3: most of the audio drivers can now handle data
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
125 // Signed 16 bit audio data |
1190 | 126 iSilence = 0x00; |
127 iBits = 16; | |
128 break; | |
3851
405a192b68e7
Backport from 1.3: most of the audio drivers can now handle data
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
129 |
405a192b68e7
Backport from 1.3: most of the audio drivers can now handle data
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
130 default: |
405a192b68e7
Backport from 1.3: most of the audio drivers can now handle data
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
131 valid_datatype = 0; |
405a192b68e7
Backport from 1.3: most of the audio drivers can now handle data
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
132 test_format = SDL_NextAudioFormat(); |
405a192b68e7
Backport from 1.3: most of the audio drivers can now handle data
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
133 break; |
405a192b68e7
Backport from 1.3: most of the audio drivers can now handle data
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
134 } |
1190 | 135 } |
3851
405a192b68e7
Backport from 1.3: most of the audio drivers can now handle data
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
136 |
405a192b68e7
Backport from 1.3: most of the audio drivers can now handle data
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
137 if (!valid_datatype) { // shouldn't happen, but just in case... |
405a192b68e7
Backport from 1.3: most of the audio drivers can now handle data
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
138 // Close DART, and exit with error code! |
405a192b68e7
Backport from 1.3: most of the audio drivers can now handle data
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
139 mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0); |
405a192b68e7
Backport from 1.3: most of the audio drivers can now handle data
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
140 SDL_SetError("Unsupported audio format"); |
405a192b68e7
Backport from 1.3: most of the audio drivers can now handle data
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
141 return (-1); |
405a192b68e7
Backport from 1.3: most of the audio drivers can now handle data
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
142 } |
405a192b68e7
Backport from 1.3: most of the audio drivers can now handle data
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
143 |
1190 | 144 iFreq = spec->freq; |
145 iChannels = spec->channels; | |
146 /* Update the fragment size as size in bytes */ | |
147 SDL_CalculateAudioSpec(spec); | |
148 iBufSize = spec->size; | |
149 | |
150 // Now query this device if it supports the given freq/bits/channels! | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
151 SDL_memset(&(_this->hidden->MixSetupParms), 0, sizeof(MCI_MIXSETUP_PARMS)); |
1190 | 152 _this->hidden->MixSetupParms.ulBitsPerSample = iBits; |
153 _this->hidden->MixSetupParms.ulFormatTag = MCI_WAVE_FORMAT_PCM; | |
154 _this->hidden->MixSetupParms.ulSamplesPerSec = iFreq; | |
155 _this->hidden->MixSetupParms.ulChannels = iChannels; | |
156 _this->hidden->MixSetupParms.ulFormatMode = MCI_PLAY; | |
157 _this->hidden->MixSetupParms.ulDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO; | |
158 _this->hidden->MixSetupParms.pmixEvent = DARTEventFunc; | |
159 rc = mciSendCommand (iDeviceOrd, MCI_MIXSETUP, | |
160 MCI_WAIT | MCI_MIXSETUP_QUERYMODE, | |
161 &(_this->hidden->MixSetupParms), 0); | |
162 if (rc!=MCIERR_SUCCESS) | |
163 { // The device cannot handle this format! | |
164 // Close DART, and exit with error code! | |
165 mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0); | |
166 SDL_SetError("Audio device doesn't support requested audio format"); | |
167 return(-1); | |
168 } | |
169 // The device can handle this format, so initialize! | |
170 rc = mciSendCommand(iDeviceOrd, MCI_MIXSETUP, | |
171 MCI_WAIT | MCI_MIXSETUP_INIT, | |
172 &(_this->hidden->MixSetupParms), 0); | |
173 if (rc!=MCIERR_SUCCESS) | |
174 { // The device could not be opened! | |
175 // Close DART, and exit with error code! | |
176 mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0); | |
177 SDL_SetError("Audio device could not be set up"); | |
178 return(-1); | |
179 } | |
180 // Ok, the device is initialized. | |
181 // Now we should allocate buffers. For this, we need a place where | |
182 // the buffer descriptors will be: | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
183 _this->hidden->pMixBuffers = (MCI_MIX_BUFFER *) SDL_malloc(sizeof(MCI_MIX_BUFFER)*iNumBufs); |
1190 | 184 if (!(_this->hidden->pMixBuffers)) |
185 { // Not enough memory! | |
186 // Close DART, and exit with error code! | |
187 mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0); | |
188 SDL_SetError("Not enough memory for audio buffer descriptors"); | |
189 return(-1); | |
190 } | |
191 // Now that we have the place for buffer list, we can ask DART for the | |
192 // buffers! | |
193 _this->hidden->BufferParms.ulNumBuffers = iNumBufs; // Number of buffers | |
194 _this->hidden->BufferParms.ulBufferSize = iBufSize; // each with this size | |
195 _this->hidden->BufferParms.pBufList = _this->hidden->pMixBuffers; // getting descriptorts into this list | |
196 // Allocate buffers! | |
197 rc = mciSendCommand(iDeviceOrd, MCI_BUFFER, | |
198 MCI_WAIT | MCI_ALLOCATE_MEMORY, | |
199 &(_this->hidden->BufferParms), 0); | |
200 if ((rc!=MCIERR_SUCCESS) || (iNumBufs != _this->hidden->BufferParms.ulNumBuffers) || (_this->hidden->BufferParms.ulBufferSize==0)) | |
201 { // Could not allocate memory! | |
202 // Close DART, and exit with error code! | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
203 SDL_free(_this->hidden->pMixBuffers); _this->hidden->pMixBuffers = NULL; |
1190 | 204 mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0); |
205 SDL_SetError("DART could not allocate buffers"); | |
206 return(-1); | |
207 } | |
208 // Ok, we have all the buffers allocated, let's mark them! | |
209 { | |
210 int i; | |
211 for (i=0; i<iNumBufs; i++) | |
212 { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
213 pMixBufferDesc pBufferDesc = (pMixBufferDesc) SDL_malloc(sizeof(tMixBufferDesc));; |
1190 | 214 // Check if this buffer was really allocated by DART |
215 if ((!(_this->hidden->pMixBuffers[i].pBuffer)) || (!pBufferDesc)) | |
216 { // Wrong buffer! | |
217 // Close DART, and exit with error code! | |
218 // Free buffer descriptions | |
219 { int j; | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
220 for (j=0; j<i; j++) SDL_free((void *)(_this->hidden->pMixBuffers[j].ulUserParm)); |
1190 | 221 } |
222 // and cleanup | |
223 mciSendCommand(iDeviceOrd, MCI_BUFFER, MCI_WAIT | MCI_DEALLOCATE_MEMORY, &(_this->hidden->BufferParms), 0); | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
224 SDL_free(_this->hidden->pMixBuffers); _this->hidden->pMixBuffers = NULL; |
1190 | 225 mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0); |
226 SDL_SetError("Error at internal buffer check"); | |
227 return(-1); | |
228 } | |
229 pBufferDesc->iBufferUsage = BUFFER_EMPTY; | |
230 pBufferDesc->pSDLAudioDevice = _this; | |
231 | |
232 _this->hidden->pMixBuffers[i].ulBufferLength = _this->hidden->BufferParms.ulBufferSize; | |
233 _this->hidden->pMixBuffers[i].ulUserParm = (ULONG) pBufferDesc; // User parameter: Description of buffer | |
234 _this->hidden->pMixBuffers[i].ulFlags = 0; // Some stuff should be flagged here for DART, like end of | |
235 // audio data, but as we will continously send | |
236 // audio data, there will be no end.:) | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
237 SDL_memset(_this->hidden->pMixBuffers[i].pBuffer, iSilence, iBufSize); |
1190 | 238 } |
239 } | |
240 _this->hidden->iNextFreeBuffer = 0; | |
241 _this->hidden->iLastPlayedBuf = -1; | |
242 // Create event semaphore | |
243 if (DosCreateEventSem(NULL, &(_this->hidden->hevAudioBufferPlayed), 0, FALSE)!=NO_ERROR) | |
244 { | |
245 // Could not create event semaphore! | |
246 { | |
247 int i; | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
248 for (i=0; i<iNumBufs; i++) SDL_free((void *)(_this->hidden->pMixBuffers[i].ulUserParm)); |
1190 | 249 } |
250 mciSendCommand(iDeviceOrd, MCI_BUFFER, MCI_WAIT | MCI_DEALLOCATE_MEMORY, &(_this->hidden->BufferParms), 0); | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
251 SDL_free(_this->hidden->pMixBuffers); _this->hidden->pMixBuffers = NULL; |
1190 | 252 mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0); |
253 SDL_SetError("Could not create event semaphore"); | |
254 return(-1); | |
255 } | |
256 | |
257 // Store the new settings in global variables | |
258 _this->hidden->iCurrDeviceOrd = iDeviceOrd; | |
259 _this->hidden->iCurrFreq = iFreq; | |
260 _this->hidden->iCurrBits = iBits; | |
261 _this->hidden->iCurrChannels = iChannels; | |
262 _this->hidden->iCurrNumBufs = iNumBufs; | |
263 _this->hidden->iCurrBufSize = iBufSize; | |
264 | |
265 return (0); | |
266 } | |
267 | |
268 | |
269 | |
270 void DART_ThreadInit(_THIS) | |
271 { | |
272 return; | |
273 } | |
274 | |
275 /* This function waits until it is possible to write a full sound buffer */ | |
276 void DART_WaitAudio(_THIS) | |
277 { | |
278 int i; | |
279 pMixBufferDesc pBufDesc; | |
280 ULONG ulPostCount; | |
281 | |
282 DosResetEventSem(_this->hidden->hevAudioBufferPlayed, &ulPostCount); | |
283 // If there is already an empty buffer, then return now! | |
284 for (i=0; i<_this->hidden->iCurrNumBufs; i++) | |
285 { | |
286 pBufDesc = (pMixBufferDesc) _this->hidden->pMixBuffers[i].ulUserParm; | |
287 if (pBufDesc->iBufferUsage == BUFFER_EMPTY) | |
288 return; | |
289 } | |
290 // If there is no empty buffer, wait for one to be empty! | |
291 DosWaitEventSem(_this->hidden->hevAudioBufferPlayed, 1000); // Wait max 1 sec!!! Important! | |
292 return; | |
293 } | |
294 | |
295 void DART_PlayAudio(_THIS) | |
296 { | |
297 int iFreeBuf = _this->hidden->iNextFreeBuffer; | |
298 pMixBufferDesc pBufDesc; | |
299 | |
300 pBufDesc = (pMixBufferDesc) _this->hidden->pMixBuffers[iFreeBuf].ulUserParm; | |
301 pBufDesc->iBufferUsage = BUFFER_USED; | |
302 // Send it to DART to be queued | |
303 _this->hidden->MixSetupParms.pmixWrite(_this->hidden->MixSetupParms.ulMixHandle, | |
304 &(_this->hidden->pMixBuffers[iFreeBuf]), 1); | |
305 | |
306 _this->hidden->iLastPlayedBuf = iFreeBuf; | |
307 iFreeBuf = (iFreeBuf+1) % _this->hidden->iCurrNumBufs; | |
308 _this->hidden->iNextFreeBuffer = iFreeBuf; | |
309 } | |
310 | |
311 Uint8 *DART_GetAudioBuf(_THIS) | |
312 { | |
313 int iFreeBuf; | |
314 Uint8 *pResult; | |
315 pMixBufferDesc pBufDesc; | |
316 | |
317 if (_this) | |
318 { | |
319 if (_this->hidden) | |
320 { | |
321 iFreeBuf = _this->hidden->iNextFreeBuffer; | |
322 pBufDesc = (pMixBufferDesc) _this->hidden->pMixBuffers[iFreeBuf].ulUserParm; | |
323 | |
324 if (pBufDesc) | |
325 { | |
326 if (pBufDesc->iBufferUsage == BUFFER_EMPTY) | |
327 { | |
328 pResult = _this->hidden->pMixBuffers[iFreeBuf].pBuffer; | |
329 return pResult; | |
330 } | |
331 } else | |
332 printf("[DART_GetAudioBuf] : ERROR! pBufDesc = %p\n", pBufDesc); | |
333 } else | |
334 printf("[DART_GetAudioBuf] : ERROR! _this->hidden = %p\n", _this->hidden); | |
335 } else | |
336 printf("[DART_GetAudioBuf] : ERROR! _this = %p\n", _this); | |
337 return NULL; | |
338 } | |
339 | |
340 void DART_WaitDone(_THIS) | |
341 { | |
342 pMixBufferDesc pBufDesc; | |
343 ULONG ulPostCount; | |
344 APIRET rc; | |
345 | |
346 pBufDesc = (pMixBufferDesc) _this->hidden->pMixBuffers[_this->hidden->iLastPlayedBuf].ulUserParm; | |
347 rc = NO_ERROR; | |
348 while ((pBufDesc->iBufferUsage != BUFFER_EMPTY) && (rc==NO_ERROR)) | |
349 { | |
350 DosResetEventSem(_this->hidden->hevAudioBufferPlayed, &ulPostCount); | |
351 rc = DosWaitEventSem(_this->hidden->hevAudioBufferPlayed, 1000); // 1 sec timeout! Important! | |
352 } | |
353 } | |
354 | |
355 void DART_CloseAudio(_THIS) | |
356 { | |
357 MCI_GENERIC_PARMS GenericParms; | |
358 int rc; | |
359 | |
360 // Stop DART playback | |
361 rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_STOP, MCI_WAIT, &GenericParms, 0); | |
362 if (rc!=MCIERR_SUCCESS) | |
363 { | |
364 #ifdef SFX_DEBUG_BUILD | |
365 printf("Could not stop DART playback!\n"); | |
366 fflush(stdout); | |
367 #endif | |
368 } | |
369 | |
370 // Close event semaphore | |
371 DosCloseEventSem(_this->hidden->hevAudioBufferPlayed); | |
372 | |
373 // Free memory of buffer descriptions | |
374 { | |
375 int i; | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
376 for (i=0; i<_this->hidden->iCurrNumBufs; i++) SDL_free((void *)(_this->hidden->pMixBuffers[i].ulUserParm)); |
1190 | 377 } |
378 | |
379 // Deallocate buffers | |
380 rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_BUFFER, MCI_WAIT | MCI_DEALLOCATE_MEMORY, &(_this->hidden->BufferParms), 0); | |
381 | |
382 // Free bufferlist | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
383 SDL_free(_this->hidden->pMixBuffers); _this->hidden->pMixBuffers = NULL; |
1190 | 384 |
385 // Close dart | |
386 rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_CLOSE, MCI_WAIT, &(GenericParms), 0); | |
387 } | |
388 | |
389 /* Audio driver bootstrap functions */ | |
390 | |
391 int Audio_Available(void) | |
392 { | |
393 return(1); | |
394 } | |
395 | |
396 void Audio_DeleteDevice(SDL_AudioDevice *device) | |
397 { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
398 SDL_free(device->hidden); |
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
399 SDL_free(device); |
1190 | 400 } |
401 | |
402 SDL_AudioDevice *Audio_CreateDevice(int devindex) | |
403 { | |
404 SDL_AudioDevice *this; | |
405 | |
406 /* Initialize all variables that we clean on shutdown */ | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
407 this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); |
1190 | 408 if ( this ) |
409 { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
410 SDL_memset(this, 0, (sizeof *this)); |
1190 | 411 this->hidden = (struct SDL_PrivateAudioData *) |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
412 SDL_malloc((sizeof *this->hidden)); |
1190 | 413 } |
414 if ( (this == NULL) || (this->hidden == NULL) ) | |
415 { | |
416 SDL_OutOfMemory(); | |
417 if ( this ) | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
418 SDL_free(this); |
1190 | 419 return(0); |
420 } | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
421 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); |
1190 | 422 |
423 /* Set the function pointers */ | |
424 this->OpenAudio = DART_OpenAudio; | |
425 this->ThreadInit = DART_ThreadInit; | |
426 this->WaitAudio = DART_WaitAudio; | |
427 this->PlayAudio = DART_PlayAudio; | |
428 this->GetAudioBuf = DART_GetAudioBuf; | |
429 this->WaitDone = DART_WaitDone; | |
430 this->CloseAudio = DART_CloseAudio; | |
431 | |
432 this->free = Audio_DeleteDevice; | |
433 | |
434 return this; | |
435 } | |
436 | |
437 AudioBootStrap DART_bootstrap = { | |
438 "dart", "OS/2 Direct Audio RouTines (DART)", | |
439 Audio_Available, Audio_CreateDevice | |
440 }; | |
441 |