Mercurial > sdl-ios-xcode
annotate src/audio/paudio/SDL_paudio.c @ 4001:6831b8723a85 SDL-1.2
Don't initialize the audio buffer passed to the application's audio callback,
since they are expected to entirely fill it with data or silence.
For legacy apps that might expect the buffer to already have silence and thus
may not fill the buffer in the callback, there's an environment variable to
expose the old behaviour.
Fixes Bugzilla #416.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Thu, 05 Jul 2007 02:24:36 +0000 |
parents | d910939febfa |
children | 782fd950bd46 c121d94672cb a1b03ba2fcd0 |
rev | line source |
---|---|
0 | 1 /* |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
2 SDL - Simple DirectMedia Layer |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
3 Copyright (C) 1997-2006 Sam Lantinga |
0 | 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:
0
diff
changeset
|
6 modify it under the terms of the GNU Lesser General Public |
0 | 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:
0
diff
changeset
|
8 version 2.1 of the License, or (at your option) any later version. |
0 | 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:
0
diff
changeset
|
13 Lesser General Public License for more details. |
0 | 14 |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
0
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:
0
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:
0
diff
changeset
|
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
0 | 18 |
19 Carsten Griwodz | |
20 griff@kom.tu-darmstadt.de | |
21 | |
22 based on linux/SDL_dspaudio.c by Sam Lantinga | |
23 */ | |
1402
d910939febfa
Use consistent identifiers for the various platforms we support.
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
24 #include "SDL_config.h" |
0 | 25 |
26 /* Allow access to a raw mixing buffer */ | |
27 | |
28 #include <errno.h> | |
29 #include <unistd.h> | |
30 #include <fcntl.h> | |
31 #include <sys/time.h> | |
32 #include <sys/ioctl.h> | |
33 #include <sys/stat.h> | |
34 | |
1358
c71e05b4dc2e
More header massaging... works great on Windows. ;-)
Sam Lantinga <slouken@libsdl.org>
parents:
1338
diff
changeset
|
35 #include "SDL_timer.h" |
0 | 36 #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
|
37 #include "../SDL_audiomem.h" |
19418e4422cb
New configure-based build system. Still work in progress, but much improved
Sam Lantinga <slouken@libsdl.org>
parents:
1358
diff
changeset
|
38 #include "../SDL_audio_c.h" |
19418e4422cb
New configure-based build system. Still work in progress, but much improved
Sam Lantinga <slouken@libsdl.org>
parents:
1358
diff
changeset
|
39 #include "../SDL_audiodev_c.h" |
0 | 40 #include "SDL_paudio.h" |
41 | |
42 #define DEBUG_AUDIO 1 | |
43 | |
44 /* A conflict within AIX 4.3.3 <sys/> headers and probably others as well. | |
45 * I guess nobody ever uses audio... Shame over AIX header files. */ | |
46 #include <sys/machine.h> | |
47 #undef BIG_ENDIAN | |
48 #include <sys/audio.h> | |
49 | |
50 /* The tag name used by paud audio */ | |
51 #define Paud_DRIVER_NAME "paud" | |
52 | |
53 /* Open the audio device for playback, and don't block if busy */ | |
54 /* #define OPEN_FLAGS (O_WRONLY|O_NONBLOCK) */ | |
55 #define OPEN_FLAGS O_WRONLY | |
56 | |
57 /* Audio driver functions */ | |
58 static int Paud_OpenAudio(_THIS, SDL_AudioSpec *spec); | |
59 static void Paud_WaitAudio(_THIS); | |
60 static void Paud_PlayAudio(_THIS); | |
61 static Uint8 *Paud_GetAudioBuf(_THIS); | |
62 static void Paud_CloseAudio(_THIS); | |
63 | |
64 /* Audio driver bootstrap functions */ | |
65 | |
66 static int Audio_Available(void) | |
67 { | |
68 int fd; | |
69 int available; | |
70 | |
71 available = 0; | |
72 fd = SDL_OpenAudioPath(NULL, 0, OPEN_FLAGS, 0); | |
73 if ( fd >= 0 ) { | |
74 available = 1; | |
75 close(fd); | |
76 } | |
77 return(available); | |
78 } | |
79 | |
80 static void Audio_DeleteDevice(SDL_AudioDevice *device) | |
81 { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
82 SDL_free(device->hidden); |
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
83 SDL_free(device); |
0 | 84 } |
85 | |
86 static SDL_AudioDevice *Audio_CreateDevice(int devindex) | |
87 { | |
88 SDL_AudioDevice *this; | |
89 | |
90 /* 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
|
91 this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); |
0 | 92 if ( this ) { |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
93 SDL_memset(this, 0, (sizeof *this)); |
0 | 94 this->hidden = (struct SDL_PrivateAudioData *) |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
95 SDL_malloc((sizeof *this->hidden)); |
0 | 96 } |
97 if ( (this == NULL) || (this->hidden == NULL) ) { | |
98 SDL_OutOfMemory(); | |
99 if ( this ) { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
100 SDL_free(this); |
0 | 101 } |
102 return(0); | |
103 } | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
104 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); |
0 | 105 audio_fd = -1; |
106 | |
107 /* Set the function pointers */ | |
108 this->OpenAudio = Paud_OpenAudio; | |
109 this->WaitAudio = Paud_WaitAudio; | |
110 this->PlayAudio = Paud_PlayAudio; | |
111 this->GetAudioBuf = Paud_GetAudioBuf; | |
112 this->CloseAudio = Paud_CloseAudio; | |
113 | |
114 this->free = Audio_DeleteDevice; | |
115 | |
116 return this; | |
117 } | |
118 | |
119 AudioBootStrap Paud_bootstrap = { | |
120 Paud_DRIVER_NAME, "AIX Paudio", | |
121 Audio_Available, Audio_CreateDevice | |
122 }; | |
123 | |
124 /* This function waits until it is possible to write a full sound buffer */ | |
125 static void Paud_WaitAudio(_THIS) | |
126 { | |
127 fd_set fdset; | |
128 | |
129 /* See if we need to use timed audio synchronization */ | |
130 if ( frame_ticks ) { | |
131 /* Use timer for general audio synchronization */ | |
132 Sint32 ticks; | |
133 | |
134 ticks = ((Sint32)(next_frame - SDL_GetTicks()))-FUDGE_TICKS; | |
135 if ( ticks > 0 ) { | |
136 SDL_Delay(ticks); | |
137 } | |
138 } else { | |
139 audio_buffer paud_bufinfo; | |
140 | |
141 /* Use select() for audio synchronization */ | |
142 struct timeval timeout; | |
143 FD_ZERO(&fdset); | |
144 FD_SET(audio_fd, &fdset); | |
145 | |
146 if ( ioctl(audio_fd, AUDIO_BUFFER, &paud_bufinfo) < 0 ) { | |
147 #ifdef DEBUG_AUDIO | |
148 fprintf(stderr, "Couldn't get audio buffer information\n"); | |
149 #endif | |
150 timeout.tv_sec = 10; | |
151 timeout.tv_usec = 0; | |
152 } else { | |
153 long ms_in_buf = paud_bufinfo.write_buf_time; | |
154 timeout.tv_sec = ms_in_buf/1000; | |
155 ms_in_buf = ms_in_buf - timeout.tv_sec*1000; | |
156 timeout.tv_usec = ms_in_buf*1000; | |
157 #ifdef DEBUG_AUDIO | |
158 fprintf( stderr, | |
159 "Waiting for write_buf_time=%ld,%ld\n", | |
160 timeout.tv_sec, | |
161 timeout.tv_usec ); | |
162 #endif | |
163 } | |
164 | |
165 #ifdef DEBUG_AUDIO | |
166 fprintf(stderr, "Waiting for audio to get ready\n"); | |
167 #endif | |
168 if ( select(audio_fd+1, NULL, &fdset, NULL, &timeout) <= 0 ) { | |
169 const char *message = "Audio timeout - buggy audio driver? (disabled)"; | |
170 /* | |
171 * In general we should never print to the screen, | |
172 * but in this case we have no other way of letting | |
173 * the user know what happened. | |
174 */ | |
175 fprintf(stderr, "SDL: %s - %s\n", strerror(errno), message); | |
176 this->enabled = 0; | |
177 /* Don't try to close - may hang */ | |
178 audio_fd = -1; | |
179 #ifdef DEBUG_AUDIO | |
180 fprintf(stderr, "Done disabling audio\n"); | |
181 #endif | |
182 } | |
183 #ifdef DEBUG_AUDIO | |
184 fprintf(stderr, "Ready!\n"); | |
185 #endif | |
186 } | |
187 } | |
188 | |
189 static void Paud_PlayAudio(_THIS) | |
190 { | |
191 int written; | |
192 | |
193 /* Write the audio data, checking for EAGAIN on broken audio drivers */ | |
194 do { | |
195 written = write(audio_fd, mixbuf, mixlen); | |
196 if ( (written < 0) && ((errno == 0) || (errno == EAGAIN)) ) { | |
197 SDL_Delay(1); /* Let a little CPU time go by */ | |
198 } | |
199 } while ( (written < 0) && | |
200 ((errno == 0) || (errno == EAGAIN) || (errno == EINTR)) ); | |
201 | |
202 /* If timer synchronization is enabled, set the next write frame */ | |
203 if ( frame_ticks ) { | |
204 next_frame += frame_ticks; | |
205 } | |
206 | |
207 /* If we couldn't write, assume fatal error for now */ | |
208 if ( written < 0 ) { | |
209 this->enabled = 0; | |
210 } | |
211 #ifdef DEBUG_AUDIO | |
212 fprintf(stderr, "Wrote %d bytes of audio data\n", written); | |
213 #endif | |
214 } | |
215 | |
216 static Uint8 *Paud_GetAudioBuf(_THIS) | |
217 { | |
218 return mixbuf; | |
219 } | |
220 | |
221 static void Paud_CloseAudio(_THIS) | |
222 { | |
223 if ( mixbuf != NULL ) { | |
224 SDL_FreeAudioMem(mixbuf); | |
225 mixbuf = NULL; | |
226 } | |
227 if ( audio_fd >= 0 ) { | |
228 close(audio_fd); | |
229 audio_fd = -1; | |
230 } | |
231 } | |
232 | |
233 static int Paud_OpenAudio(_THIS, SDL_AudioSpec *spec) | |
234 { | |
235 char audiodev[1024]; | |
236 int format; | |
237 int bytes_per_sample; | |
238 Uint16 test_format; | |
239 audio_init paud_init; | |
240 audio_buffer paud_bufinfo; | |
241 audio_status paud_status; | |
242 audio_control paud_control; | |
243 audio_change paud_change; | |
244 | |
245 /* Reset the timer synchronization flag */ | |
246 frame_ticks = 0.0; | |
247 | |
248 /* Open the audio device */ | |
249 audio_fd = SDL_OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 0); | |
250 if ( audio_fd < 0 ) { | |
251 SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno)); | |
252 return -1; | |
253 } | |
254 | |
255 /* | |
256 * We can't set the buffer size - just ask the device for the maximum | |
257 * that we can have. | |
258 */ | |
259 if ( ioctl(audio_fd, AUDIO_BUFFER, &paud_bufinfo) < 0 ) { | |
260 SDL_SetError("Couldn't get audio buffer information"); | |
261 return -1; | |
262 } | |
263 | |
264 mixbuf = NULL; | |
265 | |
266 if ( spec->channels > 1 ) | |
267 spec->channels = 2; | |
268 else | |
269 spec->channels = 1; | |
270 | |
271 /* | |
272 * Fields in the audio_init structure: | |
273 * | |
274 * Ignored by us: | |
275 * | |
276 * paud.loadpath[LOAD_PATH]; * DSP code to load, MWave chip only? | |
277 * paud.slot_number; * slot number of the adapter | |
278 * paud.device_id; * adapter identification number | |
279 * | |
280 * Input: | |
281 * | |
282 * paud.srate; * the sampling rate in Hz | |
283 * paud.bits_per_sample; * 8, 16, 32, ... | |
284 * paud.bsize; * block size for this rate | |
285 * paud.mode; * ADPCM, PCM, MU_LAW, A_LAW, SOURCE_MIX | |
286 * paud.channels; * 1=mono, 2=stereo | |
287 * paud.flags; * FIXED - fixed length data | |
288 * * LEFT_ALIGNED, RIGHT_ALIGNED (var len only) | |
289 * * TWOS_COMPLEMENT - 2's complement data | |
290 * * SIGNED - signed? comment seems wrong in sys/audio.h | |
291 * * BIG_ENDIAN | |
292 * paud.operation; * PLAY, RECORD | |
293 * | |
294 * Output: | |
295 * | |
296 * paud.flags; * PITCH - pitch is supported | |
297 * * INPUT - input is supported | |
298 * * OUTPUT - output is supported | |
299 * * MONITOR - monitor is supported | |
300 * * VOLUME - volume is supported | |
301 * * VOLUME_DELAY - volume delay is supported | |
302 * * BALANCE - balance is supported | |
303 * * BALANCE_DELAY - balance delay is supported | |
304 * * TREBLE - treble control is supported | |
305 * * BASS - bass control is supported | |
306 * * BESTFIT_PROVIDED - best fit returned | |
307 * * LOAD_CODE - DSP load needed | |
308 * paud.rc; * NO_PLAY - DSP code can't do play requests | |
309 * * NO_RECORD - DSP code can't do record requests | |
310 * * INVALID_REQUEST - request was invalid | |
311 * * CONFLICT - conflict with open's flags | |
312 * * OVERLOADED - out of DSP MIPS or memory | |
313 * paud.position_resolution; * smallest increment for position | |
314 */ | |
315 | |
316 paud_init.srate = spec->freq; | |
317 paud_init.mode = PCM; | |
318 paud_init.operation = PLAY; | |
319 paud_init.channels = spec->channels; | |
320 | |
321 /* Try for a closest match on audio format */ | |
322 format = 0; | |
323 for ( test_format = SDL_FirstAudioFormat(spec->format); | |
324 ! format && test_format; ) { | |
325 #ifdef DEBUG_AUDIO | |
326 fprintf(stderr, "Trying format 0x%4.4x\n", test_format); | |
327 #endif | |
328 switch ( test_format ) { | |
329 case AUDIO_U8: | |
330 bytes_per_sample = 1; | |
331 paud_init.bits_per_sample = 8; | |
332 paud_init.flags = TWOS_COMPLEMENT | FIXED; | |
333 format = 1; | |
334 break; | |
335 case AUDIO_S8: | |
336 bytes_per_sample = 1; | |
337 paud_init.bits_per_sample = 8; | |
338 paud_init.flags = SIGNED | | |
339 TWOS_COMPLEMENT | FIXED; | |
340 format = 1; | |
341 break; | |
342 case AUDIO_S16LSB: | |
343 bytes_per_sample = 2; | |
344 paud_init.bits_per_sample = 16; | |
345 paud_init.flags = SIGNED | | |
346 TWOS_COMPLEMENT | FIXED; | |
347 format = 1; | |
348 break; | |
349 case AUDIO_S16MSB: | |
350 bytes_per_sample = 2; | |
351 paud_init.bits_per_sample = 16; | |
352 paud_init.flags = BIG_ENDIAN | | |
353 SIGNED | | |
354 TWOS_COMPLEMENT | FIXED; | |
355 format = 1; | |
356 break; | |
357 case AUDIO_U16LSB: | |
358 bytes_per_sample = 2; | |
359 paud_init.bits_per_sample = 16; | |
360 paud_init.flags = TWOS_COMPLEMENT | FIXED; | |
361 format = 1; | |
362 break; | |
363 case AUDIO_U16MSB: | |
364 bytes_per_sample = 2; | |
365 paud_init.bits_per_sample = 16; | |
366 paud_init.flags = BIG_ENDIAN | | |
367 TWOS_COMPLEMENT | FIXED; | |
368 format = 1; | |
369 break; | |
370 default: | |
371 break; | |
372 } | |
373 if ( ! format ) { | |
374 test_format = SDL_NextAudioFormat(); | |
375 } | |
376 } | |
377 if ( format == 0 ) { | |
378 #ifdef DEBUG_AUDIO | |
379 fprintf(stderr, "Couldn't find any hardware audio formats\n"); | |
380 #endif | |
381 SDL_SetError("Couldn't find any hardware audio formats"); | |
382 return -1; | |
383 } | |
384 spec->format = test_format; | |
385 | |
386 /* | |
387 * We know the buffer size and the max number of subsequent writes | |
388 * that can be pending. If more than one can pend, allow the application | |
389 * to do something like double buffering between our write buffer and | |
390 * the device's own buffer that we are filling with write() anyway. | |
391 * | |
392 * We calculate spec->samples like this because SDL_CalculateAudioSpec() | |
393 * will give put paud_bufinfo.write_buf_cap (or paud_bufinfo.write_buf_cap/2) | |
394 * into spec->size in return. | |
395 */ | |
396 if ( paud_bufinfo.request_buf_cap == 1 ) | |
397 { | |
398 spec->samples = paud_bufinfo.write_buf_cap | |
399 / bytes_per_sample | |
400 / spec->channels; | |
401 } | |
402 else | |
403 { | |
404 spec->samples = paud_bufinfo.write_buf_cap | |
405 / bytes_per_sample | |
406 / spec->channels | |
407 / 2; | |
408 } | |
409 paud_init.bsize = bytes_per_sample * spec->channels; | |
410 | |
411 SDL_CalculateAudioSpec(spec); | |
412 | |
413 /* | |
414 * The AIX paud device init can't modify the values of the audio_init | |
415 * structure that we pass to it. So we don't need any recalculation | |
416 * of this stuff and no reinit call as in linux dsp and dma code. | |
417 * | |
418 * /dev/paud supports all of the encoding formats, so we don't need | |
419 * to do anything like reopening the device, either. | |
420 */ | |
421 if ( ioctl(audio_fd, AUDIO_INIT, &paud_init) < 0 ) { | |
422 switch ( paud_init.rc ) | |
423 { | |
424 case 1 : | |
425 SDL_SetError("Couldn't set audio format: DSP can't do play requests"); | |
426 return -1; | |
427 break; | |
428 case 2 : | |
429 SDL_SetError("Couldn't set audio format: DSP can't do record requests"); | |
430 return -1; | |
431 break; | |
432 case 4 : | |
433 SDL_SetError("Couldn't set audio format: request was invalid"); | |
434 return -1; | |
435 break; | |
436 case 5 : | |
437 SDL_SetError("Couldn't set audio format: conflict with open's flags"); | |
438 return -1; | |
439 break; | |
440 case 6 : | |
441 SDL_SetError("Couldn't set audio format: out of DSP MIPS or memory"); | |
442 return -1; | |
443 break; | |
444 default : | |
445 SDL_SetError("Couldn't set audio format: not documented in sys/audio.h"); | |
446 return -1; | |
447 break; | |
448 } | |
449 } | |
450 | |
451 /* Allocate mixing buffer */ | |
452 mixlen = spec->size; | |
453 mixbuf = (Uint8 *)SDL_AllocAudioMem(mixlen); | |
454 if ( mixbuf == NULL ) { | |
455 return -1; | |
456 } | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
457 SDL_memset(mixbuf, spec->silence, spec->size); |
0 | 458 |
459 /* | |
460 * Set some paramters: full volume, first speaker that we can find. | |
461 * Ignore the other settings for now. | |
462 */ | |
463 paud_change.input = AUDIO_IGNORE; /* the new input source */ | |
464 paud_change.output = OUTPUT_1; /* EXTERNAL_SPEAKER,INTERNAL_SPEAKER,OUTPUT_1 */ | |
465 paud_change.monitor = AUDIO_IGNORE; /* the new monitor state */ | |
466 paud_change.volume = 0x7fffffff; /* volume level [0-0x7fffffff] */ | |
467 paud_change.volume_delay = AUDIO_IGNORE; /* the new volume delay */ | |
468 paud_change.balance = 0x3fffffff; /* the new balance */ | |
469 paud_change.balance_delay = AUDIO_IGNORE; /* the new balance delay */ | |
470 paud_change.treble = AUDIO_IGNORE; /* the new treble state */ | |
471 paud_change.bass = AUDIO_IGNORE; /* the new bass state */ | |
472 paud_change.pitch = AUDIO_IGNORE; /* the new pitch state */ | |
473 | |
474 paud_control.ioctl_request = AUDIO_CHANGE; | |
475 paud_control.request_info = (char*)&paud_change; | |
476 if ( ioctl(audio_fd, AUDIO_CONTROL, &paud_control) < 0 ) { | |
477 #ifdef DEBUG_AUDIO | |
478 fprintf(stderr, "Can't change audio display settings\n" ); | |
479 #endif | |
480 } | |
481 | |
482 /* | |
483 * Tell the device to expect data. Actual start will wait for | |
484 * the first write() call. | |
485 */ | |
486 paud_control.ioctl_request = AUDIO_START; | |
487 paud_control.position = 0; | |
488 if ( ioctl(audio_fd, AUDIO_CONTROL, &paud_control) < 0 ) { | |
489 #ifdef DEBUG_AUDIO | |
490 fprintf(stderr, "Can't start audio play\n" ); | |
491 #endif | |
492 SDL_SetError("Can't start audio play"); | |
493 return -1; | |
494 } | |
495 | |
496 /* Check to see if we need to use select() workaround */ | |
497 { char *workaround; | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
498 workaround = SDL_getenv("SDL_DSP_NOSELECT"); |
0 | 499 if ( workaround ) { |
500 frame_ticks = (float)(spec->samples*1000)/spec->freq; | |
501 next_frame = SDL_GetTicks()+frame_ticks; | |
502 } | |
503 } | |
504 | |
505 /* Get the parent process id (we're the parent of the audio thread) */ | |
506 parent = getpid(); | |
507 | |
508 /* We're ready to rock and roll. :-) */ | |
509 return 0; | |
510 } | |
511 |