[alsa-devel] Bug report Realtek ALC887-VD HDA Intel tone://15000
I am writing to report a bug with ALSA that affects XMMS and Audacious.
I have a Realtek ALC887-VD HDA Intel. I tested with kernel 3.12-rc4 and alsa-libs 1.0.27.2.10.gc1fbd and alsa-oss-1.0.25.2.g39df1 library. I also compiled and installed alsa-utils-1.0.27.2.6.gf1e99 which made me realize I had to move the libraries from /usr/lib to /usr/lib64.
Playing tone://15000 in Audacious or XMMS with the ALSA driver without resampling sounds bad (in XMMS there is no resampling option).
How to reproduce the bug:
Play in XMMS tone://10
In Audacious you would have to lower the volume by 6 dB to get the same sound volume as in XMMS because it pre-amplifies sounds.
Lower the PC-volume until you stop hearing clicks. To hear the clicks you need headphones and to raise the real-life amplifier volume all the way up. For me it is,
Master: 91% PCM: 100% Front: 60%
Select the ALSA driver and no resampling in Audacious (I think Audacious comes with no resampling as the default setting which is why this is so important).
Play tone://15000
It is supposed to sound like this:
perl -e '$|++;binmode(STDOUT);$_ = 0;while(1){print pack("v",32767.0*sin(($_&(~1))*3.14159265*15000.0/48000.0));++$_;}' | aplay -f dat
but it sounds like this:
perl -e '$|++;binmode(STDOUT);$_ = 0;while(1){print pack("v",32767.0*sin(($_&(~1))*3.14159265*15000.0/44100.0));++$_;}' | aplay -f cd
This is how it sounds like if the OSS driver is invoked:
perl -e '$|++;binmode(STDOUT);$_ = 0;while(1){print pack("v",32767.0*sin(($_&(~1))*3.14159265*15000.0/44100.0));++$_;}' | sox -V4 -b 16 -c 2 -r 44100 -e signed-integer -t raw - -r 44100 -t oss -d
On my computer, the first and third command lines sound good, the second command line sounds bad.
When using the OSS driver in XMMS it sounds like the first and third command lines.
To go into more details: when using the ALSA driver in XMMS, for frequencies higher than tone://10000 the main frequency gets swamped by lower harmonics, so the frequency heard seems to drop the higher it increases. At tone://15000 what is heard is a louder lower harmonic.
My suggestion is: could there be a way to force ALSA to resample the sound when using an ALC887-VD and/or a Realtek chipset and/or HDA Intel...
This e-mail might not be threaded well. It is a follow-up to:
http://mailman.alsa-project.org/pipermail/alsa-devel/2013-October/067158.htm...
I have written a resampler for ALSA. It uses S+P with a symmetric predictor which models fourth order polynomials, 8 times oversampling followed by integration. S+P is described at,
http://www.cipr.rpi.edu/research/SPIHT/EW_Code/ip96_sp.pdf
You can take it for a testdrive:
gcc resample.c -lm -o resample
perl -e '$|++;binmode(STDOUT);$_ = 0;while(1) {print pack("v",32767.0*sin(($_&(~1))*3.14159265*15000/44100.0));++$_;}' | ./resample | aplay -f dat
sox -V4 mysong.wav -b 16 -c 2 -r 44100 -e signed-integer -t raw - | ./resample | aplay -f dat
I found what causes the ALSA bug I wrote about Oct 10. aplay uses this:
Playing raw data 'stdin' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo Plug PCM: Rate conversion PCM (48000, sformat=S32_LE) Converter: linear-interpolation
It is located at alsa-lib-1.0.27.2.10.gc1fbd/src/pcm/pcm_rate_linear.c It apears to be a resampler with linear interpolation.
The bug I wrote about is caused because linear interpolation is not good.
Linux-3.12-rc4 has a resampler at sound/core/oss/rate.c which I'm guessing is ALSA's OSS compatibility layer (OSS for short). It uses linear interpolation and is mathematically equivalent to the alsa-libs resampler. Then it should sound as bad, but the OSS driver in my Slackware-64 14, which is ALSA's OSS compatibility layer, sounds inexplicably good even on a sine generator. So I started thinking that ALSA's OSS compatibility layer puts the Realtek ALC887-VD in 44.1 KHz mode.
I have been messing up linux-3.12-rc4 adding printk(KERN_ERRs to see where the code goes through and sabotaging the ALSA's OSS resamplers so they only play garbage sound. But my song still sounds good when played with sox's OSS driver. So far, everything has held up to my hypothesis.
I added this line to linux-3.12-rc4/sound/pci/hda/hda_codec.c :
u32 rates = 0; for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++) { if (val & (1 << i)) rates |= rate_bits[i].alsa_bits; } printk(KERN_ERR "mihai rates = %d decimal\n", rates);
On 10/9/13, Mihai Moise mihai.moise5@gmail.com wrote:
I am writing to report a bug with ALSA that affects XMMS and Audacious.
I have a Realtek ALC887-VD HDA Intel. I tested with kernel 3.12-rc4 and alsa-libs 1.0.27.2.10.gc1fbd and alsa-oss-1.0.25.2.g39df1 library. I also compiled and installed alsa-utils-1.0.27.2.6.gf1e99 which made me realize I had to move the libraries from /usr/lib to /usr/lib64.
Playing tone://15000 in Audacious or XMMS with the ALSA driver without resampling sounds bad (in XMMS there is no resampling option).
How to reproduce the bug:
Play in XMMS tone://10
In Audacious you would have to lower the volume by 6 dB to get the same sound volume as in XMMS because it pre-amplifies sounds.
Lower the PC-volume until you stop hearing clicks. To hear the clicks you need headphones and to raise the real-life amplifier volume all the way up. For me it is,
Master: 91% PCM: 100% Front: 60%
Select the ALSA driver and no resampling in Audacious (I think Audacious comes with no resampling as the default setting which is why this is so important).
Play tone://15000
It is supposed to sound like this:
perl -e '$|++;binmode(STDOUT);$_ = 0;while(1){print pack("v",32767.0*sin(($_&(~1))*3.14159265*15000.0/48000.0));++$_;}' | aplay -f dat
but it sounds like this:
perl -e '$|++;binmode(STDOUT);$_ = 0;while(1){print pack("v",32767.0*sin(($_&(~1))*3.14159265*15000.0/44100.0));++$_;}' | aplay -f cd
This is how it sounds like if the OSS driver is invoked:
perl -e '$|++;binmode(STDOUT);$_ = 0;while(1){print pack("v",32767.0*sin(($_&(~1))*3.14159265*15000.0/44100.0));++$_;}' | sox -V4 -b 16 -c 2 -r 44100 -e signed-integer -t raw - -r 44100 -t oss -d
On my computer, the first and third command lines sound good, the second command line sounds bad.
When using the OSS driver in XMMS it sounds like the first and third command lines.
To go into more details: when using the ALSA driver in XMMS, for frequencies higher than tone://10000 the main frequency gets swamped by lower harmonics, so the frequency heard seems to drop the higher it increases. At tone://15000 what is heard is a louder lower harmonic.
My suggestion is: could there be a way to force ALSA to resample the sound when using an ALC887-VD and/or a Realtek chipset and/or HDA Intel...
This e-mail might not be threaded well. It is a follow-up to:
http://mailman.alsa-project.org/pipermail/alsa-devel/2013-October/067158.htm...
I found what causes the ALSA bug I wrote about on 10 Oct. aplay uses this:
Playing raw data 'stdin' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo Plug PCM: Rate conversion PCM (48000, sformat=S32_LE) Converter: linear-interpolation
It is located at alsa-lib-1.0.27.2.10.gc1fbd/src/pcm/pcm_rate_linear.c It apears to be a resampler with linear interpolation.
The bug I wrote about is caused because linear interpolation is not good. I don't mean that there is a programming error. I mean that the mathematical theory is flawed.
Linux-3.12-rc4 has a resampler at sound/core/oss/rate.c which I'm guessing is ALSA's OSS compatibility layer (OSS for short). It uses linear interpolation and is mathematically equivalent to the alsa-libs resampler. Then it should sound as bad, but the OSS driver in my Slackware-64 14, which is ALSA's OSS compatibility layer, sounds inexplicably good even on a sine generator. So I started thinking that ALSA's OSS compatibility layer puts the Realtek ALC887-VD in 44.1 KHz mode.
I have been messing up linux-3.12-rc4 adding printk(KERN_ERRs to see where the code goes through and changing the ALSA's OSS resamplers so they only play garbage sound. But my song still sounds good when played with sox's option -r 44100 -t oss -d So far, everything has held up to my hypothesis.
I added this line to linux-3.12-rc4/sound/pci/hda/hda_codec.c:snd_hda_query_supported_pcm
u32 rates = 0; for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++) { if (val & (1 << i)) rates |= rate_bits[i].alsa_bits; } printk(KERN_ERR "mihai rates = %d decimal\n", rates);
Result:
mihai rates = 5312 decimal mihai rates = 5856 decimal
I don't know what these numbers mean. According to linux-3.12-rc4/include/sound/pcm.h that would mean 192KHz. So that's not the interpretation.
I added this line to linux-3.12-rc4/sound/core/oss/rate.c:resample_expand:
printk(KERN_ERR "Entered resample_expand\n");
Result: nothing in /var/log/syslog, even after playing 44.1KHz audio through sox's option -r 44100 -t oss -d
I added this line to linux-3.12-rc4/sound/core/oss/rate.c:resample_shrink:
printk(KERN_ERR "Entered resample_shrink\n");
Result: nothing in /var/log/syslog
I made linux-3.12-rc4/sound/core/oss/rate.c:resample_expand play garbage audio like this:
*dst = val; if(((long)dst) & 4) *dst = 32767; else *dst = -32767; dst += dst_step;
And I made linux-3.12-rc4/sound/core/oss/rate.c:resample_shrink play garbage audio like this:
*dst = val; if(((long)dst) & 4) *dst = 32767; else *dst = -32767; dst += dst_step;
Result: playing a 44.1KHz song through sox's option -r 44100 -t oss -d plays just fine.
I would appreciate if someone would clarify me if ALSA's OSS compatibility layer puts the Realtek ALC887-VD in 44.1KHz mode.
On 10/24/13, Mihai Moise mihai.moise5@gmail.com wrote:
I have written a resampler for ALSA. It uses S+P with a symmetric
Please ignore this. Gmail mistakenly sent out a draft.
The next e-mail after the one I'm quoting is valid.
participants (1)
-
Mihai Moise