Search This Blog

Loading...

Wednesday, April 23, 2014

Shoot the Trouble -- USB Audio Interfaces


With all the very interesting Raspberry Pis and other ARM devices around, Linux becomes more and more interesting for many people. Great audio transports can be build at 35$.
Not to forget. Tablet and Phones are mainly Androids and that is just another Linux, using the same soundlayer (Alsa) then all other Linuxes.

Manufacturers usually still do not commit to support Linux or Android. Which is insane. The vast majority of mobile device out there are Androids.

However. Many devices work or partially work under Linux, because manufacturers comply to general USB Audio Standards (UAC1/UAC2). Meanwhile even Pro Audio companies like RME offer a "Class Compliant" mode for their newest generation of USB devices. (In the RME case they do officially focus on OSX though.)

This article intends to give some trouble shooting and tuning guidance in case of "No SOUND" or "XRUN" issues.



Even though things are getting better, there are still plenty of cases where you'll experience NO SOUND, crackles, clicks and pops or XRUNS as you could call these.

That doesn't necessarily mean that your device won't work under Linux. It might need a little configuration or tweak here and there. 

I do assume some Linux knowledge by the reader as prerequisite to understand properly what I'm talking about. And. Just to make it clear from the very beginning. I won't support anybody, who got issues with his USB interface!!!
Checkout Google or the community for support. My intention is to give directions!
If you have comments for improving the article please let me know.



Many people do have very limited Linux knowledge and give up very quickly if their interface doesn't work after turning on the Linux  machine.
With a little effort you might get your device going.

You might also try distributions like Volumio or Rune Audio first. These folks have put quite some effort in getting USB interfaces under control on ARM boards. There's a good chance that your device runs flawless with one of these.


Let's start the trouble shooting and tweaking.


1.  UAC compatibility


 Clarify if your device is UAC2 or UAC1 compatible.
 Ask your dealer, the manufacturer, the community.
 If it is not UAC compatible, you'll need a dedicated Alsa driver. Alsa is the Linux soundlayer.
 Check if there is a dedicated driver for Linux or Android available.
 If this is not the case you won't get the interface up'n running.

 Beware:
 E.g. The Audioquest Dragonfly pages do not talk about Linux support. They wouldn't ever do so.
 However. The device is working under Linux quite well.

 Advice: If you intend to purchase a device. Make sure it is at least UAC2 compatible.
 Don't let you fool by the feature list or forum feedback about great sound or similar.
 Get an interface that works on all platforms.


2.  Base software



Use the latest Linux distribution you can find. Ubuntu is usually your best bet.
The community and community support is huge.
Key is that you've got a pretty up2date kernel installed, which usually delivers the newest audio driver.
Ubuntu is usually half a year behind the generic kernel development. It's not that bad.
ArchLinux, another distribution, usually comes with the most up2date SW.
But  ArchLinux is not recommended for users without in-depth Linux knowledge.
 
You might install Ubuntu on a stick, just to test if your device gets recognized.

If you run a Debian based distro you're a usually a year or more behind.



You can check the Alsa version by typing:

cat /proc/asound/version

You'll something like


Advanced Linux Sound Architecture Driver Version k3.13.0-24-generic.
The Alsa versions are nowadays in line with the kernel revisions.

Many of those ARM boards run kernel in the range of 3.4. . That's several years
behind the most current kernels! However. Usually they backport Alsa to those
old kernels at least.

3. Device and driver check



Now I'll post some commands, that you issue in a Linux Terminal. Please open a terminal (usually the shortcut  "CTRL-ALT-t" should do)


3.1 List all recognized audio devices:




aplay -l


or


cat /proc/asound/cards


Hmmh. You can't see your device or it says "no soundcards" found...

3.2 Check all recognized USB devices


lsusb

or more in-depth

lsusb -vv


You might get a long list. Scroll back. You might find your device listed.


If you can't find your interface at this point. It is most probably not supported.




3.3 Check if the kernel module (which is the driver) is loaded


lsmod | grep snd_usb


You should see "snd_usb_audio" listed. If not, the system is not recognizing your device as audio device. The USB sound driver is usually hardcoded into the kernel.




3.4 Check the kernel ring buffer (dmesg)



dmesg | grep snd

You might see something similar:

[    2.066875] usbcore: registered new interface driver snd-usb-audio



You can stop at this point, if you don't see anything of above.


4. Alsamixer


Alsamixer is a quite important mixer tool. Sometimes certain functions of your audio device are disabled by default or volume controls are set to 0.
However. Not all devices are very well supported. Some show up with controls.
Others do not show any controls and can still work!!


4.1 Check alsamixer settings


Some soundcard controls are set to 0 by default (e.g. Dragongfly onboard volume control).


First find out your soundcard number:

cat /proc/asound/cards

All listed audio interfaces are indexed, starting with 0 and continue with 1,2,3,4.
Memorize the index that belongs to your interface.

Now we open alsamixer. Replace "INDEX" with your index  number.

alsamixer -c INDEX


Use the arrow keys to navigate and to run your adjustments.

ESC to exit alsamixer.

5. Special Cases


There are DACs which look 100% OK. And still produce NO SOUND.

I know of one case e.g. NAD M51, which uses not very common -- so called --
special file descriptors. The USB driver can't cope with these.

There are patches available to cope with the subject.



6. Soundcheck



There is nice little Alsa utility called speaker-test. It just generates noise.
That's sufficient for testing purposes.

Just run

speaker-test -D plughw:1,0 -c 2

Replace "1" with your card index.  -c 2 stands for a two channel test.

You'll experience a continuous switching left/right channel noise.


Note: Turn your volume control down before you start this test!!



Still no sound...

... you gotta tough case.






7. Dropouts, Pops, Clicks, Xruns,.....


There are many setups where users experience nasty XRUNS or crackles.
Usually these are caused by buffer underruns.

That means your DAC requires more data then your PC is willing or able to deliver.

That can be caused by competing processes, IRQ handling, joint usage of
USB bus for different purposes (e.g. network and USB)  on the same machine.
There can be power (instability) issues. And more...


Before you start make sure you are up2date with your software and kernel!
The community out there tries to improve the performance of those low muscle ARM boards on a daily basis.

Note: Run all tasks below as user "root".

7.1. Alsa buffer


The first measure is to increase your Alsa output buffer sizes.
Usually you'll find a parameter in the settings menu of your preferred app.

If we take squeezelite as example you'll have 20ms buffer by default.

You might try to increase this setting by adding

-a 40:4::1

or larger

-a 80:4::1

or larger....

7.2 Task priority


As a 2. measure you can try to increase the task priority.

With squeezelite that would be using option "-p" e.g.

-p 85

Note: 99 is max. The higher you get, the higher the chance that you lock up the system.


7.3. Increase processor clock

Many Arm devices allow to increase the processor clock in the bios setup.
This might improve the situation.

Please look up how to do it for your device.



7.4  CPU governor

Switch to performance governor for each of your CPUs:

echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor

7.5   Get rid of processes


Try to disable or remove all services  that are not required.

Quick and dirty:

Find out the process ID PID as user root

ps -edf 

The PID is listed in column 2. Then run


kill -9 PID

After reboot those processes are back. You have to redo the task.

Of course you should disable not needed services with upstart or systemd
on a permanent basis.


7.7 Unplug all other USB devices


It's not such a good idea to have other devices such as keyboards, mice, or hard disks or even monitors connected to USB.

E.g. keyboards do have a pretty high priority and put pretty much any other task on hold for a little time.

If you run songs from USB-HDD, it is obvious that the bus is used for reading and writing at the same time. No good.

If you use a Raspberry Pi. You can't avoid sharing USB and ethernet on the same bus controller.

And so on, and so on...

7.6 CPU affinity


Many ARM board distributions or images come with a very basic setup.
If you'd e.g. run a:

cat /proc/interrupts

You'll see that all interrupts are running on a single processor: CPU0.
That's also valid for most of the running user space processes btw.


All other processors then CPU0 are doing nothing on 99% of the ARM installations I've seen so far. People buy 4-Core ARM boards and are using just one CPU.



You can assign e.g. the USB port IRQ that you use to a rather "idle" processor, by issuing

echo 2 > /proc/irq/$(cat /proc/interrupts | grep "ehci_hcd:usb1" | cut -f1 -d ":" | tr -d " " )/smp_affinity
Lookup the grep expression "ehci_hcd:usb1" while looking at the "cat /proc/interrupts"
output.
If you have your DAC connected via USB, you'll see the numbers counting
up, if you run "cat /proc/interrupts" several times. You might have to replace usb1 with usb2 or similar in above command.

To check if it works, run "cat /proc/interrupts" several times after issuing above command. You should see the counter growing on the newly assigned processor.



Further you can assign a process such as squeezelite also to CPU1 - the 2nd processor, by issuing


taskset -p 0x00000002  $(pgrep squeezelite)


Squeezelite got to be running before you run this command!


7.7. WLAN



Try to avoid Wlan. Wlan can cause severe performance issues!
If you need WLAN, you might try a 20$ Netgear WLAN bridge hooked up with a 20inch cable to your ARM board instead.


7.8  RAM playback


You can avoid any access  to HDD or network while playing back, if you load the entire track into RAM.

With squeezelite you could add option similar to e.g.

-b 80000:200000

That'll reserve 80MB as streaming buffer (most flacs will fit in there) and 200MB for the processing (e.g. to store the decoded flac) buffer.
Depending on your available RAM size, you can play with these figures.
I'd recommend to not exceed 50% of your RAM size.


As another test, if you don't run squeezelite. Just copy a track to your RAM disk such as /tmp (if mounted as tmpfs) and play it from there.


7.9 HDD writes

Try to avoid as many HDD writes as possible, try below measures

1.   Mount your partitions with option "noatime"
2.   Mount "/tmp" on tmpfs (RAM) to have temporary system files on RAMdisk
3.   Disable logging

 


8.0 System Utilization


I also experienced that do to whatever reasons certain processes might not work properly causing high CPU loads and causing this or that lockup.

Just run

top

to check if there's a process causing extraordinary system load.

E.g. Just as a reference, squeezelite on my Cubitruck (Allwinner A20) is using 0.3% CPU power.


9.0 Binary compatibility

If you download a binary such as squeezelite, it's not compiled for your praticular machine.
Most binaries are compiled in a pretty generic way to meet all kind of processors of a particular processor family.

I reduced 50% load when compiling my own binary on my own machine.


Let me know if you'd like to try my binary for the Cubitruck (Allwinner A20)
architecture.


10. Power

There are ARM boards that limit the power consumption per USB port to avoid overloading the entire board. This might lead to issues with bus-powered
DACs.
Some boards offer to change the power limits for USB within the bios
setup.

On the Raspberry PI there is a polyfuse protection (750mA) which increases resistance with load. I passed that one by when playing around with the PI.
This slowly increasing resistance might have an impact.

Cheap or underdimensioned power-supplies might not supply continuous/stable voltage/current on peak loads.



Usually all above issues can be fixed with a powered hub as a first aid measure.



11. Alsa-Info.sh


The Alsa team provides a script that collects some uselful infos about your setup.
It even allows to upload your setup to the Alsa team. First you should select "Save locally" to have a look at the logfile yourself.
If you want the Alsa crowd to support you they'll ask for the logfile of your alsa-info.sh.

You can download it from here.

Once downloaded you need to

sudo su
cd /DOWNLOADDIR
chmod 777 ./alsa-info.sh
./alsa-info.sh

The script will tell you where to find the log-file.

Finale




Still No sound or XRUNS??? ....

I'm running out of ideas.

Even if you don't have issues you might try the XRUN tweaks.
You might experience slight improvements on soundquality,
when applying all my above tweaks. ;)













2 comments:

  1. Hi, do you have a kernel patch for NAD M51?

    ReplyDelete
  2. Try this one ( I havn't written it myself - lost the link reference):

    #####################

    --- ./sound/usb/mixer.c 2014-01-29 12:10:03.335082952 +0100
    +++ ./sound/usb/mixer.c.b 2014-01-29 12:19:14.079038021 +0100
    @@ -1341,7 +1341,7 @@ static int parse_audio_feature_unit(stru
    snd_printk(KERN_ERR "usbaudio: unit %u: "
    "invalid UAC_FEATURE_UNIT descriptor\n",
    unitid);
    - return -EINVAL;
    + return 0;
    }
    } else {
    struct uac2_feature_unit_descriptor *ftr = _ftr;
    @@ -1352,7 +1352,7 @@ static int parse_audio_feature_unit(stru
    snd_printk(KERN_ERR "usbaudio: unit %u: "
    "invalid UAC_FEATURE_UNIT descriptor\n",
    unitid);
    - return -EINVAL;
    + return 0;
    }
    }


    #####################

    ReplyDelete