Mercurial > mplayer.hg
comparison libao2/ao_alsa1x.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(¶ms); | |
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? */ |