Mercurial > sdl-ios-xcode
comparison src/audio/dma/SDL_dmaaudio.c @ 3817:103bbe13f5eb SDL-ryan-multiple-audio-device
Patched to compile.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Fri, 06 Oct 2006 04:49:48 +0000 |
parents | 9d070c1a45fa |
children | 66fb40445587 |
comparison
equal
deleted
inserted
replaced
3816:9d070c1a45fa | 3817:103bbe13f5eb |
---|---|
216 /* We successfully re-opened the audio */ | 216 /* We successfully re-opened the audio */ |
217 return (0); | 217 return (0); |
218 } | 218 } |
219 | 219 |
220 | 220 |
221 static void | |
222 DMA_CloseDevice(_THIS) | |
223 { | |
224 if (this->hidden != NULL) { | |
225 if (dma_buf != NULL) { | |
226 munmap(dma_buf, dma_len); | |
227 dma_buf = NULL; | |
228 } | |
229 if (audio_fd >= 0) { | |
230 close(audio_fd); | |
231 audio_fd = -1; | |
232 } | |
233 SDL_free(this->hidden); | |
234 this->hidden = NULL; | |
235 } | |
236 } | |
237 | |
221 | 238 |
222 static int | 239 static int |
223 open_device_internal(_THIS, const char *devname, int iscapture) | 240 DMA_OpenDevice(_THIS, const char *devname, int iscapture) |
224 { | 241 { |
225 const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT); | 242 const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT); |
226 int format; | 243 int format; |
227 int stereo; | 244 int stereo; |
228 int value; | 245 int value; |
247 SDL_OutOfMemory(); | 264 SDL_OutOfMemory(); |
248 return 0; | 265 return 0; |
249 } | 266 } |
250 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | 267 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); |
251 | 268 |
252 | |
253 /* Open the audio device */ | 269 /* Open the audio device */ |
254 audio_fd = open(devname, flags, 0); | 270 audio_fd = open(devname, flags, 0); |
255 if (audio_fd < 0) { | 271 if (audio_fd < 0) { |
272 DMA_CloseDevice(this); | |
256 SDL_SetError("Couldn't open %s: %s", devname, strerror(errno)); | 273 SDL_SetError("Couldn't open %s: %s", devname, strerror(errno)); |
257 return 0; | 274 return 0; |
258 } | 275 } |
259 dma_buf = NULL; | 276 dma_buf = NULL; |
260 ioctl(audio_fd, SNDCTL_DSP_RESET, 0); | 277 ioctl(audio_fd, SNDCTL_DSP_RESET, 0); |
261 | 278 |
262 /* Get a list of supported hardware formats */ | 279 /* Get a list of supported hardware formats */ |
263 if (ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &value) < 0) { | 280 if (ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &value) < 0) { |
281 DMA_CloseDevice(this); | |
264 SDL_SetError("Couldn't get audio format list"); | 282 SDL_SetError("Couldn't get audio format list"); |
265 return 0; | 283 return 0; |
266 } | 284 } |
267 | 285 |
268 /* Try for a closest match on audio format */ | 286 /* Try for a closest match on audio format */ |
310 if (!format) { | 328 if (!format) { |
311 test_format = SDL_NextAudioFormat(); | 329 test_format = SDL_NextAudioFormat(); |
312 } | 330 } |
313 } | 331 } |
314 if (format == 0) { | 332 if (format == 0) { |
333 DMA_CloseDevice(this); | |
315 SDL_SetError("Couldn't find any hardware audio formats"); | 334 SDL_SetError("Couldn't find any hardware audio formats"); |
316 return 0; | 335 return 0; |
317 } | 336 } |
318 this->spec.format = test_format; | 337 this->spec.format = test_format; |
319 | 338 |
320 /* Set the audio format */ | 339 /* Set the audio format */ |
321 value = format; | 340 value = format; |
322 if ((ioctl(audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) || (value != format)) { | 341 if ((ioctl(audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) || (value != format)) { |
342 DMA_CloseDevice(this); | |
323 SDL_SetError("Couldn't set audio format"); | 343 SDL_SetError("Couldn't set audio format"); |
324 return 0; | 344 return 0; |
325 } | 345 } |
326 | 346 |
327 /* Set mono or stereo audio (currently only two channels supported) */ | 347 /* Set mono or stereo audio (currently only two channels supported) */ |
336 /* Because some drivers don't allow setting the buffer size | 356 /* Because some drivers don't allow setting the buffer size |
337 after setting the format, we must re-open the audio device | 357 after setting the format, we must re-open the audio device |
338 once we know what format and channels are supported | 358 once we know what format and channels are supported |
339 */ | 359 */ |
340 if (DMA_ReopenAudio(this, devname, format, stereo) < 0) { | 360 if (DMA_ReopenAudio(this, devname, format, stereo) < 0) { |
361 DMA_CloseDevice(this); | |
341 /* Error is set by DMA_ReopenAudio() */ | 362 /* Error is set by DMA_ReopenAudio() */ |
342 return 0; | 363 return 0; |
343 } | 364 } |
344 | 365 |
345 /* Memory map the audio buffer */ | 366 /* Memory map the audio buffer */ |
346 if (ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info) < 0) { | 367 if (ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info) < 0) { |
368 DMA_CloseDevice(this); | |
347 SDL_SetError("Couldn't get OSPACE parameters"); | 369 SDL_SetError("Couldn't get OSPACE parameters"); |
348 return 0; | 370 return 0; |
349 } | 371 } |
350 this->spec.size = info.fragsize; | 372 this->spec.size = info.fragsize; |
351 this->spec.samples = this->spec.size / ((this->spec.format & 0xFF) / 8); | 373 this->spec.samples = this->spec.size / ((this->spec.format & 0xFF) / 8); |
353 num_buffers = info.fragstotal; | 375 num_buffers = info.fragstotal; |
354 dma_len = num_buffers * this->spec.size; | 376 dma_len = num_buffers * this->spec.size; |
355 dma_buf = (Uint8 *) mmap(NULL, dma_len, PROT_WRITE, MAP_SHARED, | 377 dma_buf = (Uint8 *) mmap(NULL, dma_len, PROT_WRITE, MAP_SHARED, |
356 audio_fd, 0); | 378 audio_fd, 0); |
357 if (dma_buf == MAP_FAILED) { | 379 if (dma_buf == MAP_FAILED) { |
380 DMA_CloseDevice(this); | |
358 SDL_SetError("DMA memory map failed"); | 381 SDL_SetError("DMA memory map failed"); |
359 dma_buf = NULL; | 382 dma_buf = NULL; |
360 return 0; | 383 return 0; |
361 } | 384 } |
362 SDL_memset(dma_buf, this->spec.silence, dma_len); | 385 SDL_memset(dma_buf, this->spec.silence, dma_len); |
374 /* Trigger audio playback */ | 397 /* Trigger audio playback */ |
375 value = 0; | 398 value = 0; |
376 ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &value); | 399 ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &value); |
377 value = PCM_ENABLE_OUTPUT; | 400 value = PCM_ENABLE_OUTPUT; |
378 if (ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &value) < 0) { | 401 if (ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &value) < 0) { |
402 DMA_CloseDevice(this); | |
379 SDL_SetError("Couldn't trigger audio output"); | 403 SDL_SetError("Couldn't trigger audio output"); |
380 return 0; | 404 return 0; |
381 } | 405 } |
382 | 406 |
383 /* Get the parent process id (we're the parent of the audio thread) */ | 407 /* Get the parent process id (we're the parent of the audio thread) */ |
384 parent = getpid(); | 408 parent = getpid(); |
385 | 409 |
386 /* We're ready to rock and roll. :-) */ | 410 /* We're ready to rock and roll. :-) */ |
387 return 1; | 411 return 1; |
388 } | 412 } |
389 | |
390 static int | |
391 DMA_OpenDevice(_THIS, const char *devname, int iscapture) | |
392 { | |
393 int retval = open_device_internal(this, devname, iscapture); | |
394 if (!retval) | |
395 DMA_CloseDevice(this); /* !!! FIXME: do this at higher level. */ | |
396 return retval; | |
397 } | |
398 | |
399 | |
400 | 413 |
401 | 414 |
402 /* This function waits until it is possible to write a full sound buffer */ | 415 /* This function waits until it is possible to write a full sound buffer */ |
403 static void | 416 static void |
404 DMA_WaitDevice(_THIS) | 417 DMA_WaitDevice(_THIS) |
503 playing = info.ptr / this->spec.size; | 516 playing = info.ptr / this->spec.size; |
504 filling = (playing + 1) % num_buffers; | 517 filling = (playing + 1) % num_buffers; |
505 return (dma_buf + (filling * this->spec.size)); | 518 return (dma_buf + (filling * this->spec.size)); |
506 } | 519 } |
507 | 520 |
508 static void | |
509 DMA_CloseDevice(_THIS) | |
510 { | |
511 if (this->hidden != NULL) { | |
512 if (dma_buf != NULL) { | |
513 munmap(dma_buf, dma_len); | |
514 dma_buf = NULL; | |
515 } | |
516 if (audio_fd >= 0) { | |
517 close(audio_fd); | |
518 audio_fd = -1; | |
519 } | |
520 SDL_free(this->hidden); | |
521 this->hidden = NULL; | |
522 } | |
523 } | |
524 | 521 |
525 static int | 522 static int |
526 DMA_Init(SDL_AudioDriverImpl *impl) | 523 DMA_Init(SDL_AudioDriverImpl *impl) |
527 { | 524 { |
528 /* Set the function pointers */ | 525 /* Set the function pointers */ |