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 audio interface doesn't work after turning on the Linux  machine.
With a little effort you might get your device going.

You could also try distributions like SOA (Squeeze on Arch), Volumio or Rune Audio first. These folks have put quite some effort in getting USB interfaces under control on different ARM boards.

There's a good chance that your device runs flawless with one of these. SOA is still under development though. I'm preferring it myself over Volumio and Rune though.


Let's start the trouble shooting and tweaking.


1.  UAC (USB Audio Class) compatibility


Clarify if your device is UAC2 or UAC1 compatible.
Ask your dealer, the manufacturer, the community, the internet.
If the interface is not UAC compatible, you'll need a dedicated Alsa driver for your device. Alsa is the Linux soundlayer btw.
Check if there is a dedicated driver for Linux or Android available.
If this is not the case you won't get the interface going. You can stop here!

Advise: Stay away from devices with proprietary drivers!!

Note:
Certain manufacturers will not talk about Linux/Android thus Alsa compatibility.
You might find references about UAC compatibility if you look for them.
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.
RME Fireface UCX offers explicitly a UAC mode to support "Android" devices. 
Since Android uses the same Alsa as any other Linux, the RME UCX will work. I'm using it as multichannel interface in UAC2 mode.

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 for devices that need proprietary drivers.
Get yourself an interface that works on all platforms!


2.  Base software



Use the latest Linux distribution with most up2date kernel/Alsa you can find. Ubuntu is usually a good starting point.
The community and community support is huge.
Key is that you've got a pretty up2date kernel installed, which usually comes
with the newest audio drivers.
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.
ArchLinux though is not recommended for users without in-depth Linux knowledge.
 
You might install Ubuntu on a stick, just to test if your audio 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.

       aplay --version

will show you the alsa-utils revison, e.g. 1.0.28 .

Many of those ARM boards run kernel in the range of 3.4. . That's several years
behind the most current kernels! However.
Usually manufacturers backport Alsa to those old kernels at least. Even most
current Android Phones (e.g. LG G3) run a 3.4. kernel.
For the Raspberry PI you can install a 3.17 !!! kernel.

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.
Note: 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 similar to above.


4. Alsamixer


Alsamixer is a quite important mixer tool. Beside setting the volumes you'll be able to (de-)activate certain features of your audio device,
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 and there are devices which pop up with nonsense controls!!


4.1 Check alsamixer settings


Some soundcard controls are set to 0 by default (e.g. Dragongfly onboard volume control - this has nothing to do with the application SW-volume control
in case of Dragonfly!!).


First find out your soundcard number/index:

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 audio-device related index number.

alsamixer -c INDEX


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

ESC to exit alsamixer.

Settings usually are stored and set after reboot.

5. Special Cases


There are DACs which look 100% OK so far. 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 standard Alsa USB driver can't cope with these.

There are Alsa patches available to cope with this 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 below, 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 only disable services that are not required!

Of course there are ways to permanently disable certain
programs/services. Above will do for trouble shooting purposes!

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. That setup is not recommended!

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 for multiprocessor boards.

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 using Onboard-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  load on HDD or network while playing back, if you load the entire track into RAM at the beginning of playback.

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

-b 50000:200000

That'll reserve 50MB 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 60% of your avialble RAM size.

free -mq

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% -0.7% CPU power for streaming 24/44.1 PCM streams .


9.0 Binary compatibility

If you download a generic binary such as squeezelite, it's most probably not compiled for your particular 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 (soldering bridge shortening the fuse)
when playing around with the PI.
This slowly increasing resistance might have an impact on your DAC performance.
Usually this issue can also be fixed with a powered hub between your RPI and the DAC as a first aid measure.


Cheap or underdimensioned power-supplies might not supply continuous/stable voltage/current on peak loads. This can lead to perfromance issues.





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. ;)













3 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
  3. Great article - Many Thanks Sir. Helped me reduce XRUNS on A20 using multichannel recording input.

    ReplyDelete