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 */