Another USB sound question


12 posts
by atom » Tue Jan 01, 2013 4:08 pm
I'm trying to make an Airplay receiver using a RPi, following these instructions: http://trouch.com/2012/08/03/airpi-airplay-audio-with-raspberry/. This works with the internal audio, but of course the sound quality isn't great so I want to use an external sound card. I'm using a Creative SoundBlaster Extigy card - it's old but it works with the standard Linux USB audio drivers on my main PC (at least under Ubuntu). But with the Raspberry Pi I'm not having so much luck.

Connecting the card before boot then running dmesg shows that the card has been recognised. Running aplay -l (as root) lists both the internal and external cards, with the internal selected as default. I then tried editing /etc/modprobe.d/alsa-base.conf, replacing the line:
Code: Select all
options snd-usb-audio index=-2

with
Code: Select all
options snd-usb-audio index=0
options snd-bcm2835 index=-2
options snd-usb-audio nrpacks=1

This is supposed to disable the internal sound card, and force the USB card to default. Running aplay -l now results in this, which looks hopeful:
Code: Select all
**** List of PLAYBACK Hardware Devices ****
card 0: Extigy [Sound Blaster Extigy], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: Extigy [Sound Blaster Extigy], device 1: USB Audio [USB Audio #1]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: Extigy [Sound Blaster Extigy], device 2: USB Audio [USB Audio #2]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

For some reason, the USB card has been listed three times. I think this might be either for 5.1 channel audio (with the three devices being front, rear and center, which each have their own plugs on the back of the card), or because the card has seperate analog, SPDIF and ToSLink outputs. Either way, trying to play something with aplay results in no sound from either the internal or external cards. So I tried specifying a device name:
Code: Select all
sudo aplay -Dhw:0,0 song.wav

This worked better. I now get sound, but it's distorted with a continual crackling/rumbling sound, and everything plays at the wrong pitch. aplay shows this warning:
Code: Select all
Warning: rate is not accurate (requested = 44100Hz, got = 48000Hz)
         please, try the plug plugin

Not sure what the plug plugin is. If I try aplay with the same card on my main (Ubuntu) PC, it selects the correct sound card without the -D option, and plays back at the correct rate with no distortion or warnings. If I use the -D option on my main PC, I get the same warning as on the Pi, and the sound is also wrong (though this time it plays too fast/high pitched). So I'd guess using the -D tag is bypassing some software that converts the sample rate, but I don't know enough about ALSA to know whether this is actually the case or not. What I do know is that on my main PC, everything works fine if I don't use the -D option. On the Pi, leaving out -D gets no sound. So how do I get ALSA to select the correct device so I don't have to use -D?
User avatar
Posts: 15
Joined: Fri Sep 14, 2012 11:52 am
Location: Cheshire, UK
by azeam » Tue Jan 01, 2013 4:52 pm
Are you using any ALSA config file (.asoundrc or /etc/asound.conf)? Can you paste the content of that file?

To try a file with the plug plugin:
Code: Select all
sudo aplay -D plughw:0,0 song.wav
User avatar
Posts: 192
Joined: Fri Oct 26, 2012 11:13 pm
by atom » Wed Jan 02, 2013 12:23 pm
So I tried running the command you said and the warning didn't come up this time, but the sound was still distorted. There is no ~/.asoundrc file, but I did find /etc/asound.conf:
Code: Select all
pcm.mmap0 {
    type mmap_emul;
    slave {
      pcm "hw:0,0";
    }
}

pcm.!default {
  type plug;
  slave {
    pcm mmap0;
  }
}
User avatar
Posts: 15
Joined: Fri Sep 14, 2012 11:52 am
Location: Cheshire, UK
by atom » Thu Jan 10, 2013 5:30 pm
OK, I've been doing some more messing around with this, trying to get resampling to work. I added the following to my /etc/asound.conf file:
Code: Select all
pcm_slave.sl2 {
    pcm "hw:0,0"
    rate 48000
}

pcm.rate_convert {
    type rate
    slave sl2
}

Then running:
Code: Select all
aplay -Drate_convert song.wav

This gives the same results as the plug plugin - the warning about an incorrect sample rate disappears, but the distortion remains. It's almost as though ALSA says it is resampling to 48kHz, but actually isn't doing anything at all. I've tried this on both Raspbian and ArchLinux, and get exactly the same results. From this and other posts I've read about similar problems, I'm starting to think that resampling just doesn't work on the Raspberry Pi at all. Maybe this is a problem with the ARM port of ALSA, or with the Pi hardware specifically. Could it be something to do with the floating point problems that also cause trouble with Mono and Java? Of course I could be completely wrong about this, and the problem could be something unrelated to resampling.

Does anyone have any ideas? In particular, has anyone been able to actually get resampling to work on a Raspberry Pi?
User avatar
Posts: 15
Joined: Fri Sep 14, 2012 11:52 am
Location: Cheshire, UK
by cyrano » Thu Jan 10, 2013 5:41 pm
My experience with Creative audio interfaces isn't good. They pretend to be confirming to USB2 audio specs, but they're not really. If you play (or record) audio through them, the clock goes way off after a while, resulting in distortion going up to 100% after 30 minutes or so. And the resampling problem you're having seems to be in the same league.

I gave away all the Creative interfaces I had laying around.

The cheap Chinese stuff seems to adhere better to standards. And cheap Behringer interfaces work without the kind of trouble you seem to be having, too.
User avatar
Posts: 505
Joined: Wed Dec 05, 2012 11:48 pm
Location: Belgium
by atom » Thu Jan 10, 2013 5:59 pm
Thing is, it works fine on my main Ubuntu PC. I've never had any problems with incorrect clock rates or distortion. Oh, and the card is old enough to be USB1.1 only, not USB2.
User avatar
Posts: 15
Joined: Fri Sep 14, 2012 11:52 am
Location: Cheshire, UK
by cyrano » Thu Jan 10, 2013 6:16 pm
That's my experience too. It works, sounds very good, but once you move to another system, troubles start again.

Maybe I'm a bit of a fanatic, but I want all my audio interfaces to be plug and play. I'll allow for a platform specific driver if the interface offers something I can't find in other interfaces. But that is the one exception to the rule :roll:
User avatar
Posts: 505
Joined: Wed Dec 05, 2012 11:48 pm
Location: Belgium
by ski522 » Thu Jan 10, 2013 7:18 pm
I'm using this card (below) and it sounds awesome whether you use the digital ports or analog ports. Rather then pulling you're air out with the card you are trying to use now I say spend the $14 and get one that is known to work with the pi.

http://www.aliexpress.com/store/product ... o_detail_a

Image

More info can be found in my thread about the card: viewtopic.php?t=20866
Posts: 394
Joined: Sun Sep 30, 2012 2:22 pm
by atom » Thu Jan 10, 2013 9:04 pm
The only problem with the cheap cards is a lack of specs, so I don't know if they would actually be a downgrade on what I've got already.
User avatar
Posts: 15
Joined: Fri Sep 14, 2012 11:52 am
Location: Cheshire, UK
by ski522 » Fri Jan 11, 2013 1:00 am
atom wrote:The only problem with the cheap cards is a lack of specs, so I don't know if they would actually be a downgrade on what I've got already.


The card I listed is based on TI's PCM2704 which seems to get decent reviews in general. More info on the chip can be found http://www.ti.com/product/pcm2704c. and has very good sound quality that not only myself but others who have gotten that card for the PI will agree with. I'm feeding the card into a high end home theater system and wouldn't be using it if it didn't meet my needs, although I'm using it for PCM and letting my receiver do the digital to analog conversion.
Posts: 394
Joined: Sun Sep 30, 2012 2:22 pm
by ssb22 » Fri Jan 18, 2013 2:12 pm
I don't think the USB audio problem is ARM floating-point by itself, because before I got my Raspberry Pi, I was using an NSLU2 reconfigured as a "Slug" (also running Debian on ARM, but with no video output and only 32M RAM), and I had a cheap unbranded USB sound card configured for it with the following /etc/asound.conf:

pcm.converter {
type plug
slave {
pcm "hw:1,0" # changed for the Pi; hw:0,0 on the NSLU2
rate 48000 # the only one listed in /proc/asound/card1/stream0
channels 2
format S16_LE
}
}
pcm.!default converter

This was playing just fine with no distortion on the NSLU2, but the same card and same config gives distortion on the Pi. So what's the difference between the Pi and the NSLU2? They both use ARM cores. The exact version of the ARM core in use is probably different between the Pi and the NSLU2, but I can't imagine this difference would be a problem. More important are the differences in the system-on-chip packaging (e.g. different USB-driver hardware) and in the Linux version and Debian setup.

One obvious difference is that the Pi runs pulseaudio (my NSLU2 did not). I tried apt-get remove pulseaudio but that did not solve the problem. (It might have helped to reduce system load a tiny bit, so I'll leave it removed unless I find out I need it.)

Another big difference between the NSLU2 and the Pi is that the Pi's Ethernet port is internally implemented over the USB bus. (The NSLU2's system-on-chip has a dedicated Ethernet interface which is separate from USB, but I understand this is not the case with the Pi.) I find the distortion problem is much greater if playing audio that is being streamed from somewhere over the network (especially at high bandwidth); it's not so bad when playing an audio file that has been stored on the Pi's SD card. Therefore I think some kind of bus contention between Ethernet and USB audio could be happening.

It is possible to increase the amount of audio that is sent to the USB device in each "burst", hence making the USB timing less critical. This can be done by increasing the "nrpacks" parameter of the kernel's snd-usb-audio module from its default of 8 to its maximum of 20. I.e. edit /etc/modules and make sure it includes:

snd-usb-audio nrpacks=20

before any other snd- lines (change takes effect at reboot). To change nrpacks in a running system, do:

rmmod snd-usb-audio
modprobe snd-usb-audio nrpacks=20

and to verify that the change has taken place, do:

cat /sys/module/snd_usb_audio/parameters/nrpacks

which should now say 20. I found this does seem to reduce the distortion, but does not remove it. I'd like to try values higher than 20, but this will require compiling a customized Linux kernel (the limit of 20 is given by the definition of MAX_PACKS in the kernel source at sound/usb/card.h; I'd like to try increasing it to 100 when I get time to figure out how to compile a Raspbian kernel).

Of course the USB card itself will have a hardware limit of how many "read ahead" packets it can accept, which might be less than the nrpacks number. I don't know if there's any way to find out how many packets the card is actually accepting.
Posts: 22
Joined: Thu Jan 17, 2013 9:41 am
by Mysterious » Fri Feb 22, 2013 11:46 am
Hi,

I set the maximum packs to 256 and compiled my own kernel. Unfortunately this didn't do the trick. I set nrpacks to several values but everything remained to distorted.
(I was using a SoundBlaster X-Fi HD USB)

Sigh, I long to see those damn USB Driver Problems solved...
Posts: 7
Joined: Fri Feb 22, 2013 11:34 am