Mercurial > sdl-ios-xcode
comparison src/audio/windx5/SDL_dx5audio.c @ 1895:c121d94672cb
SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 10 Jul 2006 21:04:37 +0000 |
parents | 9b02a5b97f79 |
children | 4ad1e863d100 |
comparison
equal
deleted
inserted
replaced
1894:c69cee13dd76 | 1895:c121d94672cb |
---|---|
30 | 30 |
31 /* Define this if you want to use DirectX 6 DirectSoundNotify interface */ | 31 /* Define this if you want to use DirectX 6 DirectSoundNotify interface */ |
32 //#define USE_POSITION_NOTIFY | 32 //#define USE_POSITION_NOTIFY |
33 | 33 |
34 /* DirectX function pointers for audio */ | 34 /* DirectX function pointers for audio */ |
35 HRESULT (WINAPI *DSoundCreate)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN); | 35 HRESULT(WINAPI * DSoundCreate) (LPGUID, LPDIRECTSOUND *, LPUNKNOWN); |
36 | 36 |
37 /* Audio driver functions */ | 37 /* Audio driver functions */ |
38 static int DX5_OpenAudio(_THIS, SDL_AudioSpec *spec); | 38 static int DX5_OpenAudio(_THIS, SDL_AudioSpec * spec); |
39 static void DX5_ThreadInit(_THIS); | 39 static void DX5_ThreadInit(_THIS); |
40 static void DX5_WaitAudio_BusyWait(_THIS); | 40 static void DX5_WaitAudio_BusyWait(_THIS); |
41 #ifdef USE_POSITION_NOTIFY | 41 #ifdef USE_POSITION_NOTIFY |
42 static void DX6_WaitAudio_EventWait(_THIS); | 42 static void DX6_WaitAudio_EventWait(_THIS); |
43 #endif | 43 #endif |
46 static void DX5_WaitDone(_THIS); | 46 static void DX5_WaitDone(_THIS); |
47 static void DX5_CloseAudio(_THIS); | 47 static void DX5_CloseAudio(_THIS); |
48 | 48 |
49 /* Audio driver bootstrap functions */ | 49 /* Audio driver bootstrap functions */ |
50 | 50 |
51 static int Audio_Available(void) | 51 static int |
52 { | 52 Audio_Available(void) |
53 HINSTANCE DSoundDLL; | 53 { |
54 int dsound_ok; | 54 HINSTANCE DSoundDLL; |
55 | 55 int dsound_ok; |
56 /* Version check DSOUND.DLL (Is DirectX okay?) */ | 56 |
57 dsound_ok = 0; | 57 /* Version check DSOUND.DLL (Is DirectX okay?) */ |
58 DSoundDLL = LoadLibrary(TEXT("DSOUND.DLL")); | 58 dsound_ok = 0; |
59 if ( DSoundDLL != NULL ) { | 59 DSoundDLL = LoadLibrary(TEXT("DSOUND.DLL")); |
60 /* We just use basic DirectSound, we're okay */ | 60 if (DSoundDLL != NULL) { |
61 /* Yay! */ | 61 /* We just use basic DirectSound, we're okay */ |
62 /* Unfortunately, the sound drivers on NT have | 62 /* Yay! */ |
63 higher latencies than the audio buffers used | 63 /* Unfortunately, the sound drivers on NT have |
64 by many SDL applications, so there are gaps | 64 higher latencies than the audio buffers used |
65 in the audio - it sounds terrible. Punt for now. | 65 by many SDL applications, so there are gaps |
66 */ | 66 in the audio - it sounds terrible. Punt for now. |
67 OSVERSIONINFO ver; | 67 */ |
68 ver.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); | 68 OSVERSIONINFO ver; |
69 GetVersionEx(&ver); | 69 ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); |
70 switch (ver.dwPlatformId) { | 70 GetVersionEx(&ver); |
71 case VER_PLATFORM_WIN32_NT: | 71 switch (ver.dwPlatformId) { |
72 if ( ver.dwMajorVersion > 4 ) { | 72 case VER_PLATFORM_WIN32_NT: |
73 /* Win2K */ | 73 if (ver.dwMajorVersion > 4) { |
74 dsound_ok = 1; | 74 /* Win2K */ |
75 } else { | 75 dsound_ok = 1; |
76 /* WinNT */ | 76 } else { |
77 dsound_ok = 0; | 77 /* WinNT */ |
78 } | 78 dsound_ok = 0; |
79 break; | 79 } |
80 default: | 80 break; |
81 /* Win95 or Win98 */ | 81 default: |
82 dsound_ok = 1; | 82 /* Win95 or Win98 */ |
83 break; | 83 dsound_ok = 1; |
84 } | 84 break; |
85 /* Now check for DirectX 5 or better - otherwise | 85 } |
86 * we will fail later in DX5_OpenAudio without a chance | 86 /* Now check for DirectX 5 or better - otherwise |
87 * to fall back to the DIB driver. */ | 87 * we will fail later in DX5_OpenAudio without a chance |
88 if (dsound_ok) { | 88 * to fall back to the DIB driver. */ |
89 /* DirectSoundCaptureCreate was added in DX5 */ | 89 if (dsound_ok) { |
90 if (!GetProcAddress(DSoundDLL, TEXT("DirectSoundCaptureCreate"))) | 90 /* DirectSoundCaptureCreate was added in DX5 */ |
91 dsound_ok = 0; | 91 if (!GetProcAddress(DSoundDLL, TEXT("DirectSoundCaptureCreate"))) |
92 | 92 dsound_ok = 0; |
93 } | 93 |
94 /* Clean up.. */ | 94 } |
95 FreeLibrary(DSoundDLL); | 95 /* Clean up.. */ |
96 } | 96 FreeLibrary(DSoundDLL); |
97 return(dsound_ok); | 97 } |
98 return (dsound_ok); | |
98 } | 99 } |
99 | 100 |
100 /* Functions for loading the DirectX functions dynamically */ | 101 /* Functions for loading the DirectX functions dynamically */ |
101 static HINSTANCE DSoundDLL = NULL; | 102 static HINSTANCE DSoundDLL = NULL; |
102 | 103 |
103 static void DX5_Unload(void) | 104 static void |
104 { | 105 DX5_Unload(void) |
105 if ( DSoundDLL != NULL ) { | 106 { |
106 FreeLibrary(DSoundDLL); | 107 if (DSoundDLL != NULL) { |
107 DSoundCreate = NULL; | 108 FreeLibrary(DSoundDLL); |
108 DSoundDLL = NULL; | 109 DSoundCreate = NULL; |
109 } | 110 DSoundDLL = NULL; |
110 } | 111 } |
111 static int DX5_Load(void) | 112 } |
112 { | 113 static int |
113 int status; | 114 DX5_Load(void) |
114 | 115 { |
115 DX5_Unload(); | 116 int status; |
116 DSoundDLL = LoadLibrary(TEXT("DSOUND.DLL")); | 117 |
117 if ( DSoundDLL != NULL ) { | 118 DX5_Unload(); |
118 DSoundCreate = (void *)GetProcAddress(DSoundDLL, | 119 DSoundDLL = LoadLibrary(TEXT("DSOUND.DLL")); |
119 TEXT("DirectSoundCreate")); | 120 if (DSoundDLL != NULL) { |
120 } | 121 DSoundCreate = (void *) GetProcAddress(DSoundDLL, |
121 if ( DSoundDLL && DSoundCreate ) { | 122 TEXT("DirectSoundCreate")); |
122 status = 0; | 123 } |
123 } else { | 124 if (DSoundDLL && DSoundCreate) { |
124 DX5_Unload(); | 125 status = 0; |
125 status = -1; | 126 } else { |
126 } | 127 DX5_Unload(); |
127 return status; | 128 status = -1; |
128 } | 129 } |
129 | 130 return status; |
130 static void Audio_DeleteDevice(SDL_AudioDevice *device) | 131 } |
131 { | 132 |
132 DX5_Unload(); | 133 static void |
133 SDL_free(device->hidden); | 134 Audio_DeleteDevice(SDL_AudioDevice * device) |
134 SDL_free(device); | 135 { |
135 } | 136 DX5_Unload(); |
136 | 137 SDL_free(device->hidden); |
137 static SDL_AudioDevice *Audio_CreateDevice(int devindex) | 138 SDL_free(device); |
138 { | 139 } |
139 SDL_AudioDevice *this; | 140 |
140 | 141 static SDL_AudioDevice * |
141 /* Load DirectX */ | 142 Audio_CreateDevice(int devindex) |
142 if ( DX5_Load() < 0 ) { | 143 { |
143 return(NULL); | 144 SDL_AudioDevice *this; |
144 } | 145 |
145 | 146 /* Load DirectX */ |
146 /* Initialize all variables that we clean on shutdown */ | 147 if (DX5_Load() < 0) { |
147 this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | 148 return (NULL); |
148 if ( this ) { | 149 } |
149 SDL_memset(this, 0, (sizeof *this)); | 150 |
150 this->hidden = (struct SDL_PrivateAudioData *) | 151 /* Initialize all variables that we clean on shutdown */ |
151 SDL_malloc((sizeof *this->hidden)); | 152 this = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice)); |
152 } | 153 if (this) { |
153 if ( (this == NULL) || (this->hidden == NULL) ) { | 154 SDL_memset(this, 0, (sizeof *this)); |
154 SDL_OutOfMemory(); | 155 this->hidden = (struct SDL_PrivateAudioData *) |
155 if ( this ) { | 156 SDL_malloc((sizeof *this->hidden)); |
156 SDL_free(this); | 157 } |
157 } | 158 if ((this == NULL) || (this->hidden == NULL)) { |
158 return(0); | 159 SDL_OutOfMemory(); |
159 } | 160 if (this) { |
160 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | 161 SDL_free(this); |
161 | 162 } |
162 /* Set the function pointers */ | 163 return (0); |
163 this->OpenAudio = DX5_OpenAudio; | 164 } |
164 this->ThreadInit = DX5_ThreadInit; | 165 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); |
165 this->WaitAudio = DX5_WaitAudio_BusyWait; | 166 |
166 this->PlayAudio = DX5_PlayAudio; | 167 /* Set the function pointers */ |
167 this->GetAudioBuf = DX5_GetAudioBuf; | 168 this->OpenAudio = DX5_OpenAudio; |
168 this->WaitDone = DX5_WaitDone; | 169 this->ThreadInit = DX5_ThreadInit; |
169 this->CloseAudio = DX5_CloseAudio; | 170 this->WaitAudio = DX5_WaitAudio_BusyWait; |
170 | 171 this->PlayAudio = DX5_PlayAudio; |
171 this->free = Audio_DeleteDevice; | 172 this->GetAudioBuf = DX5_GetAudioBuf; |
172 | 173 this->WaitDone = DX5_WaitDone; |
173 return this; | 174 this->CloseAudio = DX5_CloseAudio; |
175 | |
176 this->free = Audio_DeleteDevice; | |
177 | |
178 return this; | |
174 } | 179 } |
175 | 180 |
176 AudioBootStrap DSOUND_bootstrap = { | 181 AudioBootStrap DSOUND_bootstrap = { |
177 "dsound", "Win95/98/2000 DirectSound", | 182 "dsound", "Win95/98/2000 DirectSound", |
178 Audio_Available, Audio_CreateDevice | 183 Audio_Available, Audio_CreateDevice |
179 }; | 184 }; |
180 | 185 |
181 static void SetDSerror(const char *function, int code) | 186 static void |
182 { | 187 SetDSerror(const char *function, int code) |
183 static const char *error; | 188 { |
184 static char errbuf[1024]; | 189 static const char *error; |
185 | 190 static char errbuf[1024]; |
186 errbuf[0] = 0; | 191 |
187 switch (code) { | 192 errbuf[0] = 0; |
188 case E_NOINTERFACE: | 193 switch (code) { |
189 error = | 194 case E_NOINTERFACE: |
190 "Unsupported interface\n-- Is DirectX 5.0 or later installed?"; | 195 error = |
191 break; | 196 "Unsupported interface\n-- Is DirectX 5.0 or later installed?"; |
192 case DSERR_ALLOCATED: | 197 break; |
193 error = "Audio device in use"; | 198 case DSERR_ALLOCATED: |
194 break; | 199 error = "Audio device in use"; |
195 case DSERR_BADFORMAT: | 200 break; |
196 error = "Unsupported audio format"; | 201 case DSERR_BADFORMAT: |
197 break; | 202 error = "Unsupported audio format"; |
198 case DSERR_BUFFERLOST: | 203 break; |
199 error = "Mixing buffer was lost"; | 204 case DSERR_BUFFERLOST: |
200 break; | 205 error = "Mixing buffer was lost"; |
201 case DSERR_CONTROLUNAVAIL: | 206 break; |
202 error = "Control requested is not available"; | 207 case DSERR_CONTROLUNAVAIL: |
203 break; | 208 error = "Control requested is not available"; |
204 case DSERR_INVALIDCALL: | 209 break; |
205 error = "Invalid call for the current state"; | 210 case DSERR_INVALIDCALL: |
206 break; | 211 error = "Invalid call for the current state"; |
207 case DSERR_INVALIDPARAM: | 212 break; |
208 error = "Invalid parameter"; | 213 case DSERR_INVALIDPARAM: |
209 break; | 214 error = "Invalid parameter"; |
210 case DSERR_NODRIVER: | 215 break; |
211 error = "No audio device found"; | 216 case DSERR_NODRIVER: |
212 break; | 217 error = "No audio device found"; |
213 case DSERR_OUTOFMEMORY: | 218 break; |
214 error = "Out of memory"; | 219 case DSERR_OUTOFMEMORY: |
215 break; | 220 error = "Out of memory"; |
216 case DSERR_PRIOLEVELNEEDED: | 221 break; |
217 error = "Caller doesn't have priority"; | 222 case DSERR_PRIOLEVELNEEDED: |
218 break; | 223 error = "Caller doesn't have priority"; |
219 case DSERR_UNSUPPORTED: | 224 break; |
220 error = "Function not supported"; | 225 case DSERR_UNSUPPORTED: |
221 break; | 226 error = "Function not supported"; |
222 default: | 227 break; |
223 SDL_snprintf(errbuf, SDL_arraysize(errbuf), | 228 default: |
224 "%s: Unknown DirectSound error: 0x%x", | 229 SDL_snprintf(errbuf, SDL_arraysize(errbuf), |
225 function, code); | 230 "%s: Unknown DirectSound error: 0x%x", function, code); |
226 break; | 231 break; |
227 } | 232 } |
228 if ( ! errbuf[0] ) { | 233 if (!errbuf[0]) { |
229 SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: %s", function, error); | 234 SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: %s", function, |
230 } | 235 error); |
231 SDL_SetError("%s", errbuf); | 236 } |
232 return; | 237 SDL_SetError("%s", errbuf); |
238 return; | |
233 } | 239 } |
234 | 240 |
235 /* DirectSound needs to be associated with a window */ | 241 /* DirectSound needs to be associated with a window */ |
236 static HWND mainwin = NULL; | 242 static HWND mainwin = NULL; |
237 /* */ | 243 /* */ |
238 void DX5_SoundFocus(HWND hwnd) | 244 void |
239 { | 245 DX5_SoundFocus(HWND hwnd) |
240 mainwin = hwnd; | 246 { |
241 } | 247 mainwin = hwnd; |
242 | 248 } |
243 static void DX5_ThreadInit(_THIS) | 249 |
244 { | 250 static void |
245 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); | 251 DX5_ThreadInit(_THIS) |
246 } | 252 { |
247 | 253 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); |
248 static void DX5_WaitAudio_BusyWait(_THIS) | 254 } |
249 { | 255 |
250 DWORD status; | 256 static void |
251 DWORD cursor, junk; | 257 DX5_WaitAudio_BusyWait(_THIS) |
252 HRESULT result; | 258 { |
253 | 259 DWORD status; |
254 /* Semi-busy wait, since we have no way of getting play notification | 260 DWORD cursor, junk; |
255 on a primary mixing buffer located in hardware (DirectX 5.0) | 261 HRESULT result; |
256 */ | 262 |
257 result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, &junk, &cursor); | 263 /* Semi-busy wait, since we have no way of getting play notification |
258 if ( result != DS_OK ) { | 264 on a primary mixing buffer located in hardware (DirectX 5.0) |
259 if ( result == DSERR_BUFFERLOST ) { | 265 */ |
260 IDirectSoundBuffer_Restore(mixbuf); | 266 result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, &junk, &cursor); |
261 } | 267 if (result != DS_OK) { |
262 #ifdef DEBUG_SOUND | 268 if (result == DSERR_BUFFERLOST) { |
263 SetDSerror("DirectSound GetCurrentPosition", result); | 269 IDirectSoundBuffer_Restore(mixbuf); |
264 #endif | 270 } |
265 return; | 271 #ifdef DEBUG_SOUND |
266 } | 272 SetDSerror("DirectSound GetCurrentPosition", result); |
267 | 273 #endif |
268 while ( (cursor/mixlen) == lastchunk ) { | 274 return; |
269 /* FIXME: find out how much time is left and sleep that long */ | 275 } |
270 SDL_Delay(1); | 276 |
271 | 277 while ((cursor / mixlen) == lastchunk) { |
272 /* Try to restore a lost sound buffer */ | 278 /* FIXME: find out how much time is left and sleep that long */ |
273 IDirectSoundBuffer_GetStatus(mixbuf, &status); | 279 SDL_Delay(1); |
274 if ( (status&DSBSTATUS_BUFFERLOST) ) { | 280 |
275 IDirectSoundBuffer_Restore(mixbuf); | 281 /* Try to restore a lost sound buffer */ |
276 IDirectSoundBuffer_GetStatus(mixbuf, &status); | 282 IDirectSoundBuffer_GetStatus(mixbuf, &status); |
277 if ( (status&DSBSTATUS_BUFFERLOST) ) { | 283 if ((status & DSBSTATUS_BUFFERLOST)) { |
278 break; | 284 IDirectSoundBuffer_Restore(mixbuf); |
279 } | 285 IDirectSoundBuffer_GetStatus(mixbuf, &status); |
280 } | 286 if ((status & DSBSTATUS_BUFFERLOST)) { |
281 if ( ! (status&DSBSTATUS_PLAYING) ) { | 287 break; |
282 result = IDirectSoundBuffer_Play(mixbuf, 0, 0, DSBPLAY_LOOPING); | 288 } |
283 if ( result == DS_OK ) { | 289 } |
284 continue; | 290 if (!(status & DSBSTATUS_PLAYING)) { |
285 } | 291 result = IDirectSoundBuffer_Play(mixbuf, 0, 0, DSBPLAY_LOOPING); |
286 #ifdef DEBUG_SOUND | 292 if (result == DS_OK) { |
287 SetDSerror("DirectSound Play", result); | 293 continue; |
288 #endif | 294 } |
289 return; | 295 #ifdef DEBUG_SOUND |
290 } | 296 SetDSerror("DirectSound Play", result); |
291 | 297 #endif |
292 /* Find out where we are playing */ | 298 return; |
293 result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, | 299 } |
294 &junk, &cursor); | 300 |
295 if ( result != DS_OK ) { | 301 /* Find out where we are playing */ |
296 SetDSerror("DirectSound GetCurrentPosition", result); | 302 result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, |
297 return; | 303 &junk, &cursor); |
298 } | 304 if (result != DS_OK) { |
299 } | 305 SetDSerror("DirectSound GetCurrentPosition", result); |
306 return; | |
307 } | |
308 } | |
300 } | 309 } |
301 | 310 |
302 #ifdef USE_POSITION_NOTIFY | 311 #ifdef USE_POSITION_NOTIFY |
303 static void DX6_WaitAudio_EventWait(_THIS) | 312 static void |
304 { | 313 DX6_WaitAudio_EventWait(_THIS) |
305 DWORD status; | 314 { |
306 HRESULT result; | 315 DWORD status; |
307 | 316 HRESULT result; |
308 /* Try to restore a lost sound buffer */ | 317 |
309 IDirectSoundBuffer_GetStatus(mixbuf, &status); | 318 /* Try to restore a lost sound buffer */ |
310 if ( (status&DSBSTATUS_BUFFERLOST) ) { | 319 IDirectSoundBuffer_GetStatus(mixbuf, &status); |
311 IDirectSoundBuffer_Restore(mixbuf); | 320 if ((status & DSBSTATUS_BUFFERLOST)) { |
312 IDirectSoundBuffer_GetStatus(mixbuf, &status); | 321 IDirectSoundBuffer_Restore(mixbuf); |
313 if ( (status&DSBSTATUS_BUFFERLOST) ) { | 322 IDirectSoundBuffer_GetStatus(mixbuf, &status); |
314 return; | 323 if ((status & DSBSTATUS_BUFFERLOST)) { |
315 } | 324 return; |
316 } | 325 } |
317 if ( ! (status&DSBSTATUS_PLAYING) ) { | 326 } |
318 result = IDirectSoundBuffer_Play(mixbuf, 0, 0, DSBPLAY_LOOPING); | 327 if (!(status & DSBSTATUS_PLAYING)) { |
319 if ( result != DS_OK ) { | 328 result = IDirectSoundBuffer_Play(mixbuf, 0, 0, DSBPLAY_LOOPING); |
320 #ifdef DEBUG_SOUND | 329 if (result != DS_OK) { |
321 SetDSerror("DirectSound Play", result); | 330 #ifdef DEBUG_SOUND |
322 #endif | 331 SetDSerror("DirectSound Play", result); |
323 return; | 332 #endif |
324 } | 333 return; |
325 } | 334 } |
326 WaitForSingleObject(audio_event, INFINITE); | 335 } |
336 WaitForSingleObject(audio_event, INFINITE); | |
327 } | 337 } |
328 #endif /* USE_POSITION_NOTIFY */ | 338 #endif /* USE_POSITION_NOTIFY */ |
329 | 339 |
330 static void DX5_PlayAudio(_THIS) | 340 static void |
331 { | 341 DX5_PlayAudio(_THIS) |
332 /* Unlock the buffer, allowing it to play */ | 342 { |
333 if ( locked_buf ) { | 343 /* Unlock the buffer, allowing it to play */ |
334 IDirectSoundBuffer_Unlock(mixbuf, locked_buf, mixlen, NULL, 0); | 344 if (locked_buf) { |
335 } | 345 IDirectSoundBuffer_Unlock(mixbuf, locked_buf, mixlen, NULL, 0); |
336 | 346 } |
337 } | 347 |
338 | 348 } |
339 static Uint8 *DX5_GetAudioBuf(_THIS) | 349 |
340 { | 350 static Uint8 * |
341 DWORD cursor, junk; | 351 DX5_GetAudioBuf(_THIS) |
342 HRESULT result; | 352 { |
343 DWORD rawlen; | 353 DWORD cursor, junk; |
344 | 354 HRESULT result; |
345 /* Figure out which blocks to fill next */ | 355 DWORD rawlen; |
346 locked_buf = NULL; | 356 |
347 result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, &junk, &cursor); | 357 /* Figure out which blocks to fill next */ |
348 if ( result == DSERR_BUFFERLOST ) { | 358 locked_buf = NULL; |
349 IDirectSoundBuffer_Restore(mixbuf); | 359 result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, &junk, &cursor); |
350 result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, | 360 if (result == DSERR_BUFFERLOST) { |
351 &junk, &cursor); | 361 IDirectSoundBuffer_Restore(mixbuf); |
352 } | 362 result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, |
353 if ( result != DS_OK ) { | 363 &junk, &cursor); |
354 SetDSerror("DirectSound GetCurrentPosition", result); | 364 } |
355 return(NULL); | 365 if (result != DS_OK) { |
356 } | 366 SetDSerror("DirectSound GetCurrentPosition", result); |
357 cursor /= mixlen; | 367 return (NULL); |
358 #ifdef DEBUG_SOUND | 368 } |
359 /* Detect audio dropouts */ | 369 cursor /= mixlen; |
360 { DWORD spot = cursor; | 370 #ifdef DEBUG_SOUND |
361 if ( spot < lastchunk ) { | 371 /* Detect audio dropouts */ |
362 spot += NUM_BUFFERS; | 372 { |
363 } | 373 DWORD spot = cursor; |
364 if ( spot > lastchunk+1 ) { | 374 if (spot < lastchunk) { |
365 fprintf(stderr, "Audio dropout, missed %d fragments\n", | 375 spot += NUM_BUFFERS; |
366 (spot - (lastchunk+1))); | 376 } |
367 } | 377 if (spot > lastchunk + 1) { |
368 } | 378 fprintf(stderr, "Audio dropout, missed %d fragments\n", |
369 #endif | 379 (spot - (lastchunk + 1))); |
370 lastchunk = cursor; | 380 } |
371 cursor = (cursor+1)%NUM_BUFFERS; | 381 } |
372 cursor *= mixlen; | 382 #endif |
373 | 383 lastchunk = cursor; |
374 /* Lock the audio buffer */ | 384 cursor = (cursor + 1) % NUM_BUFFERS; |
375 result = IDirectSoundBuffer_Lock(mixbuf, cursor, mixlen, | 385 cursor *= mixlen; |
376 (LPVOID *)&locked_buf, &rawlen, NULL, &junk, 0); | 386 |
377 if ( result == DSERR_BUFFERLOST ) { | 387 /* Lock the audio buffer */ |
378 IDirectSoundBuffer_Restore(mixbuf); | 388 result = IDirectSoundBuffer_Lock(mixbuf, cursor, mixlen, |
379 result = IDirectSoundBuffer_Lock(mixbuf, cursor, mixlen, | 389 (LPVOID *) & locked_buf, &rawlen, NULL, |
380 (LPVOID *)&locked_buf, &rawlen, NULL, &junk, 0); | 390 &junk, 0); |
381 } | 391 if (result == DSERR_BUFFERLOST) { |
382 if ( result != DS_OK ) { | 392 IDirectSoundBuffer_Restore(mixbuf); |
383 SetDSerror("DirectSound Lock", result); | 393 result = IDirectSoundBuffer_Lock(mixbuf, cursor, mixlen, |
384 return(NULL); | 394 (LPVOID *) & locked_buf, &rawlen, |
385 } | 395 NULL, &junk, 0); |
386 return(locked_buf); | 396 } |
387 } | 397 if (result != DS_OK) { |
388 | 398 SetDSerror("DirectSound Lock", result); |
389 static void DX5_WaitDone(_THIS) | 399 return (NULL); |
390 { | 400 } |
391 Uint8 *stream; | 401 return (locked_buf); |
392 | 402 } |
393 /* Wait for the playing chunk to finish */ | 403 |
394 stream = this->GetAudioBuf(this); | 404 static void |
395 if ( stream != NULL ) { | 405 DX5_WaitDone(_THIS) |
396 SDL_memset(stream, silence, mixlen); | 406 { |
397 this->PlayAudio(this); | 407 Uint8 *stream; |
398 } | 408 |
399 this->WaitAudio(this); | 409 /* Wait for the playing chunk to finish */ |
400 | 410 stream = this->GetAudioBuf(this); |
401 /* Stop the looping sound buffer */ | 411 if (stream != NULL) { |
402 IDirectSoundBuffer_Stop(mixbuf); | 412 SDL_memset(stream, silence, mixlen); |
403 } | 413 this->PlayAudio(this); |
404 | 414 } |
405 static void DX5_CloseAudio(_THIS) | 415 this->WaitAudio(this); |
406 { | 416 |
407 if ( sound != NULL ) { | 417 /* Stop the looping sound buffer */ |
408 if ( mixbuf != NULL ) { | 418 IDirectSoundBuffer_Stop(mixbuf); |
409 /* Clean up the audio buffer */ | 419 } |
410 IDirectSoundBuffer_Release(mixbuf); | 420 |
411 mixbuf = NULL; | 421 static void |
412 } | 422 DX5_CloseAudio(_THIS) |
413 if ( audio_event != NULL ) { | 423 { |
414 CloseHandle(audio_event); | 424 if (sound != NULL) { |
415 audio_event = NULL; | 425 if (mixbuf != NULL) { |
416 } | 426 /* Clean up the audio buffer */ |
417 IDirectSound_Release(sound); | 427 IDirectSoundBuffer_Release(mixbuf); |
418 sound = NULL; | 428 mixbuf = NULL; |
419 } | 429 } |
430 if (audio_event != NULL) { | |
431 CloseHandle(audio_event); | |
432 audio_event = NULL; | |
433 } | |
434 IDirectSound_Release(sound); | |
435 sound = NULL; | |
436 } | |
420 } | 437 } |
421 | 438 |
422 #ifdef USE_PRIMARY_BUFFER | 439 #ifdef USE_PRIMARY_BUFFER |
423 /* This function tries to create a primary audio buffer, and returns the | 440 /* This function tries to create a primary audio buffer, and returns the |
424 number of audio chunks available in the created buffer. | 441 number of audio chunks available in the created buffer. |
425 */ | 442 */ |
426 static int CreatePrimary(LPDIRECTSOUND sndObj, HWND focus, | 443 static int |
427 LPDIRECTSOUNDBUFFER *sndbuf, WAVEFORMATEX *wavefmt, Uint32 chunksize) | 444 CreatePrimary(LPDIRECTSOUND sndObj, HWND focus, |
428 { | 445 LPDIRECTSOUNDBUFFER * sndbuf, WAVEFORMATEX * wavefmt, |
429 HRESULT result; | 446 Uint32 chunksize) |
430 DSBUFFERDESC format; | 447 { |
431 DSBCAPS caps; | 448 HRESULT result; |
432 int numchunks; | 449 DSBUFFERDESC format; |
433 | 450 DSBCAPS caps; |
434 /* Try to set primary mixing privileges */ | 451 int numchunks; |
435 result = IDirectSound_SetCooperativeLevel(sndObj, focus, | 452 |
436 DSSCL_WRITEPRIMARY); | 453 /* Try to set primary mixing privileges */ |
437 if ( result != DS_OK ) { | 454 result = IDirectSound_SetCooperativeLevel(sndObj, focus, |
438 #ifdef DEBUG_SOUND | 455 DSSCL_WRITEPRIMARY); |
439 SetDSerror("DirectSound SetCooperativeLevel", result); | 456 if (result != DS_OK) { |
440 #endif | 457 #ifdef DEBUG_SOUND |
441 return(-1); | 458 SetDSerror("DirectSound SetCooperativeLevel", result); |
442 } | 459 #endif |
443 | 460 return (-1); |
444 /* Try to create the primary buffer */ | 461 } |
445 SDL_memset(&format, 0, sizeof(format)); | 462 |
446 format.dwSize = sizeof(format); | 463 /* Try to create the primary buffer */ |
447 format.dwFlags=(DSBCAPS_PRIMARYBUFFER|DSBCAPS_GETCURRENTPOSITION2); | 464 SDL_memset(&format, 0, sizeof(format)); |
448 format.dwFlags |= DSBCAPS_STICKYFOCUS; | 465 format.dwSize = sizeof(format); |
466 format.dwFlags = (DSBCAPS_PRIMARYBUFFER | DSBCAPS_GETCURRENTPOSITION2); | |
467 format.dwFlags |= DSBCAPS_STICKYFOCUS; | |
449 #ifdef USE_POSITION_NOTIFY | 468 #ifdef USE_POSITION_NOTIFY |
450 format.dwFlags |= DSBCAPS_CTRLPOSITIONNOTIFY; | 469 format.dwFlags |= DSBCAPS_CTRLPOSITIONNOTIFY; |
451 #endif | 470 #endif |
452 result = IDirectSound_CreateSoundBuffer(sndObj, &format, sndbuf, NULL); | 471 result = IDirectSound_CreateSoundBuffer(sndObj, &format, sndbuf, NULL); |
453 if ( result != DS_OK ) { | 472 if (result != DS_OK) { |
454 #ifdef DEBUG_SOUND | 473 #ifdef DEBUG_SOUND |
455 SetDSerror("DirectSound CreateSoundBuffer", result); | 474 SetDSerror("DirectSound CreateSoundBuffer", result); |
456 #endif | 475 #endif |
457 return(-1); | 476 return (-1); |
458 } | 477 } |
459 | 478 |
460 /* Check the size of the fragment buffer */ | 479 /* Check the size of the fragment buffer */ |
461 SDL_memset(&caps, 0, sizeof(caps)); | 480 SDL_memset(&caps, 0, sizeof(caps)); |
462 caps.dwSize = sizeof(caps); | 481 caps.dwSize = sizeof(caps); |
463 result = IDirectSoundBuffer_GetCaps(*sndbuf, &caps); | 482 result = IDirectSoundBuffer_GetCaps(*sndbuf, &caps); |
464 if ( result != DS_OK ) { | 483 if (result != DS_OK) { |
465 #ifdef DEBUG_SOUND | 484 #ifdef DEBUG_SOUND |
466 SetDSerror("DirectSound GetCaps", result); | 485 SetDSerror("DirectSound GetCaps", result); |
467 #endif | 486 #endif |
468 IDirectSoundBuffer_Release(*sndbuf); | 487 IDirectSoundBuffer_Release(*sndbuf); |
469 return(-1); | 488 return (-1); |
470 } | 489 } |
471 if ( (chunksize > caps.dwBufferBytes) || | 490 if ((chunksize > caps.dwBufferBytes) || |
472 ((caps.dwBufferBytes%chunksize) != 0) ) { | 491 ((caps.dwBufferBytes % chunksize) != 0)) { |
473 /* The primary buffer size is not a multiple of 'chunksize' | 492 /* The primary buffer size is not a multiple of 'chunksize' |
474 -- this hopefully doesn't happen when 'chunksize' is a | 493 -- this hopefully doesn't happen when 'chunksize' is a |
475 power of 2. | 494 power of 2. |
476 */ | 495 */ |
477 IDirectSoundBuffer_Release(*sndbuf); | 496 IDirectSoundBuffer_Release(*sndbuf); |
478 SDL_SetError( | 497 SDL_SetError |
479 "Primary buffer size is: %d, cannot break it into chunks of %d bytes\n", | 498 ("Primary buffer size is: %d, cannot break it into chunks of %d bytes\n", |
480 caps.dwBufferBytes, chunksize); | 499 caps.dwBufferBytes, chunksize); |
481 return(-1); | 500 return (-1); |
482 } | 501 } |
483 numchunks = (caps.dwBufferBytes/chunksize); | 502 numchunks = (caps.dwBufferBytes / chunksize); |
484 | 503 |
485 /* Set the primary audio format */ | 504 /* Set the primary audio format */ |
486 result = IDirectSoundBuffer_SetFormat(*sndbuf, wavefmt); | 505 result = IDirectSoundBuffer_SetFormat(*sndbuf, wavefmt); |
487 if ( result != DS_OK ) { | 506 if (result != DS_OK) { |
488 #ifdef DEBUG_SOUND | 507 #ifdef DEBUG_SOUND |
489 SetDSerror("DirectSound SetFormat", result); | 508 SetDSerror("DirectSound SetFormat", result); |
490 #endif | 509 #endif |
491 IDirectSoundBuffer_Release(*sndbuf); | 510 IDirectSoundBuffer_Release(*sndbuf); |
492 return(-1); | 511 return (-1); |
493 } | 512 } |
494 return(numchunks); | 513 return (numchunks); |
495 } | 514 } |
496 #endif /* USE_PRIMARY_BUFFER */ | 515 #endif /* USE_PRIMARY_BUFFER */ |
497 | 516 |
498 /* This function tries to create a secondary audio buffer, and returns the | 517 /* This function tries to create a secondary audio buffer, and returns the |
499 number of audio chunks available in the created buffer. | 518 number of audio chunks available in the created buffer. |
500 */ | 519 */ |
501 static int CreateSecondary(LPDIRECTSOUND sndObj, HWND focus, | 520 static int |
502 LPDIRECTSOUNDBUFFER *sndbuf, WAVEFORMATEX *wavefmt, Uint32 chunksize) | 521 CreateSecondary(LPDIRECTSOUND sndObj, HWND focus, |
503 { | 522 LPDIRECTSOUNDBUFFER * sndbuf, WAVEFORMATEX * wavefmt, |
504 const int numchunks = 8; | 523 Uint32 chunksize) |
505 HRESULT result; | 524 { |
506 DSBUFFERDESC format; | 525 const int numchunks = 8; |
507 LPVOID pvAudioPtr1, pvAudioPtr2; | 526 HRESULT result; |
508 DWORD dwAudioBytes1, dwAudioBytes2; | 527 DSBUFFERDESC format; |
509 | 528 LPVOID pvAudioPtr1, pvAudioPtr2; |
510 /* Try to set primary mixing privileges */ | 529 DWORD dwAudioBytes1, dwAudioBytes2; |
511 if ( focus ) { | 530 |
512 result = IDirectSound_SetCooperativeLevel(sndObj, | 531 /* Try to set primary mixing privileges */ |
513 focus, DSSCL_PRIORITY); | 532 if (focus) { |
514 } else { | 533 result = IDirectSound_SetCooperativeLevel(sndObj, |
515 result = IDirectSound_SetCooperativeLevel(sndObj, | 534 focus, DSSCL_PRIORITY); |
516 GetDesktopWindow(), DSSCL_NORMAL); | 535 } else { |
517 } | 536 result = IDirectSound_SetCooperativeLevel(sndObj, |
518 if ( result != DS_OK ) { | 537 GetDesktopWindow(), |
519 #ifdef DEBUG_SOUND | 538 DSSCL_NORMAL); |
520 SetDSerror("DirectSound SetCooperativeLevel", result); | 539 } |
521 #endif | 540 if (result != DS_OK) { |
522 return(-1); | 541 #ifdef DEBUG_SOUND |
523 } | 542 SetDSerror("DirectSound SetCooperativeLevel", result); |
524 | 543 #endif |
525 /* Try to create the secondary buffer */ | 544 return (-1); |
526 SDL_memset(&format, 0, sizeof(format)); | 545 } |
527 format.dwSize = sizeof(format); | 546 |
528 format.dwFlags = DSBCAPS_GETCURRENTPOSITION2; | 547 /* Try to create the secondary buffer */ |
548 SDL_memset(&format, 0, sizeof(format)); | |
549 format.dwSize = sizeof(format); | |
550 format.dwFlags = DSBCAPS_GETCURRENTPOSITION2; | |
529 #ifdef USE_POSITION_NOTIFY | 551 #ifdef USE_POSITION_NOTIFY |
530 format.dwFlags |= DSBCAPS_CTRLPOSITIONNOTIFY; | 552 format.dwFlags |= DSBCAPS_CTRLPOSITIONNOTIFY; |
531 #endif | 553 #endif |
532 if ( ! focus ) { | 554 if (!focus) { |
533 format.dwFlags |= DSBCAPS_GLOBALFOCUS; | 555 format.dwFlags |= DSBCAPS_GLOBALFOCUS; |
534 } else { | 556 } else { |
535 format.dwFlags |= DSBCAPS_STICKYFOCUS; | 557 format.dwFlags |= DSBCAPS_STICKYFOCUS; |
536 } | 558 } |
537 format.dwBufferBytes = numchunks*chunksize; | 559 format.dwBufferBytes = numchunks * chunksize; |
538 if ( (format.dwBufferBytes < DSBSIZE_MIN) || | 560 if ((format.dwBufferBytes < DSBSIZE_MIN) || |
539 (format.dwBufferBytes > DSBSIZE_MAX) ) { | 561 (format.dwBufferBytes > DSBSIZE_MAX)) { |
540 SDL_SetError("Sound buffer size must be between %d and %d", | 562 SDL_SetError("Sound buffer size must be between %d and %d", |
541 DSBSIZE_MIN/numchunks, DSBSIZE_MAX/numchunks); | 563 DSBSIZE_MIN / numchunks, DSBSIZE_MAX / numchunks); |
542 return(-1); | 564 return (-1); |
543 } | 565 } |
544 format.dwReserved = 0; | 566 format.dwReserved = 0; |
545 format.lpwfxFormat = wavefmt; | 567 format.lpwfxFormat = wavefmt; |
546 result = IDirectSound_CreateSoundBuffer(sndObj, &format, sndbuf, NULL); | 568 result = IDirectSound_CreateSoundBuffer(sndObj, &format, sndbuf, NULL); |
547 if ( result != DS_OK ) { | 569 if (result != DS_OK) { |
548 SetDSerror("DirectSound CreateSoundBuffer", result); | 570 SetDSerror("DirectSound CreateSoundBuffer", result); |
549 return(-1); | 571 return (-1); |
550 } | 572 } |
551 IDirectSoundBuffer_SetFormat(*sndbuf, wavefmt); | 573 IDirectSoundBuffer_SetFormat(*sndbuf, wavefmt); |
552 | 574 |
553 /* Silence the initial audio buffer */ | 575 /* Silence the initial audio buffer */ |
554 result = IDirectSoundBuffer_Lock(*sndbuf, 0, format.dwBufferBytes, | 576 result = IDirectSoundBuffer_Lock(*sndbuf, 0, format.dwBufferBytes, |
555 (LPVOID *)&pvAudioPtr1, &dwAudioBytes1, | 577 (LPVOID *) & pvAudioPtr1, &dwAudioBytes1, |
556 (LPVOID *)&pvAudioPtr2, &dwAudioBytes2, | 578 (LPVOID *) & pvAudioPtr2, &dwAudioBytes2, |
557 DSBLOCK_ENTIREBUFFER); | 579 DSBLOCK_ENTIREBUFFER); |
558 if ( result == DS_OK ) { | 580 if (result == DS_OK) { |
559 if ( wavefmt->wBitsPerSample == 8 ) { | 581 if (wavefmt->wBitsPerSample == 8) { |
560 SDL_memset(pvAudioPtr1, 0x80, dwAudioBytes1); | 582 SDL_memset(pvAudioPtr1, 0x80, dwAudioBytes1); |
561 } else { | 583 } else { |
562 SDL_memset(pvAudioPtr1, 0x00, dwAudioBytes1); | 584 SDL_memset(pvAudioPtr1, 0x00, dwAudioBytes1); |
563 } | 585 } |
564 IDirectSoundBuffer_Unlock(*sndbuf, | 586 IDirectSoundBuffer_Unlock(*sndbuf, |
565 (LPVOID)pvAudioPtr1, dwAudioBytes1, | 587 (LPVOID) pvAudioPtr1, dwAudioBytes1, |
566 (LPVOID)pvAudioPtr2, dwAudioBytes2); | 588 (LPVOID) pvAudioPtr2, dwAudioBytes2); |
567 } | 589 } |
568 | 590 |
569 /* We're ready to go */ | 591 /* We're ready to go */ |
570 return(numchunks); | 592 return (numchunks); |
571 } | 593 } |
572 | 594 |
573 /* This function tries to set position notify events on the mixing buffer */ | 595 /* This function tries to set position notify events on the mixing buffer */ |
574 #ifdef USE_POSITION_NOTIFY | 596 #ifdef USE_POSITION_NOTIFY |
575 static int CreateAudioEvent(_THIS) | 597 static int |
576 { | 598 CreateAudioEvent(_THIS) |
577 LPDIRECTSOUNDNOTIFY notify; | 599 { |
578 DSBPOSITIONNOTIFY *notify_positions; | 600 LPDIRECTSOUNDNOTIFY notify; |
579 int i, retval; | 601 DSBPOSITIONNOTIFY *notify_positions; |
580 HRESULT result; | 602 int i, retval; |
581 | 603 HRESULT result; |
582 /* Default to fail on exit */ | 604 |
583 retval = -1; | 605 /* Default to fail on exit */ |
584 notify = NULL; | 606 retval = -1; |
585 | 607 notify = NULL; |
586 /* Query for the interface */ | 608 |
587 result = IDirectSoundBuffer_QueryInterface(mixbuf, | 609 /* Query for the interface */ |
588 &IID_IDirectSoundNotify, (void *)¬ify); | 610 result = IDirectSoundBuffer_QueryInterface(mixbuf, |
589 if ( result != DS_OK ) { | 611 &IID_IDirectSoundNotify, |
590 goto done; | 612 (void *) ¬ify); |
591 } | 613 if (result != DS_OK) { |
592 | 614 goto done; |
593 /* Allocate the notify structures */ | 615 } |
594 notify_positions = (DSBPOSITIONNOTIFY *)SDL_malloc(NUM_BUFFERS* | 616 |
595 sizeof(*notify_positions)); | 617 /* Allocate the notify structures */ |
596 if ( notify_positions == NULL ) { | 618 notify_positions = (DSBPOSITIONNOTIFY *) SDL_malloc(NUM_BUFFERS * |
597 goto done; | 619 sizeof |
598 } | 620 (*notify_positions)); |
599 | 621 if (notify_positions == NULL) { |
600 /* Create the notify event */ | 622 goto done; |
601 audio_event = CreateEvent(NULL, FALSE, FALSE, NULL); | 623 } |
602 if ( audio_event == NULL ) { | 624 |
603 goto done; | 625 /* Create the notify event */ |
604 } | 626 audio_event = CreateEvent(NULL, FALSE, FALSE, NULL); |
605 | 627 if (audio_event == NULL) { |
606 /* Set up the notify structures */ | 628 goto done; |
607 for ( i=0; i<NUM_BUFFERS; ++i ) { | 629 } |
608 notify_positions[i].dwOffset = i*mixlen; | 630 |
609 notify_positions[i].hEventNotify = audio_event; | 631 /* Set up the notify structures */ |
610 } | 632 for (i = 0; i < NUM_BUFFERS; ++i) { |
611 result = IDirectSoundNotify_SetNotificationPositions(notify, | 633 notify_positions[i].dwOffset = i * mixlen; |
612 NUM_BUFFERS, notify_positions); | 634 notify_positions[i].hEventNotify = audio_event; |
613 if ( result == DS_OK ) { | 635 } |
614 retval = 0; | 636 result = IDirectSoundNotify_SetNotificationPositions(notify, |
615 } | 637 NUM_BUFFERS, |
616 done: | 638 notify_positions); |
617 if ( notify != NULL ) { | 639 if (result == DS_OK) { |
618 IDirectSoundNotify_Release(notify); | 640 retval = 0; |
619 } | 641 } |
620 return(retval); | 642 done: |
643 if (notify != NULL) { | |
644 IDirectSoundNotify_Release(notify); | |
645 } | |
646 return (retval); | |
621 } | 647 } |
622 #endif /* USE_POSITION_NOTIFY */ | 648 #endif /* USE_POSITION_NOTIFY */ |
623 | 649 |
624 static int DX5_OpenAudio(_THIS, SDL_AudioSpec *spec) | 650 static int |
625 { | 651 DX5_OpenAudio(_THIS, SDL_AudioSpec * spec) |
626 HRESULT result; | 652 { |
627 WAVEFORMATEX waveformat; | 653 HRESULT result; |
628 | 654 WAVEFORMATEX waveformat; |
629 /* Set basic WAVE format parameters */ | 655 |
630 SDL_memset(&waveformat, 0, sizeof(waveformat)); | 656 /* Set basic WAVE format parameters */ |
631 waveformat.wFormatTag = WAVE_FORMAT_PCM; | 657 SDL_memset(&waveformat, 0, sizeof(waveformat)); |
632 | 658 waveformat.wFormatTag = WAVE_FORMAT_PCM; |
633 /* Determine the audio parameters from the AudioSpec */ | 659 |
634 switch ( spec->format & 0xFF ) { | 660 /* Determine the audio parameters from the AudioSpec */ |
635 case 8: | 661 switch (spec->format & 0xFF) { |
636 /* Unsigned 8 bit audio data */ | 662 case 8: |
637 spec->format = AUDIO_U8; | 663 /* Unsigned 8 bit audio data */ |
638 silence = 0x80; | 664 spec->format = AUDIO_U8; |
639 waveformat.wBitsPerSample = 8; | 665 silence = 0x80; |
640 break; | 666 waveformat.wBitsPerSample = 8; |
641 case 16: | 667 break; |
642 /* Signed 16 bit audio data */ | 668 case 16: |
643 spec->format = AUDIO_S16; | 669 /* Signed 16 bit audio data */ |
644 silence = 0x00; | 670 spec->format = AUDIO_S16; |
645 waveformat.wBitsPerSample = 16; | 671 silence = 0x00; |
646 break; | 672 waveformat.wBitsPerSample = 16; |
647 default: | 673 break; |
648 SDL_SetError("Unsupported audio format"); | 674 default: |
649 return(-1); | 675 SDL_SetError("Unsupported audio format"); |
650 } | 676 return (-1); |
651 waveformat.nChannels = spec->channels; | 677 } |
652 waveformat.nSamplesPerSec = spec->freq; | 678 waveformat.nChannels = spec->channels; |
653 waveformat.nBlockAlign = | 679 waveformat.nSamplesPerSec = spec->freq; |
654 waveformat.nChannels * (waveformat.wBitsPerSample/8); | 680 waveformat.nBlockAlign = |
655 waveformat.nAvgBytesPerSec = | 681 waveformat.nChannels * (waveformat.wBitsPerSample / 8); |
656 waveformat.nSamplesPerSec * waveformat.nBlockAlign; | 682 waveformat.nAvgBytesPerSec = |
657 | 683 waveformat.nSamplesPerSec * waveformat.nBlockAlign; |
658 /* Update the fragment size as size in bytes */ | 684 |
659 SDL_CalculateAudioSpec(spec); | 685 /* Update the fragment size as size in bytes */ |
660 | 686 SDL_CalculateAudioSpec(spec); |
661 /* Open the audio device */ | 687 |
662 result = DSoundCreate(NULL, &sound, NULL); | 688 /* Open the audio device */ |
663 if ( result != DS_OK ) { | 689 result = DSoundCreate(NULL, &sound, NULL); |
664 SetDSerror("DirectSoundCreate", result); | 690 if (result != DS_OK) { |
665 return(-1); | 691 SetDSerror("DirectSoundCreate", result); |
666 } | 692 return (-1); |
667 | 693 } |
668 /* Create the audio buffer to which we write */ | 694 |
669 NUM_BUFFERS = -1; | 695 /* Create the audio buffer to which we write */ |
696 NUM_BUFFERS = -1; | |
670 #ifdef USE_PRIMARY_BUFFER | 697 #ifdef USE_PRIMARY_BUFFER |
671 if ( mainwin ) { | 698 if (mainwin) { |
672 NUM_BUFFERS = CreatePrimary(sound, mainwin, &mixbuf, | 699 NUM_BUFFERS = CreatePrimary(sound, mainwin, &mixbuf, |
673 &waveformat, spec->size); | 700 &waveformat, spec->size); |
674 } | 701 } |
675 #endif /* USE_PRIMARY_BUFFER */ | 702 #endif /* USE_PRIMARY_BUFFER */ |
676 if ( NUM_BUFFERS < 0 ) { | 703 if (NUM_BUFFERS < 0) { |
677 NUM_BUFFERS = CreateSecondary(sound, mainwin, &mixbuf, | 704 NUM_BUFFERS = CreateSecondary(sound, mainwin, &mixbuf, |
678 &waveformat, spec->size); | 705 &waveformat, spec->size); |
679 if ( NUM_BUFFERS < 0 ) { | 706 if (NUM_BUFFERS < 0) { |
680 return(-1); | 707 return (-1); |
681 } | 708 } |
682 #ifdef DEBUG_SOUND | 709 #ifdef DEBUG_SOUND |
683 fprintf(stderr, "Using secondary audio buffer\n"); | 710 fprintf(stderr, "Using secondary audio buffer\n"); |
684 #endif | 711 #endif |
685 } | 712 } |
686 #ifdef DEBUG_SOUND | 713 #ifdef DEBUG_SOUND |
687 else | 714 else |
688 fprintf(stderr, "Using primary audio buffer\n"); | 715 fprintf(stderr, "Using primary audio buffer\n"); |
689 #endif | 716 #endif |
690 | 717 |
691 /* The buffer will auto-start playing in DX5_WaitAudio() */ | 718 /* The buffer will auto-start playing in DX5_WaitAudio() */ |
692 lastchunk = 0; | 719 lastchunk = 0; |
693 mixlen = spec->size; | 720 mixlen = spec->size; |
694 | 721 |
695 #ifdef USE_POSITION_NOTIFY | 722 #ifdef USE_POSITION_NOTIFY |
696 /* See if we can use DirectX 6 event notification */ | 723 /* See if we can use DirectX 6 event notification */ |
697 if ( CreateAudioEvent(this) == 0 ) { | 724 if (CreateAudioEvent(this) == 0) { |
698 this->WaitAudio = DX6_WaitAudio_EventWait; | 725 this->WaitAudio = DX6_WaitAudio_EventWait; |
699 } else { | 726 } else { |
700 this->WaitAudio = DX5_WaitAudio_BusyWait; | 727 this->WaitAudio = DX5_WaitAudio_BusyWait; |
701 } | 728 } |
702 #endif | 729 #endif |
703 return(0); | 730 return (0); |
704 } | 731 } |
705 | 732 |
733 /* vi: set ts=4 sw=4 expandtab: */ |