Mercurial > mplayer.hg
comparison libao2/ao_alsa1x.c @ 11775:66e491c35dc8
ALSA 1.x audio out driver
author | henry |
---|---|
date | Sun, 11 Jan 2004 17:07:32 +0000 |
parents | 129caea8bebc |
children | b9046e5093cc |
comparison
equal
deleted
inserted
replaced
11774:28b52087c48d | 11775:66e491c35dc8 |
---|---|
1 /* | 1 /* |
2 ao_alsa9 - ALSA-0.9.x output plugin for MPlayer | 2 ao_alsa1x - ALSA-1.x output plugin for MPlayer |
3 | 3 |
4 (C) Alex Beregszaszi | 4 (C) Alex Beregszaszi |
5 | 5 |
6 modified for real alsa-0.9.0-support by Joy Winter <joy@pingfm.org> | 6 modified for real alsa-0.9.0-support by Joy Winter <joy@pingfm.org> |
7 additional AC3 passthrough support by Andy Lo A Foe <andy@alsaplayer.org> | 7 additional AC3 passthrough support by Andy Lo A Foe <andy@alsaplayer.org> |
8 08/22/2002 iec958-init rewritten and merged with common init, joy | 8 08/22/2002 iec958-init rewritten and merged with common init, joy |
9 | |
10 Trivial port to ALSA 1.x API by Jindrich Makovicka | |
9 | 11 |
10 Any bugreports regarding to this driver are welcome. | 12 Any bugreports regarding to this driver are welcome. |
11 */ | 13 */ |
12 | 14 |
13 #include <errno.h> | 15 #include <errno.h> |
34 | 36 |
35 extern int verbose; | 37 extern int verbose; |
36 | 38 |
37 static ao_info_t info = | 39 static ao_info_t info = |
38 { | 40 { |
39 "ALSA-0.9.x audio output", | 41 "ALSA-1.x audio output", |
40 "alsa9", | 42 "alsa1x", |
41 "Alex Beregszaszi, Joy Winter <joy@pingfm.org>", | 43 "Alex Beregszaszi, Joy Winter <joy@pingfm.org>", |
42 "under developement" | 44 "under developement" |
43 }; | 45 }; |
44 | 46 |
45 LIBAO_EXTERN(alsa9) | 47 LIBAO_EXTERN(alsa1x) |
46 | 48 |
47 | 49 |
48 static snd_pcm_t *alsa_handler; | 50 static snd_pcm_t *alsa_handler; |
49 static snd_pcm_format_t alsa_format; | 51 static snd_pcm_format_t alsa_format; |
50 static snd_pcm_hw_params_t *alsa_hwparams; | 52 static snd_pcm_hw_params_t *alsa_hwparams; |
56 static int alsa_fragsize = 4096; | 58 static int alsa_fragsize = 4096; |
57 /* 16 sets buffersize to 16 * chunksize is as default 1024 | 59 /* 16 sets buffersize to 16 * chunksize is as default 1024 |
58 * which seems to be good avarge for most situations | 60 * which seems to be good avarge for most situations |
59 * so buffersize is 16384 frames by default */ | 61 * so buffersize is 16384 frames by default */ |
60 static int alsa_fragcount = 16; | 62 static int alsa_fragcount = 16; |
61 static int chunk_size = 1024; //is alsa_fragsize / 4 | 63 static snd_pcm_uframes_t chunk_size = 1024; //is alsa_fragsize / 4 |
62 | 64 |
63 #define MIN_CHUNK_SIZE 1024 | 65 #define MIN_CHUNK_SIZE 1024 |
64 | 66 |
65 static size_t bits_per_sample, bytes_per_sample, bits_per_frame; | 67 static size_t bits_per_sample, bytes_per_sample, bits_per_frame; |
66 static size_t chunk_bytes; | 68 static size_t chunk_bytes; |
75 | 77 |
76 #define ALSA_DEVICE_SIZE 48 | 78 #define ALSA_DEVICE_SIZE 48 |
77 | 79 |
78 #undef BUFFERTIME | 80 #undef BUFFERTIME |
79 #define SET_CHUNKSIZE | 81 #define SET_CHUNKSIZE |
82 //#define BUFFERTIME | |
83 //#undef SET_CHUNKSIZE | |
80 #undef USE_POLL | 84 #undef USE_POLL |
81 | 85 |
82 | 86 |
83 /* to set/get/query special features/parameters */ | 87 /* to set/get/query special features/parameters */ |
84 static int control(int cmd, void *arg) | 88 static int control(int cmd, void *arg) |
95 int err; | 99 int err; |
96 snd_mixer_t *handle; | 100 snd_mixer_t *handle; |
97 snd_mixer_elem_t *elem; | 101 snd_mixer_elem_t *elem; |
98 snd_mixer_selem_id_t *sid; | 102 snd_mixer_selem_id_t *sid; |
99 | 103 |
100 static const char *mix_name = NULL; | 104 static char *mix_name = NULL; |
101 static char *card = NULL; | 105 static char *card = NULL; |
102 | 106 |
103 long pmin, pmax; | 107 long pmin, pmax; |
104 long get_vol, set_vol; | 108 long get_vol, set_vol; |
105 float calc_vol, diff, f_multi; | 109 float calc_vol, diff, f_multi; |
209 */ | 213 */ |
210 static int init(int rate_hz, int channels, int format, int flags) | 214 static int init(int rate_hz, int channels, int format, int flags) |
211 { | 215 { |
212 int err; | 216 int err; |
213 int cards = -1; | 217 int cards = -1; |
214 int period_val; | 218 int dir; |
219 snd_pcm_uframes_t bufsize; | |
215 snd_pcm_info_t *alsa_info; | 220 snd_pcm_info_t *alsa_info; |
216 char *str_block_mode; | 221 char *str_block_mode; |
217 int device_set = 0; | 222 int device_set = 0; |
218 | 223 |
219 printf("alsa-init: requested format: %d Hz, %d channels, %s\n", rate_hz, | 224 printf("alsa-init: requested format: %d Hz, %d channels, %s\n", rate_hz, |
356 case 6: | 361 case 6: |
357 strcpy(devstr, "surround51"); | 362 strcpy(devstr, "surround51"); |
358 alsa_device = devstr; | 363 alsa_device = devstr; |
359 break; | 364 break; |
360 default: | 365 default: |
366 break; | |
361 } | 367 } |
362 } | 368 } |
363 | 369 |
364 | 370 |
365 /* switch for spdif | 371 /* switch for spdif |
448 } else if (strcmp(alsa_device, "help") == 0) { | 454 } else if (strcmp(alsa_device, "help") == 0) { |
449 printf("alsa-help: available options are:\n"); | 455 printf("alsa-help: available options are:\n"); |
450 printf(" mmap: sets mmap-mode\n"); | 456 printf(" mmap: sets mmap-mode\n"); |
451 printf(" noblock: sets noblock-mode\n"); | 457 printf(" noblock: sets noblock-mode\n"); |
452 printf(" device-name: sets device name (change comma to point)\n"); | 458 printf(" device-name: sets device name (change comma to point)\n"); |
453 printf(" example -ao alsa9:mmap:noblock:hw:0.3 sets noblock-mode,\n"); | 459 printf(" example -ao alsa1x:mmap:noblock:hw:0.3 sets noblock-mode,\n"); |
454 printf(" mmap-mode and the device-name as first card fourth device\n"); | 460 printf(" mmap-mode and the device-name as first card fourth device\n"); |
455 return(0); | 461 return(0); |
456 } else { | 462 } else { |
457 printf("alsa-init: soundcard set to %s\n", alsa_device); | 463 printf("alsa-init: soundcard set to %s\n", alsa_device); |
458 } | 464 } |
536 | 542 |
537 if ((err = snd_pcm_nonblock(alsa_handler, set_block_mode)) < 0) { | 543 if ((err = snd_pcm_nonblock(alsa_handler, set_block_mode)) < 0) { |
538 printf("alsa-init: error set block-mode %s\n", snd_strerror(err)); | 544 printf("alsa-init: error set block-mode %s\n", snd_strerror(err)); |
539 } | 545 } |
540 else if (verbose>0) { | 546 else if (verbose>0) { |
541 printf("alsa-init: pcm opend in %s\n", str_block_mode); | 547 printf("alsa-init: pcm opened in %s\n", str_block_mode); |
542 } | 548 } |
543 | 549 |
544 snd_pcm_hw_params_alloca(&alsa_hwparams); | 550 snd_pcm_hw_params_alloca(&alsa_hwparams); |
545 snd_pcm_sw_params_alloca(&alsa_swparams); | 551 snd_pcm_sw_params_alloca(&alsa_swparams); |
546 | 552 |
597 printf("alsa-init: unable to set channels: %s\n", | 603 printf("alsa-init: unable to set channels: %s\n", |
598 snd_strerror(err)); | 604 snd_strerror(err)); |
599 return(0); | 605 return(0); |
600 } | 606 } |
601 | 607 |
602 if ((err = snd_pcm_hw_params_set_rate_near(alsa_handler, alsa_hwparams, ao_data.samplerate, 0)) < 0) | 608 dir = 0; |
609 if ((err = snd_pcm_hw_params_set_rate_near(alsa_handler, alsa_hwparams, &ao_data.samplerate, &dir)) < 0) | |
603 { | 610 { |
604 printf("alsa-init: unable to set samplerate-2: %s\n", | 611 printf("alsa-init: unable to set samplerate-2: %s\n", |
605 snd_strerror(err)); | 612 snd_strerror(err)); |
606 return(0); | 613 return(0); |
607 } | 614 } |
608 | 615 |
609 #ifdef BUFFERTIME | 616 #ifdef BUFFERTIME |
610 { | 617 { |
611 int alsa_buffer_time = 500000; /* original 60 */ | 618 int alsa_buffer_time = 500000; /* original 60 */ |
612 | 619 int alsa_period_time; |
613 if ((err = snd_pcm_hw_params_set_buffer_time_near(alsa_handler, alsa_hwparams, alsa_buffer_time, 0)) < 0) | 620 |
621 dir = 0; | |
622 if ((err = snd_pcm_hw_params_set_buffer_time_near(alsa_handler, alsa_hwparams, &alsa_buffer_time, &dir)) < 0) | |
614 { | 623 { |
615 printf("alsa-init: unable to set buffer time near: %s\n", | 624 printf("alsa-init: unable to set buffer time near: %s\n", |
616 snd_strerror(err)); | 625 snd_strerror(err)); |
617 return(0); | 626 return(0); |
618 } else | 627 } |
619 alsa_buffer_time = err; | 628 |
620 | 629 alsa_period_time = alsa_buffer_time/4; ; |
621 if ((err = snd_pcm_hw_params_set_period_time_near(alsa_handler, alsa_hwparams, alsa_buffer_time/4, 0)) < 0) | 630 |
631 dir = 0; | |
632 if ((err = snd_pcm_hw_params_set_period_time_near(alsa_handler, alsa_hwparams, alsa_period_time, &dir)) < 0) | |
622 /* original: alsa_buffer_time/ao_data.bps */ | 633 /* original: alsa_buffer_time/ao_data.bps */ |
623 { | 634 { |
624 printf("alsa-init: unable to set period time: %s\n", | 635 printf("alsa-init: unable to set period time: %s\n", |
625 snd_strerror(err)); | 636 snd_strerror(err)); |
626 return(0); | 637 return(0); |
627 } | 638 } |
628 if (verbose>0) | 639 if (verbose>0) |
629 printf("alsa-init: buffer_time: %d, period_time :%d\n",alsa_buffer_time, err); | 640 printf("alsa-init: buffer_time: %d, period_time :%d\n",alsa_buffer_time, alsa_period_time); |
630 } | 641 } |
631 #endif | 642 #endif |
632 | 643 |
633 #ifdef SET_CHUNKSIZE | 644 #ifdef SET_CHUNKSIZE |
634 { | 645 { |
635 //set chunksize | 646 //set chunksize |
636 if ((err = snd_pcm_hw_params_set_period_size(alsa_handler, alsa_hwparams, chunk_size, 0)) < 0) | 647 dir = 0; |
648 if ((err = snd_pcm_hw_params_set_period_size_near(alsa_handler, alsa_hwparams, &chunk_size, &dir)) < 0) | |
637 { | 649 { |
638 printf("alsa-init: unable to set periodsize: %s\n", snd_strerror(err)); | 650 printf("alsa-init: unable to set periodsize: %s\n", snd_strerror(err)); |
639 return(0); | 651 return(0); |
640 } | 652 } |
641 else if (verbose>0) { | 653 else if (verbose>0) { |
642 printf("alsa-init: chunksize set to %i\n", chunk_size); | 654 printf("alsa-init: chunksize set to %i\n", chunk_size); |
643 } | 655 } |
644 | 656 |
645 //set period_count | 657 dir = 0; |
646 if ((period_val = snd_pcm_hw_params_get_periods_max(alsa_hwparams, 0)) < alsa_fragcount) { | 658 if ((err = snd_pcm_hw_params_set_periods_near(alsa_handler, alsa_hwparams, &alsa_fragcount, &dir)) < 0) { |
647 alsa_fragcount = period_val; | 659 printf("alsa-init: unable to set periods: %s\n", snd_strerror(err)); |
648 } | 660 } |
649 | 661 |
650 if (verbose>0) | 662 if (verbose>0) |
651 printf("alsa-init: current val=%i, fragcount=%i\n", period_val, alsa_fragcount); | 663 printf("alsa-init: fragcount=%i\n", alsa_fragcount); |
652 | |
653 if ((err = snd_pcm_hw_params_set_periods(alsa_handler, alsa_hwparams, alsa_fragcount, 0)) < 0) { | |
654 printf("alsa-init: unable to set periods: %s\n", snd_strerror(err)); | |
655 } | |
656 } | 664 } |
657 #endif | 665 #endif |
658 | 666 |
659 /* finally install hardware parameters */ | 667 /* finally install hardware parameters */ |
660 if ((err = snd_pcm_hw_params(alsa_handler, alsa_hwparams)) < 0) | 668 if ((err = snd_pcm_hw_params(alsa_handler, alsa_hwparams)) < 0) |
665 } | 673 } |
666 // end setting hw-params | 674 // end setting hw-params |
667 | 675 |
668 | 676 |
669 // gets buffersize for control | 677 // gets buffersize for control |
670 if ((err = snd_pcm_hw_params_get_buffer_size(alsa_hwparams)) < 0) | 678 if ((err = snd_pcm_hw_params_get_buffer_size(alsa_hwparams, &bufsize)) < 0) |
671 { | 679 { |
672 printf("alsa-init: unable to get buffersize: %s\n", snd_strerror(err)); | 680 printf("alsa-init: unable to get buffersize: %s\n", snd_strerror(err)); |
673 return(0); | 681 return(0); |
674 } | 682 } |
675 else { | 683 else { |
676 ao_data.buffersize = err * bytes_per_sample; | 684 ao_data.buffersize = bufsize * bytes_per_sample; |
677 if (verbose>0) | 685 if (verbose>0) |
678 printf("alsa-init: got buffersize=%i\n", ao_data.buffersize); | 686 printf("alsa-init: got buffersize=%i\n", ao_data.buffersize); |
679 } | 687 } |
680 | 688 |
681 // setting sw-params (only avail-min) if noblocking mode was choosed | 689 // setting sw-params (only avail-min) if noblocking mode was choosed |
715 { | 723 { |
716 printf("alsa-init: pcm prepare error: %s\n", snd_strerror(err)); | 724 printf("alsa-init: pcm prepare error: %s\n", snd_strerror(err)); |
717 return(0); | 725 return(0); |
718 } | 726 } |
719 | 727 |
720 printf("alsa9: %d Hz/%d channels/%d bpf/%d bytes buffer/%s\n", | 728 printf("alsa1x: %d Hz/%d channels/%d bpf/%d bytes buffer/%s\n", |
721 ao_data.samplerate, ao_data.channels, bytes_per_sample, ao_data.buffersize, | 729 ao_data.samplerate, ao_data.channels, bytes_per_sample, ao_data.buffersize, |
722 snd_pcm_format_description(alsa_format)); | 730 snd_pcm_format_description(alsa_format)); |
723 | 731 |
724 } // end switch alsa_handler (spdif) | 732 } // end switch alsa_handler (spdif) |
725 alsa_can_pause = snd_pcm_hw_params_can_pause(alsa_hwparams); | 733 alsa_can_pause = snd_pcm_hw_params_can_pause(alsa_hwparams); |