comparison src/audio/paudio/SDL_paudio.c @ 1668:4da1ee79c9af SDL-1.3

more tweaking indent options
author Sam Lantinga <slouken@libsdl.org>
date Mon, 29 May 2006 04:04:35 +0000
parents 782fd950bd46
children
comparison
equal deleted inserted replaced
1667:1fddae038bc8 1668:4da1ee79c9af
53 /* Open the audio device for playback, and don't block if busy */ 53 /* Open the audio device for playback, and don't block if busy */
54 /* #define OPEN_FLAGS (O_WRONLY|O_NONBLOCK) */ 54 /* #define OPEN_FLAGS (O_WRONLY|O_NONBLOCK) */
55 #define OPEN_FLAGS O_WRONLY 55 #define OPEN_FLAGS O_WRONLY
56 56
57 /* Audio driver functions */ 57 /* Audio driver functions */
58 static int Paud_OpenAudio (_THIS, SDL_AudioSpec * spec); 58 static int Paud_OpenAudio(_THIS, SDL_AudioSpec * spec);
59 static void Paud_WaitAudio (_THIS); 59 static void Paud_WaitAudio(_THIS);
60 static void Paud_PlayAudio (_THIS); 60 static void Paud_PlayAudio(_THIS);
61 static Uint8 *Paud_GetAudioBuf (_THIS); 61 static Uint8 *Paud_GetAudioBuf(_THIS);
62 static void Paud_CloseAudio (_THIS); 62 static void Paud_CloseAudio(_THIS);
63 63
64 /* Audio driver bootstrap functions */ 64 /* Audio driver bootstrap functions */
65 65
66 static int 66 static int
67 Audio_Available (void) 67 Audio_Available(void)
68 { 68 {
69 int fd; 69 int fd;
70 int available; 70 int available;
71 71
72 available = 0; 72 available = 0;
73 fd = SDL_OpenAudioPath (NULL, 0, OPEN_FLAGS, 0); 73 fd = SDL_OpenAudioPath(NULL, 0, OPEN_FLAGS, 0);
74 if (fd >= 0) { 74 if (fd >= 0) {
75 available = 1; 75 available = 1;
76 close (fd); 76 close(fd);
77 } 77 }
78 return (available); 78 return (available);
79 } 79 }
80 80
81 static void 81 static void
82 Audio_DeleteDevice (SDL_AudioDevice * device) 82 Audio_DeleteDevice(SDL_AudioDevice * device)
83 { 83 {
84 SDL_free (device->hidden); 84 SDL_free(device->hidden);
85 SDL_free (device); 85 SDL_free(device);
86 } 86 }
87 87
88 static SDL_AudioDevice * 88 static SDL_AudioDevice *
89 Audio_CreateDevice (int devindex) 89 Audio_CreateDevice(int devindex)
90 { 90 {
91 SDL_AudioDevice *this; 91 SDL_AudioDevice *this;
92 92
93 /* Initialize all variables that we clean on shutdown */ 93 /* Initialize all variables that we clean on shutdown */
94 this = (SDL_AudioDevice *) SDL_malloc (sizeof (SDL_AudioDevice)); 94 this = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice));
95 if (this) { 95 if (this) {
96 SDL_memset (this, 0, (sizeof *this)); 96 SDL_memset(this, 0, (sizeof *this));
97 this->hidden = (struct SDL_PrivateAudioData *) 97 this->hidden = (struct SDL_PrivateAudioData *)
98 SDL_malloc ((sizeof *this->hidden)); 98 SDL_malloc((sizeof *this->hidden));
99 } 99 }
100 if ((this == NULL) || (this->hidden == NULL)) { 100 if ((this == NULL) || (this->hidden == NULL)) {
101 SDL_OutOfMemory (); 101 SDL_OutOfMemory();
102 if (this) { 102 if (this) {
103 SDL_free (this); 103 SDL_free(this);
104 } 104 }
105 return (0); 105 return (0);
106 } 106 }
107 SDL_memset (this->hidden, 0, (sizeof *this->hidden)); 107 SDL_memset(this->hidden, 0, (sizeof *this->hidden));
108 audio_fd = -1; 108 audio_fd = -1;
109 109
110 /* Set the function pointers */ 110 /* Set the function pointers */
111 this->OpenAudio = Paud_OpenAudio; 111 this->OpenAudio = Paud_OpenAudio;
112 this->WaitAudio = Paud_WaitAudio; 112 this->WaitAudio = Paud_WaitAudio;
124 Audio_Available, Audio_CreateDevice 124 Audio_Available, Audio_CreateDevice
125 }; 125 };
126 126
127 /* This function waits until it is possible to write a full sound buffer */ 127 /* This function waits until it is possible to write a full sound buffer */
128 static void 128 static void
129 Paud_WaitAudio (_THIS) 129 Paud_WaitAudio(_THIS)
130 { 130 {
131 fd_set fdset; 131 fd_set fdset;
132 132
133 /* See if we need to use timed audio synchronization */ 133 /* See if we need to use timed audio synchronization */
134 if (frame_ticks) { 134 if (frame_ticks) {
135 /* Use timer for general audio synchronization */ 135 /* Use timer for general audio synchronization */
136 Sint32 ticks; 136 Sint32 ticks;
137 137
138 ticks = ((Sint32) (next_frame - SDL_GetTicks ())) - FUDGE_TICKS; 138 ticks = ((Sint32) (next_frame - SDL_GetTicks())) - FUDGE_TICKS;
139 if (ticks > 0) { 139 if (ticks > 0) {
140 SDL_Delay (ticks); 140 SDL_Delay(ticks);
141 } 141 }
142 } else { 142 } else {
143 audio_buffer paud_bufinfo; 143 audio_buffer paud_bufinfo;
144 144
145 /* Use select() for audio synchronization */ 145 /* Use select() for audio synchronization */
146 struct timeval timeout; 146 struct timeval timeout;
147 FD_ZERO (&fdset); 147 FD_ZERO(&fdset);
148 FD_SET (audio_fd, &fdset); 148 FD_SET(audio_fd, &fdset);
149 149
150 if (ioctl (audio_fd, AUDIO_BUFFER, &paud_bufinfo) < 0) { 150 if (ioctl(audio_fd, AUDIO_BUFFER, &paud_bufinfo) < 0) {
151 #ifdef DEBUG_AUDIO 151 #ifdef DEBUG_AUDIO
152 fprintf (stderr, "Couldn't get audio buffer information\n"); 152 fprintf(stderr, "Couldn't get audio buffer information\n");
153 #endif 153 #endif
154 timeout.tv_sec = 10; 154 timeout.tv_sec = 10;
155 timeout.tv_usec = 0; 155 timeout.tv_usec = 0;
156 } else { 156 } else {
157 long ms_in_buf = paud_bufinfo.write_buf_time; 157 long ms_in_buf = paud_bufinfo.write_buf_time;
158 timeout.tv_sec = ms_in_buf / 1000; 158 timeout.tv_sec = ms_in_buf / 1000;
159 ms_in_buf = ms_in_buf - timeout.tv_sec * 1000; 159 ms_in_buf = ms_in_buf - timeout.tv_sec * 1000;
160 timeout.tv_usec = ms_in_buf * 1000; 160 timeout.tv_usec = ms_in_buf * 1000;
161 #ifdef DEBUG_AUDIO 161 #ifdef DEBUG_AUDIO
162 fprintf (stderr, 162 fprintf(stderr,
163 "Waiting for write_buf_time=%ld,%ld\n", 163 "Waiting for write_buf_time=%ld,%ld\n",
164 timeout.tv_sec, timeout.tv_usec); 164 timeout.tv_sec, timeout.tv_usec);
165 #endif 165 #endif
166 } 166 }
167 167
168 #ifdef DEBUG_AUDIO 168 #ifdef DEBUG_AUDIO
169 fprintf (stderr, "Waiting for audio to get ready\n"); 169 fprintf(stderr, "Waiting for audio to get ready\n");
170 #endif 170 #endif
171 if (select (audio_fd + 1, NULL, &fdset, NULL, &timeout) <= 0) { 171 if (select(audio_fd + 1, NULL, &fdset, NULL, &timeout) <= 0) {
172 const char *message = 172 const char *message =
173 "Audio timeout - buggy audio driver? (disabled)"; 173 "Audio timeout - buggy audio driver? (disabled)";
174 /* 174 /*
175 * In general we should never print to the screen, 175 * In general we should never print to the screen,
176 * but in this case we have no other way of letting 176 * but in this case we have no other way of letting
177 * the user know what happened. 177 * the user know what happened.
178 */ 178 */
179 fprintf (stderr, "SDL: %s - %s\n", strerror (errno), message); 179 fprintf(stderr, "SDL: %s - %s\n", strerror(errno), message);
180 this->enabled = 0; 180 this->enabled = 0;
181 /* Don't try to close - may hang */ 181 /* Don't try to close - may hang */
182 audio_fd = -1; 182 audio_fd = -1;
183 #ifdef DEBUG_AUDIO 183 #ifdef DEBUG_AUDIO
184 fprintf (stderr, "Done disabling audio\n"); 184 fprintf(stderr, "Done disabling audio\n");
185 #endif 185 #endif
186 } 186 }
187 #ifdef DEBUG_AUDIO 187 #ifdef DEBUG_AUDIO
188 fprintf (stderr, "Ready!\n"); 188 fprintf(stderr, "Ready!\n");
189 #endif 189 #endif
190 } 190 }
191 } 191 }
192 192
193 static void 193 static void
194 Paud_PlayAudio (_THIS) 194 Paud_PlayAudio(_THIS)
195 { 195 {
196 int written; 196 int written;
197 197
198 /* Write the audio data, checking for EAGAIN on broken audio drivers */ 198 /* Write the audio data, checking for EAGAIN on broken audio drivers */
199 do { 199 do {
200 written = write (audio_fd, mixbuf, mixlen); 200 written = write(audio_fd, mixbuf, mixlen);
201 if ((written < 0) && ((errno == 0) || (errno == EAGAIN))) { 201 if ((written < 0) && ((errno == 0) || (errno == EAGAIN))) {
202 SDL_Delay (1); /* Let a little CPU time go by */ 202 SDL_Delay(1); /* Let a little CPU time go by */
203 } 203 }
204 } 204 }
205 while ((written < 0) && 205 while ((written < 0) &&
206 ((errno == 0) || (errno == EAGAIN) || (errno == EINTR))); 206 ((errno == 0) || (errno == EAGAIN) || (errno == EINTR)));
207 207
213 /* If we couldn't write, assume fatal error for now */ 213 /* If we couldn't write, assume fatal error for now */
214 if (written < 0) { 214 if (written < 0) {
215 this->enabled = 0; 215 this->enabled = 0;
216 } 216 }
217 #ifdef DEBUG_AUDIO 217 #ifdef DEBUG_AUDIO
218 fprintf (stderr, "Wrote %d bytes of audio data\n", written); 218 fprintf(stderr, "Wrote %d bytes of audio data\n", written);
219 #endif 219 #endif
220 } 220 }
221 221
222 static Uint8 * 222 static Uint8 *
223 Paud_GetAudioBuf (_THIS) 223 Paud_GetAudioBuf(_THIS)
224 { 224 {
225 return mixbuf; 225 return mixbuf;
226 } 226 }
227 227
228 static void 228 static void
229 Paud_CloseAudio (_THIS) 229 Paud_CloseAudio(_THIS)
230 { 230 {
231 if (mixbuf != NULL) { 231 if (mixbuf != NULL) {
232 SDL_FreeAudioMem (mixbuf); 232 SDL_FreeAudioMem(mixbuf);
233 mixbuf = NULL; 233 mixbuf = NULL;
234 } 234 }
235 if (audio_fd >= 0) { 235 if (audio_fd >= 0) {
236 close (audio_fd); 236 close(audio_fd);
237 audio_fd = -1; 237 audio_fd = -1;
238 } 238 }
239 } 239 }
240 240
241 static int 241 static int
242 Paud_OpenAudio (_THIS, SDL_AudioSpec * spec) 242 Paud_OpenAudio(_THIS, SDL_AudioSpec * spec)
243 { 243 {
244 char audiodev[1024]; 244 char audiodev[1024];
245 int format; 245 int format;
246 int bytes_per_sample; 246 int bytes_per_sample;
247 Uint16 test_format; 247 Uint16 test_format;
253 253
254 /* Reset the timer synchronization flag */ 254 /* Reset the timer synchronization flag */
255 frame_ticks = 0.0; 255 frame_ticks = 0.0;
256 256
257 /* Open the audio device */ 257 /* Open the audio device */
258 audio_fd = SDL_OpenAudioPath (audiodev, sizeof (audiodev), OPEN_FLAGS, 0); 258 audio_fd = SDL_OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 0);
259 if (audio_fd < 0) { 259 if (audio_fd < 0) {
260 SDL_SetError ("Couldn't open %s: %s", audiodev, strerror (errno)); 260 SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno));
261 return -1; 261 return -1;
262 } 262 }
263 263
264 /* 264 /*
265 * We can't set the buffer size - just ask the device for the maximum 265 * We can't set the buffer size - just ask the device for the maximum
266 * that we can have. 266 * that we can have.
267 */ 267 */
268 if (ioctl (audio_fd, AUDIO_BUFFER, &paud_bufinfo) < 0) { 268 if (ioctl(audio_fd, AUDIO_BUFFER, &paud_bufinfo) < 0) {
269 SDL_SetError ("Couldn't get audio buffer information"); 269 SDL_SetError("Couldn't get audio buffer information");
270 return -1; 270 return -1;
271 } 271 }
272 272
273 mixbuf = NULL; 273 mixbuf = NULL;
274 274
327 paud_init.operation = PLAY; 327 paud_init.operation = PLAY;
328 paud_init.channels = spec->channels; 328 paud_init.channels = spec->channels;
329 329
330 /* Try for a closest match on audio format */ 330 /* Try for a closest match on audio format */
331 format = 0; 331 format = 0;
332 for (test_format = SDL_FirstAudioFormat (spec->format); 332 for (test_format = SDL_FirstAudioFormat(spec->format);
333 !format && test_format;) { 333 !format && test_format;) {
334 #ifdef DEBUG_AUDIO 334 #ifdef DEBUG_AUDIO
335 fprintf (stderr, "Trying format 0x%4.4x\n", test_format); 335 fprintf(stderr, "Trying format 0x%4.4x\n", test_format);
336 #endif 336 #endif
337 switch (test_format) { 337 switch (test_format) {
338 case AUDIO_U8: 338 case AUDIO_U8:
339 bytes_per_sample = 1; 339 bytes_per_sample = 1;
340 paud_init.bits_per_sample = 8; 340 paud_init.bits_per_sample = 8;
373 break; 373 break;
374 default: 374 default:
375 break; 375 break;
376 } 376 }
377 if (!format) { 377 if (!format) {
378 test_format = SDL_NextAudioFormat (); 378 test_format = SDL_NextAudioFormat();
379 } 379 }
380 } 380 }
381 if (format == 0) { 381 if (format == 0) {
382 #ifdef DEBUG_AUDIO 382 #ifdef DEBUG_AUDIO
383 fprintf (stderr, "Couldn't find any hardware audio formats\n"); 383 fprintf(stderr, "Couldn't find any hardware audio formats\n");
384 #endif 384 #endif
385 SDL_SetError ("Couldn't find any hardware audio formats"); 385 SDL_SetError("Couldn't find any hardware audio formats");
386 return -1; 386 return -1;
387 } 387 }
388 spec->format = test_format; 388 spec->format = test_format;
389 389
390 /* 390 /*
404 spec->samples = paud_bufinfo.write_buf_cap 404 spec->samples = paud_bufinfo.write_buf_cap
405 / bytes_per_sample / spec->channels / 2; 405 / bytes_per_sample / spec->channels / 2;
406 } 406 }
407 paud_init.bsize = bytes_per_sample * spec->channels; 407 paud_init.bsize = bytes_per_sample * spec->channels;
408 408
409 SDL_CalculateAudioSpec (spec); 409 SDL_CalculateAudioSpec(spec);
410 410
411 /* 411 /*
412 * The AIX paud device init can't modify the values of the audio_init 412 * The AIX paud device init can't modify the values of the audio_init
413 * structure that we pass to it. So we don't need any recalculation 413 * structure that we pass to it. So we don't need any recalculation
414 * of this stuff and no reinit call as in linux dsp and dma code. 414 * of this stuff and no reinit call as in linux dsp and dma code.
415 * 415 *
416 * /dev/paud supports all of the encoding formats, so we don't need 416 * /dev/paud supports all of the encoding formats, so we don't need
417 * to do anything like reopening the device, either. 417 * to do anything like reopening the device, either.
418 */ 418 */
419 if (ioctl (audio_fd, AUDIO_INIT, &paud_init) < 0) { 419 if (ioctl(audio_fd, AUDIO_INIT, &paud_init) < 0) {
420 switch (paud_init.rc) { 420 switch (paud_init.rc) {
421 case 1: 421 case 1:
422 SDL_SetError 422 SDL_SetError
423 ("Couldn't set audio format: DSP can't do play requests"); 423 ("Couldn't set audio format: DSP can't do play requests");
424 return -1; 424 return -1;
427 SDL_SetError 427 SDL_SetError
428 ("Couldn't set audio format: DSP can't do record requests"); 428 ("Couldn't set audio format: DSP can't do record requests");
429 return -1; 429 return -1;
430 break; 430 break;
431 case 4: 431 case 4:
432 SDL_SetError ("Couldn't set audio format: request was invalid"); 432 SDL_SetError("Couldn't set audio format: request was invalid");
433 return -1; 433 return -1;
434 break; 434 break;
435 case 5: 435 case 5:
436 SDL_SetError 436 SDL_SetError
437 ("Couldn't set audio format: conflict with open's flags"); 437 ("Couldn't set audio format: conflict with open's flags");
450 } 450 }
451 } 451 }
452 452
453 /* Allocate mixing buffer */ 453 /* Allocate mixing buffer */
454 mixlen = spec->size; 454 mixlen = spec->size;
455 mixbuf = (Uint8 *) SDL_AllocAudioMem (mixlen); 455 mixbuf = (Uint8 *) SDL_AllocAudioMem(mixlen);
456 if (mixbuf == NULL) { 456 if (mixbuf == NULL) {
457 return -1; 457 return -1;
458 } 458 }
459 SDL_memset (mixbuf, spec->silence, spec->size); 459 SDL_memset(mixbuf, spec->silence, spec->size);
460 460
461 /* 461 /*
462 * Set some paramters: full volume, first speaker that we can find. 462 * Set some paramters: full volume, first speaker that we can find.
463 * Ignore the other settings for now. 463 * Ignore the other settings for now.
464 */ 464 */
473 paud_change.bass = AUDIO_IGNORE; /* the new bass state */ 473 paud_change.bass = AUDIO_IGNORE; /* the new bass state */
474 paud_change.pitch = AUDIO_IGNORE; /* the new pitch state */ 474 paud_change.pitch = AUDIO_IGNORE; /* the new pitch state */
475 475
476 paud_control.ioctl_request = AUDIO_CHANGE; 476 paud_control.ioctl_request = AUDIO_CHANGE;
477 paud_control.request_info = (char *) &paud_change; 477 paud_control.request_info = (char *) &paud_change;
478 if (ioctl (audio_fd, AUDIO_CONTROL, &paud_control) < 0) { 478 if (ioctl(audio_fd, AUDIO_CONTROL, &paud_control) < 0) {
479 #ifdef DEBUG_AUDIO 479 #ifdef DEBUG_AUDIO
480 fprintf (stderr, "Can't change audio display settings\n"); 480 fprintf(stderr, "Can't change audio display settings\n");
481 #endif 481 #endif
482 } 482 }
483 483
484 /* 484 /*
485 * Tell the device to expect data. Actual start will wait for 485 * Tell the device to expect data. Actual start will wait for
486 * the first write() call. 486 * the first write() call.
487 */ 487 */
488 paud_control.ioctl_request = AUDIO_START; 488 paud_control.ioctl_request = AUDIO_START;
489 paud_control.position = 0; 489 paud_control.position = 0;
490 if (ioctl (audio_fd, AUDIO_CONTROL, &paud_control) < 0) { 490 if (ioctl(audio_fd, AUDIO_CONTROL, &paud_control) < 0) {
491 #ifdef DEBUG_AUDIO 491 #ifdef DEBUG_AUDIO
492 fprintf (stderr, "Can't start audio play\n"); 492 fprintf(stderr, "Can't start audio play\n");
493 #endif 493 #endif
494 SDL_SetError ("Can't start audio play"); 494 SDL_SetError("Can't start audio play");
495 return -1; 495 return -1;
496 } 496 }
497 497
498 /* Check to see if we need to use select() workaround */ 498 /* Check to see if we need to use select() workaround */
499 { 499 {
500 char *workaround; 500 char *workaround;
501 workaround = SDL_getenv ("SDL_DSP_NOSELECT"); 501 workaround = SDL_getenv("SDL_DSP_NOSELECT");
502 if (workaround) { 502 if (workaround) {
503 frame_ticks = (float) (spec->samples * 1000) / spec->freq; 503 frame_ticks = (float) (spec->samples * 1000) / spec->freq;
504 next_frame = SDL_GetTicks () + frame_ticks; 504 next_frame = SDL_GetTicks() + frame_ticks;
505 } 505 }
506 } 506 }
507 507
508 /* Get the parent process id (we're the parent of the audio thread) */ 508 /* Get the parent process id (we're the parent of the audio thread) */
509 parent = getpid (); 509 parent = getpid();
510 510
511 /* We're ready to rock and roll. :-) */ 511 /* We're ready to rock and roll. :-) */
512 return 0; 512 return 0;
513 } 513 }
514 514