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);