Re: [alsa-devel] SPDIF/IEC958 sample rate on HDA/ALC882
Takashi Iwai <tiwai <at> suse.de> writes:
Hi,
Sorry, looks like I overlooked this post...
At Wed, 01 Nov 2006 17:58:55 +0100, Erik Slagter wrote:
Sorry if this is considered to be "user" question, but I got no response at all from the "user" list. Guess the real cracks hang around here.
I have lots of questions I cannot resolve from all of the docs, but for the moment I'll stick to the most important one.
The combination of HDA/ALC882 should be able to deliver sound at 96 kHz (hda..., right...) Also the ALC882 datasheet says it can deliver sound at 96 kHz.
In practise, though, I cannot get it to output any other sample rate than 48 kHz. Any other sample rate handed to hw:0,0 is simply converted (somewhere??? and badly...) to 48 kHz and the SPDIF is still driven at 48 kHz.
iecset allows me to set the rate to 32/44.1/48 kHz, the spdif output is still at 48 kHz. Some other flags from iecset are actually honoured (like "data" and "emphasis").
It's simply because iecset program doesn't support the rates over 48kHz. But the hda-intel driver supports the rate, AFAIK. (At least, there is no particular code that restricts over-48kHz.)
One thing to be noted is that if you use "hw" PCM device, you have to set up the SPDIF status bits _manually_ via control API. If you use "iec958" or "spdif" PCM device, you can pass these bits as optional arguments at opening the PCM.
I can ask aplay to play at various rates (from a suitable PCM file), but it complains at any other rate than 44.1 or 48 (notably 32) kHz that the rate is not supported. It plays at 44.1 kHz though. And again converts it to 48 kHz! Sigh...
Who complains? At least, the driver won't.
Maybe I am using the wrong "hw", there is also a "hw:0,2" device, which I cannot make work properly at all (only one channel is output, large chunks are discarded, much much clipping).
The first PCM device is for the multi-output PCM. It's for both analog and digital. The dedicated SPDIF is the secondary one.
Takashi
Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=D...
Hi,
I was googling around and found this (old) post; I can confirm that there are severe problems with the ALC882 and/or the driver code.
I'm experiencing the same problem as Erik - I cannot get the ALC882 to transmit at any other sample rate than 48kHz over S/PDIF.
When I attempt to play 44.1kHz sound, the S/PDIF connection is still locked at 48kHz (shown by my amplifier), and the resulting sound is less than pleasing. It would seem like a 44.1kHz signal packed in a 48kHz frame rate played back directly - high-pitched sounds suffer badly from what my ears recognize as straightforward sample picking as opposed to resampling.
Looking at hda_codec.c:convert_from_spdif_status() it seems that the IEC958 parameter bit for 44.1kHz/48kHz is not used for anything (correct me if I'm wrong). This would mean that the rate is only set in snd_hda_codec_setup_stream(), and as far as I can tell from looking at the array rate_bits and the ALC882 Series Datasheet the setting is correct for 44.1kHz.
Since I can't find any obvious mistake in the HDA code, I guess there is some problem in patch_realtek.c, or an initialization incompatibility with the HDA code and the ALC882 chip.
There are certainly initialization problems somewhere, as the S/PDIF output is sometimes not able to send AC3 data correctly (amplifier cannot detect AC3 and stays silent), and attempting to play audio (even 48kHz) results in intermittent screeches. This is solved by setting and resetting the IEC958 control widget, trying again and again until it finally works. When it does work, it works without a hitch until the next reboot.
Any ideas? Is there anything I can help to test in order to nail down the problem? My motherboard is an Asus P5W DH Deluxe with an 82801G HDA controller, in case this has any relevance.
Dag Lem dag@nimrod.no writes:
Since I can't find any obvious mistake in the HDA code, I guess there is some problem in patch_realtek.c, or an initialization incompatibility with the HDA code and the ALC882 chip.
There are certainly initialization problems somewhere, as the S/PDIF output is sometimes not able to send AC3 data correctly (amplifier cannot detect AC3 and stays silent), and attempting to play audio (even 48kHz) results in intermittent screeches. This is solved by setting and resetting the IEC958 control widget, trying again and again until it finally works. When it does work, it works without a hitch until the next reboot.
Any ideas? Is there anything I can help to test in order to nail down the problem? My motherboard is an Asus P5W DH Deluxe with an 82801G HDA controller, in case this has any relevance.
I'm looking at a same kind of issue for my MSI mobo (ALC883).
There's something fishy about the verb used to set the stream format (also referred as stream converter in realtek's doc).
The verb used in snd-hda-intel are 0x200 and 0x300 where Intel's and Realtek's doc specify 2h and 3h.
So I tried to switch the verbs to 0x002 and 0x003, but it did not work. :-( (it would be too easy ;-) )
The parameter passed with these verbs also look fishy, but I can't say more as I was to tired to dig further. I'll have a look tonight.
HTH
Dominique Dumont domi.dumont@free.fr writes:
I'm looking at a same kind of issue for my MSI mobo (ALC883).
There's something fishy about the verb used to set the stream format (also referred as stream converter in realtek's doc).
The verb used in snd-hda-intel are 0x200 and 0x300 where Intel's and Realtek's doc specify 2h and 3h.
Hmm, that one escaped me. If this is a problem with hda_codec.h and not with the documentation, then there are more errors:
#define AC_VERB_GET_STREAM_FORMAT 0x0a00 -> 0x000a #define AC_VERB_GET_AMP_GAIN_MUTE 0x0b00 -> 0x000b #define AC_VERB_GET_PROC_COEF 0x0c00 -> 0x000c #define AC_VERB_GET_COEF_INDEX 0x0d00 -> 0x000d
#define AC_VERB_SET_STREAM_FORMAT 0x200 -> 0x002 #define AC_VERB_SET_AMP_GAIN_MUTE 0x300 -> 0x003 #define AC_VERB_SET_PROC_COEF 0x400 -> 0x004 #define AC_VERB_SET_COEF_INDEX 0x500 -> 0x005
So I tried to switch the verbs to 0x002 and 0x003, but it did not work. :-( (it would be too easy ;-) )
Why not, I wish it were that easy :-)
The parameter passed with these verbs also look fishy, but I can't say more as I was to tired to dig further. I'll have a look tonight.
I checked the parameter calculation in hda_codec.c:snd_hda_calc_stream_format(), and it seems to match the Realtek ALC882 Series Datasheet spec. Perhaps something has escaped me here as well, please do have a look.
I'm glad that I'm not alone with the S/PDIF sample rate problem, please keep me updated on your research! So far I can only state that there is definitely an initialization problem somewhere, since the behavior of the S/PDIF link is not deterministic. Perhaps a codec reset timing issue?
Dag Lem dag@nimrod.no writes:
Dominique Dumont domi.dumont@free.fr writes:
[...]
The verb used in snd-hda-intel are 0x200 and 0x300 where Intel's and Realtek's doc specify 2h and 3h.
Hmm, that one escaped me. If this is a problem with hda_codec.h and not with the documentation, then there are more errors:
#define AC_VERB_GET_STREAM_FORMAT 0x0a00 -> 0x000a #define AC_VERB_GET_AMP_GAIN_MUTE 0x0b00 -> 0x000b #define AC_VERB_GET_PROC_COEF 0x0c00 -> 0x000c #define AC_VERB_GET_COEF_INDEX 0x0d00 -> 0x000d
#define AC_VERB_SET_STREAM_FORMAT 0x200 -> 0x002 #define AC_VERB_SET_AMP_GAIN_MUTE 0x300 -> 0x003 #define AC_VERB_SET_PROC_COEF 0x400 -> 0x004 #define AC_VERB_SET_COEF_INDEX 0x500 -> 0x005
Reading the documentation again it all seems correct to me. The verbs above are "4-Bit verbs", which are correctly shifted in order to assemble 40-Bit commands in hda_intel.c:azx_corb_send_cmd()
Now azx_corb_send_cmd() seems to use an on-chip command buffer. I'm going to try to use azx_single_send_cmd() instead tonight (module parameter single_cmd=1), to see whether this makes any difference.
Dag Lem dag@nimrod.no writes:
Reading the documentation again it all seems correct to me. The verbs above are "4-Bit verbs", which are correctly shifted in order to assemble 40-Bit commands in hda_intel.c:azx_corb_send_cmd()
You're right. Intel's doc section 5.3 p 130...
On my side, I'm trying to get AC3 on spdif.
According to the traces I've set up, here's what sent to the alc883 when sending an ac3 stream:
Mar 22 21:50:55 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 70d parm a1 Mar 22 21:50:55 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 70e parm 2 Mar 22 21:50:55 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 706 parm 50 Mar 22 21:50:55 gandalf kernel: snd_hda_codec_write: nid 6 direct 0 verb 200 parm 11
The parm of the last verb (0x200) is 0x11. When looking at Realtek;'s doc (p44), this means a PCM stream.
And I know that my amp does not like ac3 in audio stream. It won't decode unless the stream is flagged as non-audio. (should be parm 0x8011 , ie. bit 15 set)
So it looks like the MSB of the parm where clobbered somewhere.
BTW, the Sample base rate (which controls whether the stream is 44khz or 48khz) is bit 14. So this may be a lead for your problem.
HTH
Dominique Dumont domi.dumont@free.fr writes:
The parm of the last verb (0x200) is 0x11. When looking at Realtek;'s doc (p44), this means a PCM stream.
And I know that my amp does not like ac3 in audio stream. It won't decode unless the stream is flagged as non-audio. (should be parm 0x8011 , ie. bit 15 set)
Err, scratch that. The non-audio bit is set by verb 70D.
So it looks like the MSB of the parm where clobbered somewhere.
BTW, the Sample base rate (which controls whether the stream is 44khz or 48khz) is bit 14. So this may be a lead for your problem.
Probably not.
Sorry for the noise.
Dominique Dumont domi.dumont@free.fr writes:
Dominique Dumont domi.dumont@free.fr writes:
The parm of the last verb (0x200) is 0x11. When looking at Realtek;'s doc (p44), this means a PCM stream.
And I know that my amp does not like ac3 in audio stream. It won't decode unless the stream is flagged as non-audio. (should be parm 0x8011 , ie. bit 15 set)
Err, scratch that. The non-audio bit is set by verb 70D.
Both mythtv and mplayer seem to disable the audio flag correctly. AC3/DTS passthrough works beautifully, as long as the S/PDIF is not "locked up" :-/
If you wanted to play back AC3/DTS from software which is not aware of the audio flag, I suppose you could try the following:
iecset audio off
So it looks like the MSB of the parm where clobbered somewhere.
BTW, the Sample base rate (which controls whether the stream is 44khz or 48khz) is bit 14. So this may be a lead for your problem.
Probably not.
Sorry for the noise.
No noise as far as I'm concerned, I hope I'm not too noisy myself :-)
In any case I cannot find any obvious error in the HDA code. The debug log from attempting to play a 44.1kHz stereo audio file through aplay -Dhw:0,1 is shown below:
[aplay open] Mar 23 00:20:36 localhost kernel: ALSA sound/pci/hda/hda_codec.c:620: hda_codec_setup_stream: NID=0x6, stream=0x0, channel=0, format=0x0 Mar 23 00:21:13 localhost kernel: ALSA sound/pci/hda/hda_intel.c:1158: azx_pcm_prepare: bufsize=0x10000, fragsize=0x4000, format=0x4011 Mar 23 00:21:13 localhost kernel: ALSA sound/pci/hda/hda_codec.c:620: hda_codec_setup_stream: NID=0x6, stream=0x5, channel=0, format=0x4011
[aplay close] Mar 23 00:22:12 localhost kernel: ALSA sound/pci/hda/hda_codec.c:620: hda_codec_setup_stream: NID=0x6, stream=0x0, channel=0, format=0x0
As far as I can tell the format value 0x4011 translates to PCM, 44.1kHz, rate multiplier 1, rate divisor 1, 16 bits, 2 channels - all by the book. And NID 0x6 corresponds to S/PDIF out according to the Realtek documentation.
Does anybody achieve 44.1kHz over S/PDIF with any other brand codec?
If so, there is probably some quirk that must be used for the Realtek chips to control the S/PDIF frame rate. Someone at Realtek should have an idea on what is going on here...
As it stands, S/PDIF works at 48kHz if you're lucky (intermittent audio screeches and unability to detect AC3/DTS if you're not so lucky). It's impossible to set the frame rate to 44.1kHz (or 96khz or 192kHz, for that matter). There is no error reported, but the S/PDIF link stays at 48kHz, no matter what I do.
Dag Lem dag@nimrod.no writes:
Both mythtv and mplayer seem to disable the audio flag correctly. AC3/DTS passthrough works beautifully, as long as the S/PDIF is not "locked up" :-/
Yes.
What I see on my side: - CPM 48Khz works flawlessly - CPM 44KHz sounds horrible - AC3 does not work (requires non-audio flag) - DTS does not work (does not require non-audio flag tx to compatibility with DTS CD) - With DTS and AC3, my amp does not show the frame rate
My best guess is that I've also some trouble with the frame rate also.
At some point it did work, but I don't remember how. Probably when I first loaded manually the driver. I'll try in this area. May be I'll get a real lead...
If you wanted to play back AC3/DTS from software which is not aware of the audio flag, I suppose you could try the following:
iecset audio off
I've tried that to no avail
No noise as far as I'm concerned, I hope I'm not too noisy myself :-)
;-)
As far as I can tell the format value 0x4011 translates to PCM, 44.1kHz, rate multiplier 1, rate divisor 1, 16 bits, 2 channels - all by the book. And NID 0x6 corresponds to S/PDIF out according to the Realtek documentation.
Agreed
If so, there is probably some quirk that must be used for the Realtek chips to control the S/PDIF frame rate. Someone at Realtek should have an idea on what is going on here...
I've downloaded Realtek's version of alsa driver. I'll compare their code to vanilla alsa.
Cheers
Dominique Dumont domi.dumont@free.fr writes:
What I see on my side:
- CPM 48Khz works flawlessly
- CPM 44KHz sounds horrible
- AC3 does not work (requires non-audio flag)
- DTS does not work (does not require non-audio flag tx to compatibility with DTS CD)
- With DTS and AC3, my amp does not show the frame rate
My best guess is that I've also some trouble with the frame rate also.
At some point it did work, but I don't remember how. Probably when I first loaded manually the driver. I'll try in this area. May be I'll get a real lead...
I have the exact same experiences as you, except that even 48kHz audio playback can get severely messed up... I have problems with the ALC882 not sending correct AC3/DTS all the time. I haven't found any reliable pattern to it, but try the following:
1. Turn off IEC958 (e.g. in alsamixer). 2. Start playing a 44.1kHz sound file with aplay (no sound is output, of course). 3. Interrupt aplay. 4. Turn on IEC958. 5. Play an AC3/DTS file from DVD (mplayer dvd:// -ao alsa -ac hwdts,hwac3,)
If it still doesn't work, repeat all the steps again... When you finally do get it to work, you're good until you reboot.
It's not really usable right now, unfortunately :-(
I've downloaded Realtek's version of alsa driver. I'll compare their code to vanilla alsa.
I came across this link while googling today:
http://www.audioasylum.com/forums/pcaudio/messages/18753.html
It seems it is not possible to get anything but 48kHz over S/PDIF in Windows either, except with an old driver (WDM_R131.exe).
Do you have a Windows setup on your machine so that you can try this driver? You'll find it by googling for the file name. I would be extremely interested in knowing whether it is at all actually possible to get 44.1kHz over S/PDIF with these chips. If this driver does work, I suppose it should be possible to sniff out how the S/PDIF frame rate is actually controlled.
I also sent an email to Realtek technical support today, in the hope that they can offer information that can help us.
Dag Lem dag@nimrod.no writes:
- Turn off IEC958 (e.g. in alsamixer).
- Start playing a 44.1kHz sound file with aplay (no sound is output, of course).
- Interrupt aplay.
- Turn on IEC958.
- Play an AC3/DTS file from DVD (mplayer dvd:// -ao alsa -ac hwdts,hwac3,)
I've an interesting weirdness :
If I switch iec958 in alsamixer while playing PCM , I can see when switching on: * verb sent to switch iec958 on : snd_hda_codec_write: nid 6 direct 0 verb 70d parm 81 snd_hda_codec_write: nid 6 direct 0 verb 300 parm b000 * my amp 'digital source' going on with 48KHz
When switching off : * verb sent to switch iec958 off : snd_hda_codec_write: nid 6 direct 0 verb 70d parm 80 snd_hda_codec_write: nid 6 direct 0 verb 300 parm b080 * my amp 'digital source' going on with 48KHz
But while playing ac3 with ac3dec, nothing happens. No verb is sent to the codec, and the 'digital source' indicator on my amp stays on.
Still digging...
HTH
Dominique Dumont domi.dumont@free.fr writes:
[...]
But while playing ac3 with ac3dec, nothing happens. No verb is sent to the codec, and the 'digital source' indicator on my amp stays on.
That is probably caused by the following setting in /etc/alsa/cards/HDA-Intel.conf:
name "IEC958 Playback Switch" lock true
If you change that to "lock false" you will be able to flip the switch while the device is open.
IIRC the lock setting is effective if you specify the device "default" or "iec958", but not if you specify "hw:0,1". I assume this is why you get different results with PCM and AC3 playback.
Dag Lem dag@nimrod.no writes:
That is probably caused by the following setting in /etc/alsa/cards/HDA-Intel.conf:
name "IEC958 Playback Switch" lock true
Got it. Thanks for the tip.
IIRC the lock setting is effective if you specify the device "default" or "iec958", but not if you specify "hw:0,1". I assume this is why you get different results with PCM and AC3 playback.
Yes.
I've also used iecset to switch the audio/non-audio bit while playing an AC3 stream with 'ac3dec -C -D hw:0,1'.
With 'iecset audio mode true', I can hear the typical shuf-shuf-shuf of an ac3 stream played "raw" and the 48KHz Frame rate is shown by my amplifier.
With 'iecset audio mode true', the sound shuts off and the 48KHz indicator is removed from my amp display.
So I assume that the AC3 stream is garbled somewhere.
According the HDA doc, the same stream settings must be sent to: - the HDA controler - the converter (verb 0x200) - the digital converter (verb 0x70D 0x70E)
So far I can't see anything wrong with the converter or the digital converter. Except may be the converter's PCM bit 15 set to PCM instead of non-PCM. (But I've changed it to no avail :-( )
The only thing I've not verified is the HDA controler stream setting. I still have to find where it's done :o)
HTH
Dominique Dumont domi.dumont@free.fr writes:
I've also used iecset to switch the audio/non-audio bit while playing an AC3 stream with 'ac3dec -C -D hw:0,1'.
With 'iecset audio mode true', I can hear the typical shuf-shuf-shuf of an ac3 stream played "raw" and the 48KHz Frame rate is shown by my amplifier.
With 'iecset audio mode true', the sound shuts off and the 48KHz indicator is removed from my amp display.
Did you try my workaround cookbook?
1. Turn off IEC958 in alsamixer. 2. Play and interrupt a 44.1kHz PCM with aplay. 3. Turn on IEC958 in alsamixer. 4. Play AC3 stream.
I have also read while googling that the "WAV volume" in Windows drivers must be set to max in order for S/PDIF output to work. I assume this is the same as PCM volume in ALSA.
Dag Lem dag@nimrod.no writes:
Did you try my workaround cookbook?
- Turn off IEC958 in alsamixer.
- Play and interrupt a 44.1kHz PCM with aplay.
- Turn on IEC958 in alsamixer.
- Play AC3 stream.
Yes ! It works !
Now I have a lead ( and a trace of all verbs sent to the codec).
I have also read while googling that the "WAV volume" in Windows drivers must be set to max in order for S/PDIF output to work. I assume this is the same as PCM volume in ALSA.
Currently, it works while PCM is at 82 (according to alsamixer)
Thanks for the tip.
At Fri, 30 Mar 2007 18:57:39 +0200, Dominique Dumont wrote:
Dag Lem dag@nimrod.no writes:
Did you try my workaround cookbook?
- Turn off IEC958 in alsamixer.
- Play and interrupt a 44.1kHz PCM with aplay.
- Turn on IEC958 in alsamixer.
- Play AC3 stream.
Yes ! It works !
Now I have a lead ( and a trace of all verbs sent to the codec).
I have also read while googling that the "WAV volume" in Windows drivers must be set to max in order for S/PDIF output to work. I assume this is the same as PCM volume in ALSA.
Currently, it works while PCM is at 82 (according to alsamixer)
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.
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.
Takashi
Takashi Iwai tiwai@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 domi@komarr.grenoble.hp.com writes:
[...]
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.
I have been able to shave one step off the workaround, it can be done like this:
1. Turn off IEC958 in alsamixer. 2. Play AC3 stream. 3. Turn on IEC958 in alsamixer while the AC3 stream is playing.
Note that in order to toggle the IEC958 switch while a stream is playing you have to change "true" to "false" in the following setting in /etc/alsa/cards/HDA-Intel.conf:
name "IEC958 Playback Switch" lock false
I'm looking forward to hearing about the outcome if you're going to test reordering the initialization sequence. The question is whether it is sufficient to reorder the sequence, or whether it is actually necessary to start sending data through the converter before turning the digital output bit on.
To confuse things further it also seems to work if you use the default "multiout" device (i.e. don't specify any device). I suppose you have to set the PCM volume to max here, as this device does volume mixing in software.
Takashi Iwai tiwai@suse.de writes:
[...]
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.
Thanks for taking an interest in this.
I've been scratching my head here for a while, and we seem to have initialization problems with the Realtek ALC88x chips (mine is marked ALC882M). One workaround for AC3/DTS, as mentioned in today's reply to Dominique, is to turn the IEC958 switch off, start playing, then turn the IEC958 switch on while playing. Opening the (first) stream while the IEC958 switch is on simply doesn't work - the connected amplifier doesn't detect the AC3/DTS stream.
The more serious problem, for which I have no workaround, is that it doesn't seem to be possible to lock the S/PDIF output frame rate to anything but 48kHz. I am using hw:0,1 and not the default device (which resamples to 48kHz). Can you confirm that it is possible to achieve e.g. 44.1kHz frame rate over S/PDIF using the HDA driver (using any chip)?
Do you happen to have any contacts at Realtek who may be able to sort out the S/PDIF frame rate problem? I tried contacting Realtek, but the reply I got unfortunately didn't answer any of my questions.
At 03 Apr 2007 12:26:52 +0200, Dag Lem wrote:
Takashi Iwai tiwai@suse.de writes:
[...]
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.
Thanks for taking an interest in this.
I've been scratching my head here for a while, and we seem to have initialization problems with the Realtek ALC88x chips (mine is marked ALC882M). One workaround for AC3/DTS, as mentioned in today's reply to Dominique, is to turn the IEC958 switch off, start playing, then turn the IEC958 switch on while playing. Opening the (first) stream while the IEC958 switch is on simply doesn't work - the connected amplifier doesn't detect the AC3/DTS stream.
The more serious problem, for which I have no workaround, is that it doesn't seem to be possible to lock the S/PDIF output frame rate to anything but 48kHz. I am using hw:0,1 and not the default device (which resamples to 48kHz). Can you confirm that it is possible to achieve e.g. 44.1kHz frame rate over S/PDIF using the HDA driver (using any chip)?
Well, I don't remember whether 44kHz worked on my test system, and currently I cannot test right now.
The HD-audio DIGI_CONVERT* verb itself has no rate information but it contains only a part of IEC958 status bits. It seems that the rate is referred from the setting of the corresponding audio output widget.
In your case, your receiver doesn't recognize if it's 44kHZ? What about audio (PCM) samples via 44.1kHz over SPDIF? I assume the driver doesn't produce any error but you see the problem in the receiver side, right?
In theory, we can switch to use the raw 32bit SPDIF frames and let alsa-lib convert it. But I'd like to fix the current code rather than this way if possible.
Do you happen to have any contacts at Realtek who may be able to sort out the S/PDIF frame rate problem? I tried contacting Realtek, but the reply I got unfortunately didn't answer any of my questions.
I don't think we have no contact regarding this...
Takashi
Takashi Iwai tiwai@suse.de writes:
[...]
Well, I don't remember whether 44kHz worked on my test system, and currently I cannot test right now.
OK. This means that currently we don't know for sure whether the frame rate problem is specific to Realtek chips. Do you know of anyone who is likely to have tested 44.1kHz over S/PDIF?
The HD-audio DIGI_CONVERT* verb itself has no rate information but it contains only a part of IEC958 status bits. It seems that the rate is referred from the setting of the corresponding audio output widget.
As far as I can tell the IEC958 rate setting (as reported by iecset) is not used for anything. Which IHMO is good, as it would only complicate things. If I'm mistaken and it *is* used for something, then it would likely cause problems.
In your case, your receiver doesn't recognize if it's 44kHZ? What about audio (PCM) samples via 44.1kHz over SPDIF? I assume the driver doesn't produce any error but you see the problem in the receiver side, right?
Correct, the receiver detects a 48kHz frame rate, regardless of the frame rate setting in the ALC882M digital converter (NID 0x06). What I am trying to do is actually PCM at 44.1kHz, and the ALC88M is not cooperating. I have also tried 96kHz and 192kHz without success - whatever I do the S/PDIF frame rate is locked at 48kHz. If I connect a CD player to the receiver, the receiver detects 44.1kHz as expected.
The resulting sound is quite unpleasant. I believe missing samples are simply repeated to convert from 44.1kHz to 48kHz (I have some hands-on experience with resampling and the harshness in high-pitched sounds leads me to this conclusion).
Thanks again, I hope these problems can be resolved. I'll test your patch tomorrow.
At 03 Apr 2007 18:24:17 +0200, Dag Lem wrote:
Takashi Iwai tiwai@suse.de writes:
[...]
Well, I don't remember whether 44kHz worked on my test system, and currently I cannot test right now.
OK. This means that currently we don't know for sure whether the frame rate problem is specific to Realtek chips. Do you know of anyone who is likely to have tested 44.1kHz over S/PDIF?
No, I hope someone will answer on ML.
The HD-audio DIGI_CONVERT* verb itself has no rate information but it contains only a part of IEC958 status bits. It seems that the rate is referred from the setting of the corresponding audio output widget.
As far as I can tell the IEC958 rate setting (as reported by iecset) is not used for anything. Which IHMO is good, as it would only complicate things. If I'm mistaken and it *is* used for something, then it would likely cause problems.
iecset can't show any rate information because the bits aren't handled at all in the driver. The only question is whether the codec chip really handles or not.
In your case, your receiver doesn't recognize if it's 44kHZ? What about audio (PCM) samples via 44.1kHz over SPDIF? I assume the driver doesn't produce any error but you see the problem in the receiver side, right?
Correct, the receiver detects a 48kHz frame rate, regardless of the frame rate setting in the ALC882M digital converter (NID 0x06). What I am trying to do is actually PCM at 44.1kHz, and the ALC88M is not cooperating. I have also tried 96kHz and 192kHz without success - whatever I do the S/PDIF frame rate is locked at 48kHz. If I connect a CD player to the receiver, the receiver detects 44.1kHz as expected.
The resulting sound is quite unpleasant. I believe missing samples are simply repeated to convert from 44.1kHz to 48kHz (I have some hands-on experience with resampling and the harshness in high-pitched sounds leads me to this conclusion).
Thanks again, I hope these problems can be resolved. I'll test your patch tomorrow.
You can try also iec958 alsa-lib plugin. Define a PCM like below in ~/.asoundrc:
pcm.spdif44 { type iec958 slave { pcm { type hw card 0 device 1 # whatever you like } format IEC958_SUBFRAME_LE } # the below should be corrected with 44.1kHz rates status [ 0x04 0x92 0x10 0x02 ] }
This plugin then will convert samples to 32bit SPDIF frames, send to the specified slave PCM.
Now play 2channel 16bit samples via this device: % aplay -Dspdif44 any-44khz-samples.wav
Currently, the status bits won't be changed dynamically via sample rate, so you have to define it beforehand in asoundrc. I'll fix it later if this approach somehow works...
Maybe you should try the above first with 48kHz (and copy the proper status bits). Of course, make sure that you're using the latest alsa-lib.
Takashi
participants (4)
-
Dag Lem
-
Dominique Dumont
-
Dominique Dumont
-
Takashi Iwai