comparison libao2/ao_alsa9.c @ 6193:2fd9ec444098

AC3 passthrough support by Andy Lo A Foe <andy at alsaplayer dot org>
author alex
date Sun, 26 May 2002 12:23:19 +0000
parents d9641a4e7dbb
children 156144ee6810
comparison
equal deleted inserted replaced
6192:f03fe2e84efd 6193:2fd9ec444098
1 /* 1 /*
2 ao_alsa9 - ALSA-0.9.x output plugin for MPlayer 2 ao_alsa9 - ALSA-0.9.x output plugin for MPlayer
3 3
4 (C) Alex Beregszaszi <alex@naxine.org> 4 (C) Alex Beregszaszi <alex@naxine.org>
5 5
6 modified for better alsa-0.9.0beta8a-support by Joy Winter <joy@pingfm.org> 6 modified for better alsa-0.9.0beta8a-support by Joy Winter <joy@pingfm.org>
7 7 additional AC3 passthrough support by Andy Lo A Foe <andy@alsaplayer.org>
8
8 This driver is still at alpha stage. 9 This driver is still at alpha stage.
9 If you want stable sound-support use the OSS emulation instead. 10 If you want stable sound-support use the OSS emulation instead.
10 11
11 Any bugreports regarding to this driver are welcome either to the mplayer-user-mailinglist or directly to the authors. 12 Any bugreports regarding to this driver are welcome either to the mplayer-user-mailinglist or directly to the authors.
12 */ 13 */
50 static int alsa_fragsize = 8192; /* possible 4096, original 8192 */ 51 static int alsa_fragsize = 8192; /* possible 4096, original 8192 */
51 static int alsa_fragcount = 8; 52 static int alsa_fragcount = 8;
52 53
53 static int chunk_size = -1; 54 static int chunk_size = -1;
54 static int start_delay = 1; 55 static int start_delay = 1;
56
57 snd_pcm_t *
58 spdif_init(int acard, int adevice)
59 {
60 //char *pcm_name = "hw:0,2"; /* first card second device */
61 char pcm_name[255];
62 static snd_aes_iec958_t spdif;
63 snd_pcm_info_t *info;
64 snd_pcm_t *handler;
65 snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;
66 unsigned int channels = 2;
67 unsigned int rate = 48000;
68 int err, c;
69
70 if (err = snprintf(&pcm_name[0], 11, "hw:%1d,%1d", acard, adevice) <= 0)
71 {
72 return NULL;
73 }
74
75 if ((err = snd_pcm_open(&handler, pcm_name, SND_PCM_STREAM_PLAYBACK, 0)) < 0)
76 {
77 fprintf(stderr, "open: %s\n", snd_strerror(err));
78 return NULL;
79 }
80
81 snd_pcm_info_alloca(&info);
82
83 if ((err = snd_pcm_info(handler, info)) < 0) {
84 fprintf(stderr, "info: %s\n", snd_strerror(err));
85 snd_pcm_close(handler);
86 return NULL;
87 }
88 printf("device: %d, subdevice: %d\n", snd_pcm_info_get_device(info),
89 snd_pcm_info_get_subdevice(info));
90 {
91 snd_ctl_elem_value_t *ctl;
92 snd_ctl_t *ctl_handler;
93 char ctl_name[12];
94 int ctl_card;
95
96 spdif.status[0] = IEC958_AES0_NONAUDIO |
97 IEC958_AES0_CON_EMPHASIS_NONE;
98 spdif.status[1] = IEC958_AES1_CON_ORIGINAL |
99 IEC958_AES1_CON_PCM_CODER;
100 spdif.status[2] = 0;
101 spdif.status[3] = IEC958_AES3_CON_FS_48000;
102
103 snd_ctl_elem_value_alloca(&ctl);
104 snd_ctl_elem_value_set_interface(ctl, SND_CTL_ELEM_IFACE_PCM);
105 snd_ctl_elem_value_set_device(ctl, snd_pcm_info_get_device(info));
106 snd_ctl_elem_value_set_subdevice(ctl, snd_pcm_info_get_subdevice(info));
107 snd_ctl_elem_value_set_name(ctl, SND_CTL_NAME_IEC958("", PLAYBACK,PCM_STREAM));
108 snd_ctl_elem_value_set_iec958(ctl, &spdif);
109 ctl_card = snd_pcm_info_get_card(info);
110 if (ctl_card < 0) {
111 fprintf(stderr, "Unable to setup the IEC958 (S/PDIF) interface - PCM has no assigned card");
112 goto __diga_end;
113 }
114 sprintf(ctl_name, "hw:%d", ctl_card);
115 printf("hw:%d\n", ctl_card);
116 if ((err = snd_ctl_open(&ctl_handler, ctl_name, 0)) < 0) {
117 fprintf(stderr, "Unable to open the control interface '%s': %s", ctl_name, snd_strerror(err));
118 goto __diga_end;
119 }
120 if ((err = snd_ctl_elem_write(ctl_handler, ctl)) < 0) {
121 fprintf(stderr, "Unable to update the IEC958 control: %s", snd_strerror(err));
122 goto __diga_end;
123 }
124 snd_ctl_close(ctl_handler);
125 __diga_end:
126
127 }
128
129 {
130 snd_pcm_hw_params_t *params;
131 snd_pcm_sw_params_t *swparams;
132
133 snd_pcm_hw_params_alloca(&params);
134 snd_pcm_sw_params_alloca(&swparams);
135
136 err = snd_pcm_hw_params_any(handler, params);
137 if (err < 0) {
138 fprintf(stderr, "Broken configuration for this PCM: no configurations available");
139 return NULL;
140 }
141 err = snd_pcm_hw_params_set_access(handler, params,
142 SND_PCM_ACCESS_RW_INTERLEAVED);
143 if (err < 0) {
144 fprintf(stderr, "Access tyep not available");
145 return NULL;
146 }
147 err = snd_pcm_hw_params_set_format(handler, params, format);
148
149 if (err < 0) {
150 fprintf(stderr, "Sample format non available");
151 return NULL;
152 }
153
154 err = snd_pcm_hw_params_set_channels(handler, params, channels);
155
156 if (err < 0) {
157 fprintf(stderr, "Channels count non avaible");
158 return NULL;
159 }
160
161 err = snd_pcm_hw_params_set_rate_near(handler, params, rate, 0); assert(err >= 0);
162
163 err = snd_pcm_hw_params(handler, params);
164
165 if (err < 0) {
166 fprintf(stderr, "Cannot set buffer size\n");
167 return NULL;
168 }
169 snd_pcm_sw_params_current(handler, swparams);
170 }
171 return handler;
172 }
173
55 174
56 /* to set/get/query special features/parameters */ 175 /* to set/get/query special features/parameters */
57 static int control(int cmd, int arg) 176 static int control(int cmd, int arg)
58 { 177 {
59 switch(cmd) 178 switch(cmd)
188 } 307 }
189 308
190 printf("alsa-init: %d soundcard%s found, using: %s\n", cards+1, 309 printf("alsa-init: %d soundcard%s found, using: %s\n", cards+1,
191 (cards >= 0) ? "" : "s", alsa_device); 310 (cards >= 0) ? "" : "s", alsa_device);
192 311
193 if ((err = snd_pcm_open(&alsa_handler, alsa_device, SND_PCM_STREAM_PLAYBACK, 312 if (format == AFMT_AC3) {
194 0)) < 0) 313 // Try to initialize the SPDIF interface
195 { 314 alsa_handler = spdif_init(0, 2);
196 printf("alsa-init: playback open error: %s\n", snd_strerror(err)); 315 }
197 return(0); 316
198 } 317 if (!alsa_handler) {
318 if ((err = snd_pcm_open(&alsa_handler, alsa_device, SND_PCM_STREAM_PLAYBACK,
319 0)) < 0)
320 {
321 printf("alsa-init: playback open error: %s\n", snd_strerror(err));
322 return(0);
323 }
324 }
199 325
200 snd_pcm_hw_params_malloc(&alsa_hwparams); 326 snd_pcm_hw_params_malloc(&alsa_hwparams);
201 //snd_pcm_sw_params_malloc(&alsa_swparams);
202 snd_pcm_sw_params_alloca(&alsa_swparams); 327 snd_pcm_sw_params_alloca(&alsa_swparams);
203 if ((err = snd_pcm_hw_params_any(alsa_handler, alsa_hwparams)) < 0) 328 if ((err = snd_pcm_hw_params_any(alsa_handler, alsa_hwparams)) < 0)
204 { 329 {
205 printf("alsa-init: unable to get initial parameters: %s\n", 330 printf("alsa-init: unable to get initial parameters: %s\n",
206 snd_strerror(err)); 331 snd_strerror(err));
386 511
387 if (alsa_device != NULL) 512 if (alsa_device != NULL)
388 free(alsa_device); 513 free(alsa_device);
389 514
390 snd_pcm_hw_params_free(alsa_hwparams); 515 snd_pcm_hw_params_free(alsa_hwparams);
391 snd_pcm_sw_params_free(alsa_swparams);
392 516
393 if ((err = snd_pcm_drain(alsa_handler)) < 0) 517 if ((err = snd_pcm_drain(alsa_handler)) < 0)
394 { 518 {
395 printf("alsa-uninit: pcm drain error: %s\n", snd_strerror(err)); 519 printf("alsa-uninit: pcm drain error: %s\n", snd_strerror(err));
396 return; 520 return;
485 609
486 /* 610 /*
487 plays 'len' bytes of 'data' 611 plays 'len' bytes of 'data'
488 returns: number of bytes played 612 returns: number of bytes played
489 */ 613 */
614
490 static int play(void* data, int len, int flags) 615 static int play(void* data, int len, int flags)
491 { 616 {
492 int got_len; 617 int got_len;
493 618
494 got_len = snd_pcm_writei(alsa_handler, data, len / 4); 619 got_len = snd_pcm_writei(alsa_handler, data, len / 4);
495 620
496 //if ((got_len = snd_pcm_writei(alsa_handler, data, (len/ao_data.bps))) != (len/ao_data.bps)) { 621 //if ((got_len = snd_pcm_writei(alsa_handler, data, (len/ao_data.bps))) != (len/ao_data.bps)) {
497 //SHOULD BE FIXED 622 //SHOULD BE FIXED
498 if (got_len == -EPIPE) /* underrun? */ 623 if (got_len == -EPIPE) /* underrun? */