comparison src/audio/paudio/SDL_paudio.c @ 3832:ca74a71063ac SDL-ryan-multiple-audio-device

Paudio driver moved to 1.3 API.
author Ryan C. Gordon <icculus@icculus.org>
date Sat, 07 Oct 2006 20:20:59 +0000
parents 7852b5b78af5
children 66fb40445587
comparison
equal deleted inserted replaced
3831:7df0d3efe682 3832:ca74a71063ac
38 #include "SDL_stdinc.h" 38 #include "SDL_stdinc.h"
39 #include "../SDL_audiomem.h" 39 #include "../SDL_audiomem.h"
40 #include "../SDL_audio_c.h" 40 #include "../SDL_audio_c.h"
41 #include "SDL_paudio.h" 41 #include "SDL_paudio.h"
42 42
43 #define DEBUG_AUDIO 1 43 #define DEBUG_AUDIO 0
44 44
45 /* A conflict within AIX 4.3.3 <sys/> headers and probably others as well. 45 /* A conflict within AIX 4.3.3 <sys/> headers and probably others as well.
46 * I guess nobody ever uses audio... Shame over AIX header files. */ 46 * I guess nobody ever uses audio... Shame over AIX header files. */
47 #include <sys/machine.h> 47 #include <sys/machine.h>
48 #undef BIG_ENDIAN 48 #undef BIG_ENDIAN
49 #include <sys/audio.h> 49 #include <sys/audio.h>
50 50
51 /* The tag name used by paud audio */ 51 /* The tag name used by paud audio */
52 #define Paud_DRIVER_NAME "paud" 52 #define PAUDIO_DRIVER_NAME "paud"
53 53
54 /* Open the audio device for playback, and don't block if busy */ 54 /* Open the audio device for playback, and don't block if busy */
55 /* #define OPEN_FLAGS (O_WRONLY|O_NONBLOCK) */ 55 /* #define OPEN_FLAGS (O_WRONLY|O_NONBLOCK) */
56 #define OPEN_FLAGS O_WRONLY 56 #define OPEN_FLAGS O_WRONLY
57
58 /* Audio driver functions */
59 static int Paud_OpenAudio(_THIS, SDL_AudioSpec * spec);
60 static void Paud_WaitAudio(_THIS);
61 static void Paud_PlayAudio(_THIS);
62 static Uint8 *Paud_GetAudioBuf(_THIS);
63 static void Paud_CloseAudio(_THIS);
64
65 57
66 /* Get the name of the audio device we use for output */ 58 /* Get the name of the audio device we use for output */
67 59
68 #ifndef _PATH_DEV_DSP 60 #ifndef _PATH_DEV_DSP
69 #define _PATH_DEV_DSP "/dev/%caud%c/%c" 61 #define _PATH_DEV_DSP "/dev/%caud%c/%c"
83 75
84 static int 76 static int
85 OpenUserDefinedDevice(char *path, int maxlen, int flags) 77 OpenUserDefinedDevice(char *path, int maxlen, int flags)
86 { 78 {
87 const char *audiodev; 79 const char *audiodev;
88 int audio_fd; 80 int fd;
89 81
90 /* Figure out what our audio device is */ 82 /* Figure out what our audio device is */
91 if ((audiodev = SDL_getenv("SDL_PATH_DSP")) == NULL) { 83 if ((audiodev = SDL_getenv("SDL_PATH_DSP")) == NULL) {
92 audiodev = SDL_getenv("AUDIODEV"); 84 audiodev = SDL_getenv("AUDIODEV");
93 } 85 }
94 if (audiodev == NULL) { 86 if (audiodev == NULL) {
95 return -1; 87 return -1;
96 } 88 }
97 audio_fd = open(audiodev, flags, 0); 89 fd = open(audiodev, flags, 0);
98 if (path != NULL) { 90 if (path != NULL) {
99 SDL_strlcpy(path, audiodev, maxlen); 91 SDL_strlcpy(path, audiodev, maxlen);
100 path[maxlen - 1] = '\0'; 92 path[maxlen - 1] = '\0';
101 } 93 }
102 return audio_fd; 94 return fd;
103 } 95 }
104 96
105 int 97 static int
106 OpenAudioPath(char *path, int maxlen, int flags, int classic) 98 OpenAudioPath(char *path, int maxlen, int flags, int classic)
107 { 99 {
108 struct stat sb; 100 struct stat sb;
109 int audio_fd; 101 int cycle = 0;
110 char audiopath[1024]; 102 int fd = OpenUserDefinedDevice(path, maxlen, flags);
111 int cycle; 103
112 104 if (fd != -1) {
113 audio_fd = OpenUserDefinedDevice(path, maxlen, flags); 105 return fd;
114 if (audio_fd != -1) { 106 }
115 return audio_fd; 107
116 }
117
118 cycle = 0;
119 /* !!! FIXME: do we really need a table here? */ 108 /* !!! FIXME: do we really need a table here? */
120 while (devsettings[cycle][0] != '\0') { 109 while (devsettings[cycle][0] != '\0') {
110 char audiopath[1024];
121 SDL_snprintf(audiopath, SDL_arraysize(audiopath), 111 SDL_snprintf(audiopath, SDL_arraysize(audiopath),
122 _PATH_DEV_DSP, 112 _PATH_DEV_DSP,
123 devsettings[cycle][0], 113 devsettings[cycle][0],
124 devsettings[cycle][1], devsettings[cycle][2]); 114 devsettings[cycle][1], devsettings[cycle][2]);
125 115
126 if (stat(audiopath, &sb) == 0) { 116 if (stat(audiopath, &sb) == 0) {
127 audio_fd = open(audiopath, flags, 0); 117 fd = open(audiopath, flags, 0);
128 if (audio_fd > 0) { 118 if (fd > 0) {
129 if (path != NULL) { 119 if (path != NULL) {
130 SDL_strlcpy(path, audiopath, maxlen); 120 SDL_strlcpy(path, audiopath, maxlen);
131 } 121 }
132 return audio_fd; 122 return fd;
133 } 123 }
134 } 124 }
135 } 125 }
136 return -1; 126 return -1;
137 } 127 }
138 128
139 129
140 /* Audio driver bootstrap functions */
141
142 static int 130 static int
143 Audio_Available(void) 131 PAUDIO_Available(void)
144 { 132 {
145 int fd; 133 int fd;
146 int available; 134 int available;
147 135
148 available = 0; 136 available = 0;
152 close(fd); 140 close(fd);
153 } 141 }
154 return (available); 142 return (available);
155 } 143 }
156 144
157 static void
158 Audio_DeleteDevice(SDL_AudioDevice * device)
159 {
160 SDL_free(device->hidden);
161 SDL_free(device);
162 }
163
164 static SDL_AudioDevice *
165 Audio_CreateDevice(int devindex)
166 {
167 SDL_AudioDevice *this;
168
169 /* Initialize all variables that we clean on shutdown */
170 this = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice));
171 if (this) {
172 SDL_memset(this, 0, (sizeof *this));
173 this->hidden = (struct SDL_PrivateAudioData *)
174 SDL_malloc((sizeof *this->hidden));
175 }
176 if ((this == NULL) || (this->hidden == NULL)) {
177 SDL_OutOfMemory();
178 if (this) {
179 SDL_free(this);
180 }
181 return (0);
182 }
183 SDL_memset(this->hidden, 0, (sizeof *this->hidden));
184 audio_fd = -1;
185
186 /* Set the function pointers */
187 this->OpenAudio = Paud_OpenAudio;
188 this->WaitAudio = Paud_WaitAudio;
189 this->PlayAudio = Paud_PlayAudio;
190 this->GetAudioBuf = Paud_GetAudioBuf;
191 this->CloseAudio = Paud_CloseAudio;
192
193 this->free = Audio_DeleteDevice;
194
195 return this;
196 }
197
198 AudioBootStrap Paud_bootstrap = {
199 Paud_DRIVER_NAME, "AIX Paudio",
200 Audio_Available, Audio_CreateDevice, 0
201 };
202 145
203 /* This function waits until it is possible to write a full sound buffer */ 146 /* This function waits until it is possible to write a full sound buffer */
204 static void 147 static void
205 Paud_WaitAudio(_THIS) 148 PAUDIO_WaitDevice(_THIS)
206 { 149 {
207 fd_set fdset; 150 fd_set fdset;
208 151
209 /* See if we need to use timed audio synchronization */ 152 /* See if we need to use timed audio synchronization */
210 if (frame_ticks) { 153 if (this->hidden->frame_ticks) {
211 /* Use timer for general audio synchronization */ 154 /* Use timer for general audio synchronization */
212 Sint32 ticks; 155 Sint32 ticks;
213 156
214 ticks = ((Sint32) (next_frame - SDL_GetTicks())) - FUDGE_TICKS; 157 ticks = ((Sint32)(this->hidden->next_frame-SDL_GetTicks()))-FUDGE_TICKS;
215 if (ticks > 0) { 158 if (ticks > 0) {
216 SDL_Delay(ticks); 159 SDL_Delay(ticks);
217 } 160 }
218 } else { 161 } else {
219 audio_buffer paud_bufinfo; 162 audio_buffer paud_bufinfo;
220 163
221 /* Use select() for audio synchronization */ 164 /* Use select() for audio synchronization */
222 struct timeval timeout; 165 struct timeval timeout;
223 FD_ZERO(&fdset); 166 FD_ZERO(&fdset);
224 FD_SET(audio_fd, &fdset); 167 FD_SET(this->hidden->audio_fd, &fdset);
225 168
226 if (ioctl(audio_fd, AUDIO_BUFFER, &paud_bufinfo) < 0) { 169 if (ioctl(this->hidden->audio_fd, AUDIO_BUFFER, &paud_bufinfo) < 0) {
227 #ifdef DEBUG_AUDIO 170 #ifdef DEBUG_AUDIO
228 fprintf(stderr, "Couldn't get audio buffer information\n"); 171 fprintf(stderr, "Couldn't get audio buffer information\n");
229 #endif 172 #endif
230 timeout.tv_sec = 10; 173 timeout.tv_sec = 10;
231 timeout.tv_usec = 0; 174 timeout.tv_usec = 0;
242 } 185 }
243 186
244 #ifdef DEBUG_AUDIO 187 #ifdef DEBUG_AUDIO
245 fprintf(stderr, "Waiting for audio to get ready\n"); 188 fprintf(stderr, "Waiting for audio to get ready\n");
246 #endif 189 #endif
247 if (select(audio_fd + 1, NULL, &fdset, NULL, &timeout) <= 0) { 190 if (select(this->hidden->audio_fd+1,NULL,&fdset,NULL,&timeout) <= 0) {
248 const char *message = 191 const char *message =
249 "Audio timeout - buggy audio driver? (disabled)"; 192 "Audio timeout - buggy audio driver? (disabled)";
250 /* 193 /*
251 * In general we should never print to the screen, 194 * In general we should never print to the screen,
252 * but in this case we have no other way of letting 195 * but in this case we have no other way of letting
253 * the user know what happened. 196 * the user know what happened.
254 */ 197 */
255 fprintf(stderr, "SDL: %s - %s\n", strerror(errno), message); 198 fprintf(stderr, "SDL: %s - %s\n", strerror(errno), message);
256 this->enabled = 0; 199 this->enabled = 0;
257 /* Don't try to close - may hang */ 200 /* Don't try to close - may hang */
258 audio_fd = -1; 201 this->hidden->audio_fd = -1;
259 #ifdef DEBUG_AUDIO 202 #ifdef DEBUG_AUDIO
260 fprintf(stderr, "Done disabling audio\n"); 203 fprintf(stderr, "Done disabling audio\n");
261 #endif 204 #endif
262 } 205 }
263 #ifdef DEBUG_AUDIO 206 #ifdef DEBUG_AUDIO
265 #endif 208 #endif
266 } 209 }
267 } 210 }
268 211
269 static void 212 static void
270 Paud_PlayAudio(_THIS) 213 PAUDIO_PlayDevice(_THIS)
271 { 214 {
272 int written; 215 int written = 0;
216 const Uint8 *mixbuf = this->hidden->mixbuf;
217 const size_t mixlen = this->hidden->mixlen;
273 218
274 /* Write the audio data, checking for EAGAIN on broken audio drivers */ 219 /* Write the audio data, checking for EAGAIN on broken audio drivers */
275 do { 220 do {
276 written = write(audio_fd, mixbuf, mixlen); 221 written = write(this->hidden->audio_fd, mixbuf, mixlen);
277 if ((written < 0) && ((errno == 0) || (errno == EAGAIN))) { 222 if ((written < 0) && ((errno == 0) || (errno == EAGAIN))) {
278 SDL_Delay(1); /* Let a little CPU time go by */ 223 SDL_Delay(1); /* Let a little CPU time go by */
279 } 224 }
280 } 225 }
281 while ((written < 0) && 226 while ((written < 0) &&
282 ((errno == 0) || (errno == EAGAIN) || (errno == EINTR))); 227 ((errno == 0) || (errno == EAGAIN) || (errno == EINTR)));
283 228
284 /* If timer synchronization is enabled, set the next write frame */ 229 /* If timer synchronization is enabled, set the next write frame */
285 if (frame_ticks) { 230 if (this->hidden->frame_ticks) {
286 next_frame += frame_ticks; 231 this->hidden->next_frame += this->hidden->frame_ticks;
287 } 232 }
288 233
289 /* If we couldn't write, assume fatal error for now */ 234 /* If we couldn't write, assume fatal error for now */
290 if (written < 0) { 235 if (written < 0) {
291 this->enabled = 0; 236 this->enabled = 0;
294 fprintf(stderr, "Wrote %d bytes of audio data\n", written); 239 fprintf(stderr, "Wrote %d bytes of audio data\n", written);
295 #endif 240 #endif
296 } 241 }
297 242
298 static Uint8 * 243 static Uint8 *
299 Paud_GetAudioBuf(_THIS) 244 PAUDIO_GetDeviceBuf(_THIS)
300 { 245 {
301 return mixbuf; 246 return this->hidden->mixbuf;
302 } 247 }
303 248
304 static void 249 static void
305 Paud_CloseAudio(_THIS) 250 PAUDIO_CloseDevice(_THIS)
306 { 251 {
307 if (mixbuf != NULL) { 252 if (this->hidden != NULL) {
308 SDL_FreeAudioMem(mixbuf); 253 if (this->hidden->mixbuf != NULL) {
309 mixbuf = NULL; 254 SDL_FreeAudioMem(this->hidden->mixbuf);
310 } 255 this->hidden->mixbuf = NULL;
311 if (audio_fd >= 0) { 256 }
312 close(audio_fd); 257 if (this->hidden->audio_fd >= 0) {
313 audio_fd = -1; 258 close(this->hidden->audio_fd);
259 this->hidden->audio_fd = -1;
260 }
261 SDL_free(this->hidden);
262 this->hidden = NULL;
314 } 263 }
315 } 264 }
316 265
317 static int 266 static int
318 Paud_OpenAudio(_THIS, SDL_AudioSpec * spec) 267 PAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
319 { 268 {
269 const char *workaround = SDL_getenv("SDL_DSP_NOSELECT");
320 char audiodev[1024]; 270 char audiodev[1024];
271 const char *err = NULL;
321 int format; 272 int format;
322 int bytes_per_sample; 273 int bytes_per_sample;
323 SDL_AudioFormat test_format; 274 SDL_AudioFormat test_format;
324 audio_init paud_init; 275 audio_init paud_init;
325 audio_buffer paud_bufinfo; 276 audio_buffer paud_bufinfo;
326 audio_status paud_status; 277 audio_status paud_status;
327 audio_control paud_control; 278 audio_control paud_control;
328 audio_change paud_change; 279 audio_change paud_change;
329 280 int fd = -1;
330 /* Reset the timer synchronization flag */ 281
331 frame_ticks = 0.0; 282 /* Initialize all variables that we clean on shutdown */
283 this->hidden = (struct SDL_PrivateAudioData *)
284 SDL_malloc((sizeof *this->hidden));
285 if (this->hidden == NULL) {
286 SDL_OutOfMemory();
287 return 0;
288 }
289 SDL_memset(this->hidden, 0, (sizeof *this->hidden));
332 290
333 /* Open the audio device */ 291 /* Open the audio device */
334 audio_fd = OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 0); 292 fd = OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 0);
335 if (audio_fd < 0) { 293 this->hidden->audio_fd = fd;
294 if (fd < 0) {
295 PAUDIO_CloseDevice(this);
336 SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno)); 296 SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno));
337 return -1; 297 return 0;
338 } 298 }
339 299
340 /* 300 /*
341 * We can't set the buffer size - just ask the device for the maximum 301 * We can't set the buffer size - just ask the device for the maximum
342 * that we can have. 302 * that we can have.
343 */ 303 */
344 if (ioctl(audio_fd, AUDIO_BUFFER, &paud_bufinfo) < 0) { 304 if (ioctl(fd, AUDIO_BUFFER, &paud_bufinfo) < 0) {
305 PAUDIO_CloseDevice(this);
345 SDL_SetError("Couldn't get audio buffer information"); 306 SDL_SetError("Couldn't get audio buffer information");
346 return -1; 307 return 0;
347 } 308 }
348 309
349 mixbuf = NULL; 310 if (this->spec.channels > 1)
350 311 this->spec.channels = 2;
351 if (spec->channels > 1)
352 spec->channels = 2;
353 else 312 else
354 spec->channels = 1; 313 this->spec.channels = 1;
355 314
356 /* 315 /*
357 * Fields in the audio_init structure: 316 * Fields in the audio_init structure:
358 * 317 *
359 * Ignored by us: 318 * Ignored by us:
396 * * CONFLICT - conflict with open's flags 355 * * CONFLICT - conflict with open's flags
397 * * OVERLOADED - out of DSP MIPS or memory 356 * * OVERLOADED - out of DSP MIPS or memory
398 * paud.position_resolution; * smallest increment for position 357 * paud.position_resolution; * smallest increment for position
399 */ 358 */
400 359
401 paud_init.srate = spec->freq; 360 paud_init.srate = this->spec.freq;
402 paud_init.mode = PCM; 361 paud_init.mode = PCM;
403 paud_init.operation = PLAY; 362 paud_init.operation = PLAY;
404 paud_init.channels = spec->channels; 363 paud_init.channels = this->spec.channels;
405 364
406 /* Try for a closest match on audio format */ 365 /* Try for a closest match on audio format */
407 format = 0; 366 format = 0;
408 for (test_format = SDL_FirstAudioFormat(spec->format); 367 for (test_format = SDL_FirstAudioFormat(this->spec.format);
409 !format && test_format;) { 368 !format && test_format;) {
410 #ifdef DEBUG_AUDIO 369 #ifdef DEBUG_AUDIO
411 fprintf(stderr, "Trying format 0x%4.4x\n", test_format); 370 fprintf(stderr, "Trying format 0x%4.4x\n", test_format);
412 #endif 371 #endif
413 switch (test_format) { 372 switch (test_format) {
456 } 415 }
457 if (format == 0) { 416 if (format == 0) {
458 #ifdef DEBUG_AUDIO 417 #ifdef DEBUG_AUDIO
459 fprintf(stderr, "Couldn't find any hardware audio formats\n"); 418 fprintf(stderr, "Couldn't find any hardware audio formats\n");
460 #endif 419 #endif
420 PAUDIO_CloseDevice(this);
461 SDL_SetError("Couldn't find any hardware audio formats"); 421 SDL_SetError("Couldn't find any hardware audio formats");
462 return -1; 422 return 0;
463 } 423 }
464 spec->format = test_format; 424 this->spec.format = test_format;
465 425
466 /* 426 /*
467 * We know the buffer size and the max number of subsequent writes 427 * We know the buffer size and the max number of subsequent writes
468 * that can be pending. If more than one can pend, allow the application 428 * that can be pending. If more than one can pend, allow the application
469 * to do something like double buffering between our write buffer and 429 * to do something like double buffering between our write buffer and
470 * the device's own buffer that we are filling with write() anyway. 430 * the device's own buffer that we are filling with write() anyway.
471 * 431 *
472 * We calculate spec->samples like this because SDL_CalculateAudioSpec() 432 * We calculate this->spec.samples like this because
473 * will give put paud_bufinfo.write_buf_cap (or paud_bufinfo.write_buf_cap/2) 433 * SDL_CalculateAudioSpec() will give put paud_bufinfo.write_buf_cap
474 * into spec->size in return. 434 * (or paud_bufinfo.write_buf_cap/2) into this->spec.size in return.
475 */ 435 */
476 if (paud_bufinfo.request_buf_cap == 1) { 436 if (paud_bufinfo.request_buf_cap == 1) {
477 spec->samples = paud_bufinfo.write_buf_cap 437 this->spec.samples = paud_bufinfo.write_buf_cap
478 / bytes_per_sample / spec->channels; 438 / bytes_per_sample / this->spec.channels;
479 } else { 439 } else {
480 spec->samples = paud_bufinfo.write_buf_cap 440 this->spec.samples = paud_bufinfo.write_buf_cap
481 / bytes_per_sample / spec->channels / 2; 441 / bytes_per_sample / this->spec.channels / 2;
482 } 442 }
483 paud_init.bsize = bytes_per_sample * spec->channels; 443 paud_init.bsize = bytes_per_sample * this->spec.channels;
484 444
485 SDL_CalculateAudioSpec(spec); 445 SDL_CalculateAudioSpec(&this->spec);
486 446
487 /* 447 /*
488 * The AIX paud device init can't modify the values of the audio_init 448 * The AIX paud device init can't modify the values of the audio_init
489 * structure that we pass to it. So we don't need any recalculation 449 * structure that we pass to it. So we don't need any recalculation
490 * of this stuff and no reinit call as in linux dsp and dma code. 450 * of this stuff and no reinit call as in linux dsp and dma code.
491 * 451 *
492 * /dev/paud supports all of the encoding formats, so we don't need 452 * /dev/paud supports all of the encoding formats, so we don't need
493 * to do anything like reopening the device, either. 453 * to do anything like reopening the device, either.
494 */ 454 */
495 if (ioctl(audio_fd, AUDIO_INIT, &paud_init) < 0) { 455 if (ioctl(fd, AUDIO_INIT, &paud_init) < 0) {
496 switch (paud_init.rc) { 456 switch (paud_init.rc) {
497 case 1: 457 case 1:
498 SDL_SetError 458 err = "Couldn't set audio format: DSP can't do play requests";
499 ("Couldn't set audio format: DSP can't do play requests");
500 return -1;
501 break; 459 break;
502 case 2: 460 case 2:
503 SDL_SetError 461 err = "Couldn't set audio format: DSP can't do record requests";
504 ("Couldn't set audio format: DSP can't do record requests");
505 return -1;
506 break; 462 break;
507 case 4: 463 case 4:
508 SDL_SetError("Couldn't set audio format: request was invalid"); 464 err = "Couldn't set audio format: request was invalid";
509 return -1;
510 break; 465 break;
511 case 5: 466 case 5:
512 SDL_SetError 467 err = "Couldn't set audio format: conflict with open's flags";
513 ("Couldn't set audio format: conflict with open's flags");
514 return -1;
515 break; 468 break;
516 case 6: 469 case 6:
517 SDL_SetError 470 err = "Couldn't set audio format: out of DSP MIPS or memory";
518 ("Couldn't set audio format: out of DSP MIPS or memory");
519 return -1;
520 break; 471 break;
521 default: 472 default:
522 SDL_SetError 473 err = "Couldn't set audio format: not documented in sys/audio.h";
523 ("Couldn't set audio format: not documented in sys/audio.h"); 474 break;
524 return -1; 475 }
525 break; 476 }
526 } 477
478 if (err != NULL) {
479 PAUDIO_CloseDevice(this);
480 SDL_SetError("Paudio: %s", err);
481 return 0;
527 } 482 }
528 483
529 /* Allocate mixing buffer */ 484 /* Allocate mixing buffer */
530 mixlen = spec->size; 485 this->hidden->mixlen = this->spec.size;
531 mixbuf = (Uint8 *) SDL_AllocAudioMem(mixlen); 486 this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
532 if (mixbuf == NULL) { 487 if (this->hidden->mixbuf == NULL) {
533 return -1; 488 PAUDIO_CloseDevice(this);
534 } 489 SDL_OutOfMemory();
535 SDL_memset(mixbuf, spec->silence, spec->size); 490 return 0;
491 }
492 SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
536 493
537 /* 494 /*
538 * Set some paramters: full volume, first speaker that we can find. 495 * Set some paramters: full volume, first speaker that we can find.
539 * Ignore the other settings for now. 496 * Ignore the other settings for now.
540 */ 497 */
549 paud_change.bass = AUDIO_IGNORE; /* the new bass state */ 506 paud_change.bass = AUDIO_IGNORE; /* the new bass state */
550 paud_change.pitch = AUDIO_IGNORE; /* the new pitch state */ 507 paud_change.pitch = AUDIO_IGNORE; /* the new pitch state */
551 508
552 paud_control.ioctl_request = AUDIO_CHANGE; 509 paud_control.ioctl_request = AUDIO_CHANGE;
553 paud_control.request_info = (char *) &paud_change; 510 paud_control.request_info = (char *) &paud_change;
554 if (ioctl(audio_fd, AUDIO_CONTROL, &paud_control) < 0) { 511 if (ioctl(fd, AUDIO_CONTROL, &paud_control) < 0) {
555 #ifdef DEBUG_AUDIO 512 #ifdef DEBUG_AUDIO
556 fprintf(stderr, "Can't change audio display settings\n"); 513 fprintf(stderr, "Can't change audio display settings\n");
557 #endif 514 #endif
558 } 515 }
559 516
561 * Tell the device to expect data. Actual start will wait for 518 * Tell the device to expect data. Actual start will wait for
562 * the first write() call. 519 * the first write() call.
563 */ 520 */
564 paud_control.ioctl_request = AUDIO_START; 521 paud_control.ioctl_request = AUDIO_START;
565 paud_control.position = 0; 522 paud_control.position = 0;
566 if (ioctl(audio_fd, AUDIO_CONTROL, &paud_control) < 0) { 523 if (ioctl(fd, AUDIO_CONTROL, &paud_control) < 0) {
524 PAUDIO_CloseDevice(this);
567 #ifdef DEBUG_AUDIO 525 #ifdef DEBUG_AUDIO
568 fprintf(stderr, "Can't start audio play\n"); 526 fprintf(stderr, "Can't start audio play\n");
569 #endif 527 #endif
570 SDL_SetError("Can't start audio play"); 528 SDL_SetError("Can't start audio play");
571 return -1; 529 return 0;
572 } 530 }
573 531
574 /* Check to see if we need to use select() workaround */ 532 /* Check to see if we need to use select() workaround */
575 { 533 if (workaround != NULL) {
576 char *workaround; 534 this->hidden->frame_ticks = (float) (this->spec.samples * 1000) /
577 workaround = SDL_getenv("SDL_DSP_NOSELECT"); 535 this->spec.freq;
578 if (workaround) { 536 this->hidden->next_frame = SDL_GetTicks() + this->hidden->frame_ticks;
579 frame_ticks = (float) (spec->samples * 1000) / spec->freq; 537 }
580 next_frame = SDL_GetTicks() + frame_ticks;
581 }
582 }
583
584 /* Get the parent process id (we're the parent of the audio thread) */
585 parent = getpid();
586 538
587 /* We're ready to rock and roll. :-) */ 539 /* We're ready to rock and roll. :-) */
588 return 0; 540 return 1;
589 } 541 }
542
543 static int
544 PAUDIO_Init(SDL_AudioDriverImpl *impl)
545 {
546 /* Set the function pointers */
547 impl->OpenDevice = DSP_OpenDevice;
548 impl->PlayDevice = DSP_PlayDevice;
549 impl->PlayDevice = DSP_WaitDevice;
550 impl->GetDeviceBuf = DSP_GetDeviceBuf;
551 impl->CloseDevice = DSP_CloseDevice;
552 impl->OnlyHasDefaultOutputDevice = 1; /* !!! FIXME: add device enum! */
553
554 return 1;
555 }
556
557 AudioBootStrap PAUDIO_bootstrap = {
558 PAUDIO_DRIVER_NAME, "AIX Paudio",
559 PAUDIO_Available, PAUDIO_Init, 0
560 };
590 561
591 /* vi: set ts=4 sw=4 expandtab: */ 562 /* vi: set ts=4 sw=4 expandtab: */