Monday, 27 February 2017

Preferentially using an external USB Audio Interface as a primary/default pulseaudio sink when available.

On my Lenovo laptop, there is an internal Intel HDA sound card, but a far superior TASCAM audio interface is plugged into my dock, which is in turn wired up to my speakers. When docked, I want the laptop to use the TASCAM sound card, but when roaming, I want it to switch to the internal.

entropy@symplex:~$ pactl list short cards
0 alsa_card.pci-0000_00_03.0 module-alsa-card.c
1 alsa_card.usb-TEAC_Corporation_US-2x2-00 module-alsa-card.c
2 alsa_card.pci-0000_00_1b.0 module-alsa-card.c

I'm talking about the TEAC one, of course; TASCAM is a TEAC offshoot. The third one you see is just HDMI, and we'll ignore it for now.

In your modules list, you should see a module called module-default-device-restore. This is the module that will do the magic, but it doesn't do what we want out of the box. The module is meant to save your configured default-sink and restore it on boot. What happens is that when you boot with the laptop undocked, the module sees that the default-saved-sink is not available, and goes back to the internal one (what we want), but when you shut down, it saves the current default-sink as the new default-saved-sink, which means that the next time you boot-up docked, the internal card will still be the active default sink.

entropy@symplex:~$ pactl list short modules 0 module-device-restore
1 module-stream-restore
2 module-card-restore
3 module-augment-properties
4 module-switch-on-port-available
5 module-udev-detect
6 module-alsa-card device_id="0" name="pci-0000_00_03.0" card_name="alsa_card.pci-0000_00_03.0" namereg_fail=false tsched=yes fixed_latency_range=no ignore_dB=no deferred_volume=yes use_ucm=yes card_properties="module-udev-detect.discovered=1"
7 module-alsa-card device_id="2" name="usb-TEAC_Corporation_US-2x2-00" card_name="alsa_card.usb-TEAC_Corporation_US-2x2-00" namereg_fail=false tsched=yes fixed_latency_range=no ignore_dB=no deferred_volume=yes use_ucm=yes card_properties="module-udev-detect.discovered=1"
9 module-alsa-card device_id="1" name="pci-0000_00_1b.0" card_name="alsa_card.pci-0000_00_1b.0" namereg_fail=false tsched=yes fixed_latency_range=no ignore_dB=no deferred_volume=yes use_ucm=yes card_properties="module-udev-detect.discovered=1"
10 module-bluetooth-policy
11 module-bluetooth-discover
12 module-bluez5-discover
13 module-native-protocol-unix
14 module-default-device-restore
15 module-rescue-streams
16 module-always-sink
17 module-intended-roles
18 module-suspend-on-idle
19 module-systemd-login
20 module-position-event-sounds
21 module-filter-heuristics
22 module-filter-apply
23 module-x11-publish display=:0.0
24 module-x11-bell display=:0.0 sample=bell.ogg
25 module-x11-cork-request display=:0.0
26 module-x11-xsmp display=:0.0 session_manager=local/symplex:@/tmp/.ICE-unix/1407,unix/symplex:/tmp/.ICE-unix/1407

The way to do this is to simply remove write permissions from the file to which the module saves the default-sink to. This is in the pulse configuration directory. If you have many of the *-default-sink files, then check their timestamps and perform the procedure on the latest one. The hash is a machine ID that pulse uses to associate configurations to machines. The one with the latest timestamp is most likely your current machine ID hash.

entropy@symplex:~$ ls ~/.config/pulse/
entropy@symplex:~$ cat ~/.config/pulse/ffdf15cb76974ed4aaa951b2d3564f7b-default-sink

First make sure that the you are docked and the external card is the currently-saved card as the default-sink (as in the above example), then remove the permissions.

entropy@symplex:~$ chmod a-w ~/.config/pulse/ffdf15cb76974ed4aaa951b2d3564f7b-default-sink


Pulse will always try to restore the external card as the default-sink, and failing that revert to the internal card.

Friday, 17 February 2017

Bitwig Studio (for Linux) can no longer use (freezes on) ALSA audio interfaces as of version >= 1.2.0

This is an utterly infuriating problem. I cracked it today by going to Store DJ, which kindly let me sit and play around with a lot of their interface that were on display. I thought this was actually a problem with the audio interface, because I always felt it was a fluke that my interface worked in the first place, since it was a very Windows/OSX-oriented interface, but alas, it is a bug in Bitwig Studio.

The problem manifests itself like this:

After upgrading to Bitwig Studio 1.2.0 on Linux, you find that your audio interface is still recognised and configurable, but can't be used in any way. This culminates in transport not progressing when you press "Play", and no audio coming in when you hit record.

Transport started ("Play" pressed), but transport time not advancing (nothing is playing/recording).

You will observe the same with recording. There will be no transport and nothing will record when you try to use the interface with a version higher than 1.2.0.

This is actually a bug in Bitwig Studio, and after much strace/gdb action, I can tell you that it has to do with the way that Bitwig Studio parses the configuration files. It appears that as of version 1.2.0 and beyond, Bitwig Studio parses configuration files in a different way; possibly the format/layout is incompatible. This results in some stale configuration that can never be erased from the preferences file, even if you change that very preference. There's another manifestation of this, and that is the name of the interface being the name of an old interface, even if a different one is plugged in and the old one is not.

Name of the interface will be that of the old, stale interface that erroneously can never be changed.

Luckily there is a simple solution... erase your preferences files.

1. Close Bitwig Studio

Just do it.

2. Erase Preference Files

This will not erase your license key. That's kept in another file.

entropy@symplex:~$ rm ~/.BitwigStudio/prefs -rf

3. Start Bitwig Studio

You'll need to configure everything from scratch; yes, it's annoying.