comparison src/audio/bsd/SDL_bsdaudio.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
65 #else 65 #else
66 #define OPEN_FLAGS (O_WRONLY|O_NONBLOCK) 66 #define OPEN_FLAGS (O_WRONLY|O_NONBLOCK)
67 #endif 67 #endif
68 68
69 /* Audio driver functions */ 69 /* Audio driver functions */
70 static void OBSD_WaitAudio (_THIS); 70 static void OBSD_WaitAudio(_THIS);
71 static int OBSD_OpenAudio (_THIS, SDL_AudioSpec * spec); 71 static int OBSD_OpenAudio(_THIS, SDL_AudioSpec * spec);
72 static void OBSD_PlayAudio (_THIS); 72 static void OBSD_PlayAudio(_THIS);
73 static Uint8 *OBSD_GetAudioBuf (_THIS); 73 static Uint8 *OBSD_GetAudioBuf(_THIS);
74 static void OBSD_CloseAudio (_THIS); 74 static void OBSD_CloseAudio(_THIS);
75 75
76 #ifdef DEBUG_AUDIO 76 #ifdef DEBUG_AUDIO
77 static void OBSD_Status (_THIS); 77 static void OBSD_Status(_THIS);
78 #endif 78 #endif
79 79
80 /* Audio driver bootstrap functions */ 80 /* Audio driver bootstrap functions */
81 81
82 static int 82 static int
83 Audio_Available (void) 83 Audio_Available(void)
84 { 84 {
85 int fd; 85 int fd;
86 int available; 86 int available;
87 87
88 available = 0; 88 available = 0;
89 fd = SDL_OpenAudioPath (NULL, 0, OPEN_FLAGS, 0); 89 fd = SDL_OpenAudioPath(NULL, 0, OPEN_FLAGS, 0);
90 if (fd >= 0) { 90 if (fd >= 0) {
91 available = 1; 91 available = 1;
92 close (fd); 92 close(fd);
93 } 93 }
94 return (available); 94 return (available);
95 } 95 }
96 96
97 static void 97 static void
98 Audio_DeleteDevice (SDL_AudioDevice * device) 98 Audio_DeleteDevice(SDL_AudioDevice * device)
99 { 99 {
100 SDL_free (device->hidden); 100 SDL_free(device->hidden);
101 SDL_free (device); 101 SDL_free(device);
102 } 102 }
103 103
104 static SDL_AudioDevice * 104 static SDL_AudioDevice *
105 Audio_CreateDevice (int devindex) 105 Audio_CreateDevice(int devindex)
106 { 106 {
107 SDL_AudioDevice *this; 107 SDL_AudioDevice *this;
108 108
109 /* Initialize all variables that we clean on shutdown */ 109 /* Initialize all variables that we clean on shutdown */
110 this = (SDL_AudioDevice *) SDL_malloc (sizeof (SDL_AudioDevice)); 110 this = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice));
111 if (this) { 111 if (this) {
112 SDL_memset (this, 0, (sizeof *this)); 112 SDL_memset(this, 0, (sizeof *this));
113 this->hidden = (struct SDL_PrivateAudioData *) 113 this->hidden = (struct SDL_PrivateAudioData *)
114 SDL_malloc ((sizeof *this->hidden)); 114 SDL_malloc((sizeof *this->hidden));
115 } 115 }
116 if ((this == NULL) || (this->hidden == NULL)) { 116 if ((this == NULL) || (this->hidden == NULL)) {
117 SDL_OutOfMemory (); 117 SDL_OutOfMemory();
118 if (this) 118 if (this)
119 SDL_free (this); 119 SDL_free(this);
120 return (0); 120 return (0);
121 } 121 }
122 SDL_memset (this->hidden, 0, (sizeof *this->hidden)); 122 SDL_memset(this->hidden, 0, (sizeof *this->hidden));
123 audio_fd = -1; 123 audio_fd = -1;
124 124
125 /* Set the function pointers */ 125 /* Set the function pointers */
126 this->OpenAudio = OBSD_OpenAudio; 126 this->OpenAudio = OBSD_OpenAudio;
127 this->WaitAudio = OBSD_WaitAudio; 127 this->WaitAudio = OBSD_WaitAudio;
139 Audio_Available, Audio_CreateDevice 139 Audio_Available, Audio_CreateDevice
140 }; 140 };
141 141
142 /* This function waits until it is possible to write a full sound buffer */ 142 /* This function waits until it is possible to write a full sound buffer */
143 static void 143 static void
144 OBSD_WaitAudio (_THIS) 144 OBSD_WaitAudio(_THIS)
145 { 145 {
146 #ifndef USE_BLOCKING_WRITES /* Not necessary when using blocking writes */ 146 #ifndef USE_BLOCKING_WRITES /* Not necessary when using blocking writes */
147 /* See if we need to use timed audio synchronization */ 147 /* See if we need to use timed audio synchronization */
148 if (frame_ticks) { 148 if (frame_ticks) {
149 /* Use timer for general audio synchronization */ 149 /* Use timer for general audio synchronization */
150 Sint32 ticks; 150 Sint32 ticks;
151 151
152 ticks = ((Sint32) (next_frame - SDL_GetTicks ())) - FUDGE_TICKS; 152 ticks = ((Sint32) (next_frame - SDL_GetTicks())) - FUDGE_TICKS;
153 if (ticks > 0) { 153 if (ticks > 0) {
154 SDL_Delay (ticks); 154 SDL_Delay(ticks);
155 } 155 }
156 } else { 156 } else {
157 /* Use select() for audio synchronization */ 157 /* Use select() for audio synchronization */
158 fd_set fdset; 158 fd_set fdset;
159 struct timeval timeout; 159 struct timeval timeout;
160 160
161 FD_ZERO (&fdset); 161 FD_ZERO(&fdset);
162 FD_SET (audio_fd, &fdset); 162 FD_SET(audio_fd, &fdset);
163 timeout.tv_sec = 10; 163 timeout.tv_sec = 10;
164 timeout.tv_usec = 0; 164 timeout.tv_usec = 0;
165 #ifdef DEBUG_AUDIO 165 #ifdef DEBUG_AUDIO
166 fprintf (stderr, "Waiting for audio to get ready\n"); 166 fprintf(stderr, "Waiting for audio to get ready\n");
167 #endif 167 #endif
168 if (select (audio_fd + 1, NULL, &fdset, NULL, &timeout) <= 0) { 168 if (select(audio_fd + 1, NULL, &fdset, NULL, &timeout) <= 0) {
169 const char *message = 169 const char *message =
170 "Audio timeout - buggy audio driver? (disabled)"; 170 "Audio timeout - buggy audio driver? (disabled)";
171 /* In general we should never print to the screen, 171 /* In general we should never print to the screen,
172 but in this case we have no other way of letting 172 but in this case we have no other way of letting
173 the user know what happened. 173 the user know what happened.
174 */ 174 */
175 fprintf (stderr, "SDL: %s\n", message); 175 fprintf(stderr, "SDL: %s\n", message);
176 this->enabled = 0; 176 this->enabled = 0;
177 /* Don't try to close - may hang */ 177 /* Don't try to close - may hang */
178 audio_fd = -1; 178 audio_fd = -1;
179 #ifdef DEBUG_AUDIO 179 #ifdef DEBUG_AUDIO
180 fprintf (stderr, "Done disabling audio\n"); 180 fprintf(stderr, "Done disabling audio\n");
181 #endif 181 #endif
182 } 182 }
183 #ifdef DEBUG_AUDIO 183 #ifdef DEBUG_AUDIO
184 fprintf (stderr, "Ready!\n"); 184 fprintf(stderr, "Ready!\n");
185 #endif 185 #endif
186 } 186 }
187 #endif /* !USE_BLOCKING_WRITES */ 187 #endif /* !USE_BLOCKING_WRITES */
188 } 188 }
189 189
190 static void 190 static void
191 OBSD_PlayAudio (_THIS) 191 OBSD_PlayAudio(_THIS)
192 { 192 {
193 int written, p = 0; 193 int written, p = 0;
194 194
195 /* Write the audio data, checking for EAGAIN on broken audio drivers */ 195 /* Write the audio data, checking for EAGAIN on broken audio drivers */
196 do { 196 do {
197 written = write (audio_fd, &mixbuf[p], mixlen - p); 197 written = write(audio_fd, &mixbuf[p], mixlen - p);
198 if (written > 0) 198 if (written > 0)
199 p += written; 199 p += written;
200 if (written == -1 && errno != 0 && errno != EAGAIN && errno != EINTR) { 200 if (written == -1 && errno != 0 && errno != EAGAIN && errno != EINTR) {
201 /* Non recoverable error has occurred. It should be reported!!! */ 201 /* Non recoverable error has occurred. It should be reported!!! */
202 perror ("audio"); 202 perror("audio");
203 break; 203 break;
204 } 204 }
205 205
206 if (p < written 206 if (p < written
207 || ((written < 0) && ((errno == 0) || (errno == EAGAIN)))) { 207 || ((written < 0) && ((errno == 0) || (errno == EAGAIN)))) {
208 SDL_Delay (1); /* Let a little CPU time go by */ 208 SDL_Delay(1); /* Let a little CPU time go by */
209 } 209 }
210 } 210 }
211 while (p < written); 211 while (p < written);
212 212
213 /* If timer synchronization is enabled, set the next write frame */ 213 /* If timer synchronization is enabled, set the next write frame */
218 /* If we couldn't write, assume fatal error for now */ 218 /* If we couldn't write, assume fatal error for now */
219 if (written < 0) { 219 if (written < 0) {
220 this->enabled = 0; 220 this->enabled = 0;
221 } 221 }
222 #ifdef DEBUG_AUDIO 222 #ifdef DEBUG_AUDIO
223 fprintf (stderr, "Wrote %d bytes of audio data\n", written); 223 fprintf(stderr, "Wrote %d bytes of audio data\n", written);
224 #endif 224 #endif
225 } 225 }
226 226
227 static Uint8 * 227 static Uint8 *
228 OBSD_GetAudioBuf (_THIS) 228 OBSD_GetAudioBuf(_THIS)
229 { 229 {
230 return (mixbuf); 230 return (mixbuf);
231 } 231 }
232 232
233 static void 233 static void
234 OBSD_CloseAudio (_THIS) 234 OBSD_CloseAudio(_THIS)
235 { 235 {
236 if (mixbuf != NULL) { 236 if (mixbuf != NULL) {
237 SDL_FreeAudioMem (mixbuf); 237 SDL_FreeAudioMem(mixbuf);
238 mixbuf = NULL; 238 mixbuf = NULL;
239 } 239 }
240 if (audio_fd >= 0) { 240 if (audio_fd >= 0) {
241 close (audio_fd); 241 close(audio_fd);
242 audio_fd = -1; 242 audio_fd = -1;
243 } 243 }
244 } 244 }
245 245
246 #ifdef DEBUG_AUDIO 246 #ifdef DEBUG_AUDIO
247 void 247 void
248 OBSD_Status (_THIS) 248 OBSD_Status(_THIS)
249 { 249 {
250 audio_info_t info; 250 audio_info_t info;
251 251
252 if (ioctl (audio_fd, AUDIO_GETINFO, &info) < 0) { 252 if (ioctl(audio_fd, AUDIO_GETINFO, &info) < 0) {
253 fprintf (stderr, "AUDIO_GETINFO failed.\n"); 253 fprintf(stderr, "AUDIO_GETINFO failed.\n");
254 return; 254 return;
255 } 255 }
256 256
257 fprintf (stderr, "\n" 257 fprintf(stderr, "\n"
258 "[play/record info]\n" 258 "[play/record info]\n"
259 "buffer size : %d bytes\n" 259 "buffer size : %d bytes\n"
260 "sample rate : %i Hz\n" 260 "sample rate : %i Hz\n"
261 "channels : %i\n" 261 "channels : %i\n"
262 "precision : %i-bit\n" 262 "precision : %i-bit\n"
263 "encoding : 0x%x\n" 263 "encoding : 0x%x\n"
264 "seek : %i\n" 264 "seek : %i\n"
265 "sample count : %i\n" 265 "sample count : %i\n"
266 "EOF count : %i\n" 266 "EOF count : %i\n"
267 "paused : %s\n" 267 "paused : %s\n"
268 "error occured : %s\n" 268 "error occured : %s\n"
269 "waiting : %s\n" 269 "waiting : %s\n"
270 "active : %s\n" 270 "active : %s\n"
271 "", 271 "",
272 info. 272 info.
273 play. 273 play.
274 buffer_size, 274 buffer_size,
275 info. 275 info.
276 play. 276 play.
277 sample_rate, 277 sample_rate,
278 info. 278 info.
279 play. 279 play.
280 channels, 280 channels,
281 info. 281 info.
282 play. 282 play.
283 precision, 283 precision,
284 info. 284 info.
285 play. 285 play.
286 encoding, 286 encoding,
287 info. 287 info.
288 play. 288 play.
289 seek, 289 seek,
290 info. 290 info.
291 play. 291 play.
292 samples, 292 samples,
293 info. 293 info.
294 play. 294 play.
295 eof, 295 eof,
296 info. 296 info.
297 play. 297 play.
298 pause 298 pause
299 ? 299 ?
300 "yes" 300 "yes"
301 : 301 :
302 "no", 302 "no",
303 info. 303 info.
304 play. 304 play.
305 error 305 error
306 ? 306 ?
307 "yes" 307 "yes"
308 : 308 :
309 "no", 309 "no",
310 info. 310 info.
311 play.waiting ? "yes" : "no", info.play.active ? "yes" : "no"); 311 play.waiting ? "yes" : "no", info.play.active ? "yes" : "no");
312 312
313 fprintf (stderr, "\n" 313 fprintf(stderr, "\n"
314 "[audio info]\n" 314 "[audio info]\n"
315 "monitor_gain : %i\n" 315 "monitor_gain : %i\n"
316 "hw block size : %d bytes\n" 316 "hw block size : %d bytes\n"
317 "hi watermark : %i\n" 317 "hi watermark : %i\n"
318 "lo watermark : %i\n" 318 "lo watermark : %i\n"
319 "audio mode : %s\n" 319 "audio mode : %s\n"
320 "", 320 "",
321 info.monitor_gain, 321 info.monitor_gain,
322 info.blocksize, 322 info.blocksize,
323 info.hiwat, info.lowat, 323 info.hiwat, info.lowat,
324 (info.mode == AUMODE_PLAY) ? "PLAY" 324 (info.mode == AUMODE_PLAY) ? "PLAY"
325 : (info.mode = AUMODE_RECORD) ? "RECORD" 325 : (info.mode = AUMODE_RECORD) ? "RECORD"
326 : (info.mode == AUMODE_PLAY_ALL ? "PLAY_ALL" : "?")); 326 : (info.mode == AUMODE_PLAY_ALL ? "PLAY_ALL" : "?"));
327 } 327 }
328 #endif /* DEBUG_AUDIO */ 328 #endif /* DEBUG_AUDIO */
329 329
330 static int 330 static int
331 OBSD_OpenAudio (_THIS, SDL_AudioSpec * spec) 331 OBSD_OpenAudio(_THIS, SDL_AudioSpec * spec)
332 { 332 {
333 char audiodev[64]; 333 char audiodev[64];
334 Uint16 format; 334 Uint16 format;
335 audio_info_t info; 335 audio_info_t info;
336 336
337 AUDIO_INITINFO (&info); 337 AUDIO_INITINFO(&info);
338 338
339 /* Calculate the final parameters for this audio specification */ 339 /* Calculate the final parameters for this audio specification */
340 SDL_CalculateAudioSpec (spec); 340 SDL_CalculateAudioSpec(spec);
341 341
342 #ifdef USE_TIMER_SYNC 342 #ifdef USE_TIMER_SYNC
343 frame_ticks = 0.0; 343 frame_ticks = 0.0;
344 #endif 344 #endif
345 345
346 /* Open the audio device */ 346 /* Open the audio device */
347 audio_fd = SDL_OpenAudioPath (audiodev, sizeof (audiodev), OPEN_FLAGS, 0); 347 audio_fd = SDL_OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 0);
348 if (audio_fd < 0) { 348 if (audio_fd < 0) {
349 SDL_SetError ("Couldn't open %s: %s", audiodev, strerror (errno)); 349 SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno));
350 return (-1); 350 return (-1);
351 } 351 }
352 352
353 /* Set to play mode */ 353 /* Set to play mode */
354 info.mode = AUMODE_PLAY; 354 info.mode = AUMODE_PLAY;
355 if (ioctl (audio_fd, AUDIO_SETINFO, &info) < 0) { 355 if (ioctl(audio_fd, AUDIO_SETINFO, &info) < 0) {
356 SDL_SetError ("Couldn't put device into play mode"); 356 SDL_SetError("Couldn't put device into play mode");
357 return (-1); 357 return (-1);
358 } 358 }
359 359
360 mixbuf = NULL; 360 mixbuf = NULL;
361 AUDIO_INITINFO (&info); 361 AUDIO_INITINFO(&info);
362 for (format = SDL_FirstAudioFormat (spec->format); 362 for (format = SDL_FirstAudioFormat(spec->format);
363 format; format = SDL_NextAudioFormat ()) { 363 format; format = SDL_NextAudioFormat()) {
364 switch (format) { 364 switch (format) {
365 case AUDIO_U8: 365 case AUDIO_U8:
366 info.play.encoding = AUDIO_ENCODING_ULINEAR; 366 info.play.encoding = AUDIO_ENCODING_ULINEAR;
367 info.play.precision = 8; 367 info.play.precision = 8;
368 break; 368 break;
387 info.play.precision = 16; 387 info.play.precision = 16;
388 break; 388 break;
389 default: 389 default:
390 continue; 390 continue;
391 } 391 }
392 if (ioctl (audio_fd, AUDIO_SETINFO, &info) == 0) 392 if (ioctl(audio_fd, AUDIO_SETINFO, &info) == 0)
393 break; 393 break;
394 } 394 }
395 395
396 if (!format) { 396 if (!format) {
397 SDL_SetError ("No supported encoding for 0x%x", spec->format); 397 SDL_SetError("No supported encoding for 0x%x", spec->format);
398 return (-1); 398 return (-1);
399 } 399 }
400 400
401 spec->format = format; 401 spec->format = format;
402 402
403 AUDIO_INITINFO (&info); 403 AUDIO_INITINFO(&info);
404 info.play.channels = spec->channels; 404 info.play.channels = spec->channels;
405 if (ioctl (audio_fd, AUDIO_SETINFO, &info) == -1) 405 if (ioctl(audio_fd, AUDIO_SETINFO, &info) == -1)
406 spec->channels = 1; 406 spec->channels = 1;
407 AUDIO_INITINFO (&info); 407 AUDIO_INITINFO(&info);
408 info.play.sample_rate = spec->freq; 408 info.play.sample_rate = spec->freq;
409 info.blocksize = spec->size; 409 info.blocksize = spec->size;
410 info.hiwat = 5; 410 info.hiwat = 5;
411 info.lowat = 3; 411 info.lowat = 3;
412 (void) ioctl (audio_fd, AUDIO_SETINFO, &info); 412 (void) ioctl(audio_fd, AUDIO_SETINFO, &info);
413 (void) ioctl (audio_fd, AUDIO_GETINFO, &info); 413 (void) ioctl(audio_fd, AUDIO_GETINFO, &info);
414 spec->freq = info.play.sample_rate; 414 spec->freq = info.play.sample_rate;
415 /* Allocate mixing buffer */ 415 /* Allocate mixing buffer */
416 mixlen = spec->size; 416 mixlen = spec->size;
417 mixbuf = (Uint8 *) SDL_AllocAudioMem (mixlen); 417 mixbuf = (Uint8 *) SDL_AllocAudioMem(mixlen);
418 if (mixbuf == NULL) { 418 if (mixbuf == NULL) {
419 return (-1); 419 return (-1);
420 } 420 }
421 SDL_memset (mixbuf, spec->silence, spec->size); 421 SDL_memset(mixbuf, spec->silence, spec->size);
422 422
423 /* Get the parent process id (we're the parent of the audio thread) */ 423 /* Get the parent process id (we're the parent of the audio thread) */
424 parent = getpid (); 424 parent = getpid();
425 425
426 #ifdef DEBUG_AUDIO 426 #ifdef DEBUG_AUDIO
427 OBSD_Status (this); 427 OBSD_Status(this);
428 #endif 428 #endif
429 429
430 /* We're ready to rock and roll. :-) */ 430 /* We're ready to rock and roll. :-) */
431 return (0); 431 return (0);
432 } 432 }