Using the Tascam US-144MKII with Linux

Today I got a Tascam US-144MKII from a colleague because he couldn’t use it anymore with Mac OSX. Apparently this USB2.0 audio interface stopped working on El Capitan. Tascam claims they’re working on a driver but they’re only generating bad publicity with that announcement it seems. So he gave it to me, maybe it would work on Linux.

Tascam US-144MKII
Tascam US-144MKII

First thing I did was plugging it in. The snd_usb_122l module got loaded but that was about it. So much for plug and play. There are reports though that this interface should work so when I got home I started digging a bit deeper. Apparently you have to disable the ehci_hcd USB driver, which is actually the USB2.0 controller driver, and force the US-144MKII to use the uhci_hcd USB1.1 driver instead so that it thinks it’s in USB1.1 mode. This limits the capabilities of the device but my goal for today was to get sound out of this interface, not getting the most out of it.

I quickly found out that on my trusty XPS13 forcing USB1.1 was probably not going to work because it only has USB3.0 ports. So I can disable the ehci_hcd driver but then it seems the xhci_hcd USB3.0 driver takes over. And disabling that driver effectively disables all USB ports. So I grabbed an older notebook with USB2.0 ports and disabled the ehci_hcd driver by unbinding it since it’s not compiled as a module. Unbinding a driver is done by writing the system ID of a device to a so-called unbind file of the driver that is bound to this device. In this case we’re interested in the system ID’s of the devices that use the ehci_hcd driver which can be found in /sys/bus/drivers/ehci-pci/:

# ls /sys/bus/pci/drivers/ehci-pci/
0000:00:1a.7  bind  new_id  remove_id  uevent  unbind
# echo -n "0000:00:1a.7" > /sys/bus/pci/drivers/ehci-pci/unbind

This will unbind the ehci_hcd driver from the device with system ID 0000:00:1a.7 which in this case is an USB2.0 controller.When plugging in the USB interface it now got properly picked up by the system and I was greeted with an active green USB led on the interface as proof.

$ cat /proc/asound/cards
 0 [Intel          ]: HDA-Intel - HDA Intel
                      HDA Intel at 0xf4800000 irq 46
 1 [US122L         ]: USB US-122L - TASCAM US-122L
                      TASCAM US-122L (644:8020 if 0 at 006/002

So ALSA picked it up as a device but it doesn’t show up in the list of sound cards when issuing aplay -l. This is because you have to tell ALSA to talk to the device in a different way then to a normal audio interface. Normally an audio interface can be addressed by using the hw plugin which is the most low-level ALSA plugin that does nothing more than talking to the driver and this is what most applications use, including JACK. The US-144MKII works differently though, its driver snd_usb_122l has to be accessed with the use of the usb_stream plugin which is part of the libasound2-plugins package and that allows you to set a PCM device name that can be used with JACK for instance. This can be done with the following .asoundrc file that you have to create in the root of your home directory:

pcm.us-144mkii {
        type usb_stream
        card "US122L"
}

ctl.us-144mkii {
        type hw
        card "US122L"
}

What we do here is creating a PCM device called us-144mkii and coupling that to the card name we got from cat /proc/asound/cards which is US122L. Of course you can name the PCM device anything you want. Almost all other examples name it usb_stream but that’s a bit confusing because that is the name of the plugin and you’d rather have a name that has some relation to the device you’re using. Also practically all examples use card numbers. But who says that the USB audio interface will always be card 0, or 1. It could also be 2, or 10 if you have 9 other audio interfaces. Other examples work around this by fixing the order of the numbers that get assigned to each available audio interface by adjusting the index parameter for the snd_usb_122l driver. But why do that when ALSA also accepts the name of the card? This also makes thing a lot easier to read, it’s now clear that we are coupling the PCM name us-144mkii to the card named US122L. And we’re avoiding having to edit system-wide settings. The ctl stanza is not strictly necessary but it prevents the following warning when starting JACK:

ALSA lib control.c:953:(snd_ctl_open_noupdate) Invalid CTL us-144mkii
control open "us-144mkii" (No such file or directory)

So with the .asoundrc in place you can try starting JACK:

$ jackd -P85 -t2000 -dalsa -r48000 -p512 -n2 -Cus-144mkii -Pus-144mkii
jackd 0.124.2
Copyright 2001-2009 Paul Davis, Stephane Letz, Jack O'Quinn, Torben Hohn and others.
jackd comes with ABSOLUTELY NO WARRANTY
This is free software, and you are welcome to redistribute it
under certain conditions; see the file COPYING for details

no message buffer overruns
JACK compiled with System V SHM support.
loading driver ..
apparent rate = 48000
creating alsa driver ... us-144mkii|us-144mkii|512|2|48000|0|0|nomon|swmeter|-|32bit
configuring for 48000Hz, period = 512 frames (10.7 ms), buffer = 2 periods
ALSA: final selected sample format for capture: 24bit little-endian in 3bytes format
ALSA: use 2 periods for capture
ALSA: final selected sample format for playback: 24bit little-endian in 3bytes format
ALSA: use 2 periods for playback

This translates to the following settings in QjackCtl:

QjackCtl Settings – Parameters
QjackCtl Settings – Parameters
QjackCtl Settings – Advanced
QjackCtl Settings – Advanced

Don’t expect miracles of this setup. You won’t be able to achieve super low-latencies but at least you can still use your Tascam US-144MKII instead of having to give it away to a colleague.

Using the Tascam US-144MKII with Linux

Resolved JACK issues on notebook

Finally got around troubleshooting the issues I was facing with JACK on my notebook, a BTO that is actually a Clevo W170ER. Somehow I couldn’t go lower than -p128 with USB audio interfaces. When I thought I had tried every option, even disabling hyperthreading, I noticed two unidentified entries in my lsusb output:

Bus 001 Device 003: ID 8087:07da Intel Corp. 
Bus 002 Device 003: ID 5986:0401 Acer, Inc

The first entry is a Bluetooth adapter and the second entry is a webcam. Both devices are unnecessary when making music so I thought, why not unbind them. First I had to figure out their respective bus ID’s:

$ tree /sys/bus/usb/drivers/usb
/sys/bus/usb/drivers/usb
??? 1-1 -> ../../../../devices/pci0000:00/0000:00:1a.0/usb1/1-1
??? 1-1.3 -> ../../../../devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.3
??? 2-1 -> ../../../../devices/pci0000:00/0000:00:1d.0/usb2/2-1
??? 2-1.6 -> ../../../../devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.6
??? bind
??? uevent
??? unbind
??? usb1 -> ../../../../devices/pci0000:00/0000:00:1a.0/usb1
??? usb2 -> ../../../../devices/pci0000:00/0000:00:1d.0/usb2
??? usb3 -> ../../../../devices/pci0000:00/0000:00:14.0/usb3
??? usb4 -> ../../../../devices/pci0000:00/0000:00:14.0/usb4

Since the Bluetooth adapter sits on bus 1 and the webcam on bus two their respective ID’s should be 1-1 and 2-1. So I echoed the ID’s to the unbind file in the same directory:

$ echo -n "1-1" | sudo tee /sys/bus/usb/drivers/usb/unbind
$ echo -n "2-1" | sudo tee /sys/bus/usb/drivers/usb/unbind

Good riddance:

$ lsusb
Bus 001 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub

Then I started JACK again with -p64 using an USB audio interface connected to bus 3 (so no rate matching hub in between) and no more xruns, not even with a generic kernel and using WiFi and all. Next hurdle is the onboard sound. Below -p128 I get bursts of massive xruns and so far I didn’t manage to pinpoint the culprit.

Edit #1: I’ve found out that the Bluetooth adapter is the main bottleneck. Also, by echoing the aformentioned ID’s (1-1 and 2-1) you disable the whole USB bus apparently. To disable just the USB device echo the last ID in the respective path names, so for the Bluetooth adapter that’s 1-1.3 and for the webcam 2-1.6. This way you can still use the USB bus on which these devices are residing. In my case disabling the whole bus is not an option, this would mean I’d have to connect all my USB interfaces to bus 3 (bus 4 doesn’t have any external inputs) which could result in these devices getting in each other’s way with regard to bandwidth. After echoing the ID’s the output of the tree command looks like this:

$ tree /sys/bus/usb/drivers/usb
/sys/bus/usb/drivers/usb
??? 1-1 -> ../../../../devices/pci0000:00/0000:00:1a.0/usb1/1-1
??? 2-1 -> ../../../../devices/pci0000:00/0000:00:1d.0/usb2/2-1
??? bind
??? uevent
??? unbind
??? usb1 -> ../../../../devices/pci0000:00/0000:00:1a.0/usb1
??? usb2 -> ../../../../devices/pci0000:00/0000:00:1d.0/usb2
??? usb3 -> ../../../../devices/pci0000:00/0000:00:14.0/usb3
??? usb4 -> ../../../../devices/pci0000:00/0000:00:14.0/usb4

The lsusb command still shows the devices though.

Edit #2: unbinding drivers like described above won’t persist across reboots. If you’d like to make the unbinding persistent you could add the unbind command to /etc/rc.local or create a script that runs at login. There are other options of course like blacklisting the Bluetooth drivers.

Resolved JACK issues on notebook