[alsa-devel] iec958 switch uneffective while playing ac3 stream
Dominique Dumont
domi at komarr.grenoble.hp.com
Tue Apr 3 10:43:14 CEST 2007
Takashi Iwai <tiwai at suse.de> writes:
> Hm, I thought AC3 should have worked as it is. A possible problem
> is in the case that other apps already occupied the stream.
> Currently, the digital output is automatically assigned together
> when an analog output is opened. This is because most of users want
> to output the "audio" data to SPDIF output without hustle if they
> have a receiver. When trying to open the dedicated SPDIF for AC3,
> then it fails because the digital stream was already opened by the
> process for analog streams.
Yes, we've discussed this issue a while ago. In this case, the symptom
is: the application cannot open the hardware device.
> Or, it's simply some missing setup by apps. The app sending the
> non-audio streams like AC3 over SPDIF is supposed to set up the IEC958
> status bits appropriately at opening the stream. The IEC958 bits can
> be passed via arguments for the "spdif" (or "iec958") PCM. For
> example, ac3dec in alsa-tools openes like
>
> plug:iec958:{AES0 0x.. AES1 0x..... AES3 0x..}
>
> where the hex numbers represent status bits. These numbers can be
> shown via iecset utility with -x option. So, you can check via iecset
> whether the parameters are set up properly when you start an app
> accessing SPDIF.
All iec settings are good.
Here's what I found while doing some tests with this setup:
$ cat /proc/asound/cards
0 [Live ]: EMU10K1 - SB Live 5.1 Dell OEM [SB0220]
SB Live 5.1 Dell OEM [SB0220] (rev.10, serial:0x80661102) at 0xb800, irq 50
1 [SB ]: HDA-Intel - HDA ATI SB
HDA ATI SB at 0xffef4000 irq 217
First here's the basic test case which does not work:
- reload alsa driver
- launch 'ac3dec -c 1 -C some_file.ac3'
Here are the traces (I've hacked hda_codec.c and hda_intel.c to
provide more infos) without the boot sequence :
- switch iec958 on alsamixer off:
Apr 1 17:16:54 gandalf kernel: snd_hda_spdif_out_switch_put: val 280 change 1 spdif_ctls 281
Apr 1 17:16:54 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 70d parm 80
Apr 1 17:16:54 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 300 parm b080
- switch iec958 on alsamixer on:
Apr 1 17:17:01 gandalf kernel: snd_hda_spdif_out_switch_put: val 281 change 1 spdif_ctls 280
Apr 1 17:17:01 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 70d parm 81
Apr 1 17:17:01 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 300 parm b000
- ac3 play with ac3dec -c1
Apr 1 17:17:10 gandalf kernel: snd_hda_spdif_out_switch_put: val 2b1 change 1 spdif_ctls 2b1
---> This verb set the correct spdif bit (and switch iec958 on):
Apr 1 17:17:10 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 70d parm b1
Apr 1 17:17:10 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 70e parm 2
Apr 1 17:17:10 gandalf kernel: snd_hda_spdif_out_switch_put: val 2b1 change 0 spdif_ctls 2b1
Apr 1 17:17:10 gandalf kernel: snd_hda_calc_stream_format: format 2, iec958 BE 0, iec958 LE 0
Apr 1 17:17:10 gandalf kernel: ALSA /home/domi/freeware/alsa-stuff/alsa-driver-1.0.14rc3/pci/hda/../../alsa-kernel/pci/hda/hda_intel.c:1163: azx_pcm_prepare: bufsize=0x10000, fragsize=0x800, format=0x11
Apr 1 17:17:10 gandalf kernel: ALSA /home/domi/freeware/alsa-stuff/alsa-driver-1.0.14rc3/pci/hda/hda_codec.c:633: hda_codec_setup_stream: NID=0x6, stream=0x5, channel=0, format=0x11
Apr 1 17:17:10 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 706 parm 50
Apr 1 17:17:10 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 200 parm 11
Apr 1 17:17:10 gandalf kernel: hda-intel: Invalid position buffer, using LPIB read method instead.
ac3 stop
Apr 1 17:17:17 gandalf kernel: ALSA /home/domi/freeware/alsa-stuff/alsa-driver-1.0.14rc3/pci/hda/hda_codec.c:633: hda_codec_setup_stream: NID=0x6, stream=0x0, channel=0, format=0x0
Apr 1 17:17:17 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 706 parm 0
Apr 1 17:17:17 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 200 parm 0
Apr 1 17:17:17 gandalf kernel: snd_hda_spdif_out_switch_put: val 281 change 1 spdif_ctls 281
Apr 1 17:17:17 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 70d parm 81
Apr 1 17:17:17 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 70e parm 2
Apr 1 17:17:17 gandalf kernel: snd_hda_spdif_out_switch_put: val 281 change 0 spdif_ctls 281
Apr 1 17:17:17 gandalf kernel: ALSA /home/domi/freeware/alsa-stuff/alsa-driver-1.0.14rc3/pci/hda/hda_codec.c:633: hda_codec_setup_stream: NID=0x6, stream=0x0, channel=0, format=0x0
Apr 1 17:17:17 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 706 parm 0
Apr 1 17:17:17 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 200 parm 0
At this point the amp refuses to decode and does not display the FS rate.
Now I done some test with the workaround Dag mentioned. Here'is what works:
- switch iec958 off
- play 44Hz on hw1,1 (works also with 48KHz)
- switch iec958 on (optional)
- play ac3
And here are the trace:
- iec958 off
Mar 30 18:40:23 gandalf kernel: snd_hda_spdif_out_switch_put: val 280 change 1 spdif_ctls 281
Mar 30 18:40:23 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 70d parm 80
Mar 30 18:40:23 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 300 parm b080
- start play 44.1KHz audio (you'll note that iec958 is not switched on there)
Mar 30 18:40:49 gandalf kernel: snd_hda_calc_stream_format: format 2, iec958 BE 0, iec958 LE 0
Mar 30 18:40:49 gandalf kernel: ALSA /home/domi/freeware/alsa-stuff/alsa-driver-1.0.14rc3/pci/hda/../../alsa-kernel/pci/hda/hda_intel.c:1163: azx_pcm_prepare: bufsize=0x10000, fragsize=0x4000, format=0x4011
---> Format 0x4011 is indeed 44,1Khz, 16bits 2 channels :
Mar 30 18:40:49 gandalf kernel: ALSA /home/domi/freeware/alsa-stuff/alsa-driver-1.0.14rc3/pci/hda/hda_codec.c:633: hda_codec_setup_stream: NID=0x6, stream=0x5, channel=0, format=0x4011
Mar 30 18:40:49 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 706 parm 50
Mar 30 18:40:49 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 200 parm 4011
Mar 30 18:40:49 gandalf kernel: hda-intel: Invalid position buffer, using LPIB read method instead.
stop 44.1. audio
Mar 30 18:40:54 gandalf kernel: ALSA /home/domi/freeware/alsa-stuff/alsa-driver-1.0.14rc3/pci/hda/hda_codec.c:633: hda_codec_setup_stream: NID=0x6, stream=0x0, channel=0, format=0x0
Mar 30 18:40:54 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 706 parm 0
Mar 30 18:40:54 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 200 parm 0
Mar 30 18:40:54 gandalf kernel: ALSA /home/domi/freeware/alsa-stuff/alsa-driver-1.0.14rc3/pci/hda/hda_codec.c:633: hda_codec_setup_stream: NID=0x6, stream=0x0, channel=0, format=0x0
Mar 30 18:40:54 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 706 parm 0
Mar 30 18:40:54 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 200 parm 0
[ Why is the format now set twice ?? ]
iec958 on
Mar 30 18:40:59 gandalf kernel: snd_hda_spdif_out_switch_put: val 281 change 1 spdif_ctls 280
Mar 30 18:40:59 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 70d parm 81
Mar 30 18:40:59 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 300 parm b000
play ac3
---> first with iec958 on (set digi converter)
Mar 30 18:41:51 gandalf kernel: snd_hda_spdif_out_switch_put: val 2b1 change 1 spdif_ctls 2b1
Mar 30 18:41:51 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 70d parm b1
Mar 30 18:41:51 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 70e parm 2
Mar 30 18:41:51 gandalf kernel: snd_hda_spdif_out_switch_put: val 2b1 change 0 spdif_ctls 2b1
---> then set the stream format
Mar 30 18:41:51 gandalf kernel: snd_hda_calc_stream_format: format 2, iec958 BE 0, iec958 LE 0
Mar 30 18:41:51 gandalf kernel: ALSA /home/domi/freeware/alsa-stuff/alsa-driver-1.0.14rc3/pci/hda/../../alsa-kernel/pci/hda/hda_intel.c:1163: azx_pcm_prepare: bufsize=0x10000, fragsize=0x800, format=0x11
Mar 30 18:41:51 gandalf kernel: ALSA /home/domi/freeware/alsa-stuff/alsa-driver-1.0.14rc3/pci/hda/hda_codec.c:633: hda_codec_setup_stream: NID=0x6, stream=0x5, channel=0, format=0x11
Mar 30 18:41:51 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 706 parm 50
Mar 30 18:41:51 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 200 parm 11
Mar 30 18:41:51 gandalf kernel: snd_hda_calc_stream_format: format 2, iec958 BE 0, iec958 LE 0
---> stream format is set twice (???)
Mar 30 18:41:51 gandalf kernel: ALSA /home/domi/freeware/alsa-stuff/alsa-driver-1.0.14rc3/pci/hda/../../alsa-kernel/pci/hda/hda_intel.c:1163: azx_pcm_prepare: bufsize=0x10000, fragsize=0x800, format=0x11
Mar 30 18:41:51 gandalf kernel: ALSA /home/domi/freeware/alsa-stuff/alsa-driver-1.0.14rc3/pci/hda/hda_codec.c:633: hda_codec_setup_stream: NID=0x6, stream=0x5, channel=0, format=0x11
Mar 30 18:41:51 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 706 parm 50
Mar 30 18:41:51 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 200 parm 11
stop ac3
Mar 30 18:42:30 gandalf kernel: ALSA /home/domi/freeware/alsa-stuff/alsa-driver-1.0.14rc3/pci/hda/hda_codec.c:633: hda_codec_setup_stream: NID=0x6, stream=0x0, channel=0, format=0x0
Mar 30 18:42:30 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 706 parm 0
Mar 30 18:42:30 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 200 parm 0
Mar 30 18:42:30 gandalf kernel: snd_hda_spdif_out_switch_put: val 281 change 1 spdif_ctls 281
Mar 30 18:42:30 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 70d parm 81
Mar 30 18:42:30 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 70e parm 2
Mar 30 18:42:30 gandalf kernel: snd_hda_spdif_out_switch_put: val 281 change 0 spdif_ctls 281
Mar 30 18:42:30 gandalf kernel: ALSA /home/domi/freeware/alsa-stuff/alsa-driver-1.0.14rc3/pci/hda/hda_codec.c:633: hda_codec_setup_stream: NID=0x6, stream=0x0, channel=0, format=0x0
Mar 30 18:42:30 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 706 parm 0
Mar 30 18:42:30 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 200 parm 0
At this point, I think there's a problem with the fact that playing
ac3 stream is done with:
- set digi converter
- then set the stream format.
If the stream format is not valid when the digi converter is set up,
there's a chance that the digi converter goes belly up.
I reckon that setting the stream *then* the digi converter would be safer.
I've not yet tested this theory.
Cheers
--
Dominique Dumont
"Delivering successful solutions requires giving people what they
need, not what they want." Kurt Bittner
More information about the Alsa-devel
mailing list