Skip to content

Instantly share code, notes, and snippets.

@unDocUMeantIt
Last active February 12, 2022 13:12
Show Gist options
  • Save unDocUMeantIt/651b621d48108c9a301224ffb886ca20 to your computer and use it in GitHub Desktop.
Save unDocUMeantIt/651b621d48108c9a301224ffb886ca20 to your computer and use it in GitHub Desktop.

M-Audio Fast Track Ultra 8R: ALSA and PulseAudio setup

I was looking for a used audio device with at least 8 line/mic ins/outs and phantom power supply, that would run flawlessly under Ubuntu 20.04 for recording (e.g., with Ardour), SIP phone conferences, and basically everyday stuff when I want headphones. I want my basic instruments and microphones plugged in to be ready to use when I fleel like it, and just have to switch on the device to be ready to go.

Spoiler: I haven't found that yet. But with the rack version of the M-Audio Fast Track Ultra I've come quite close.

It took me about two weeks of searching the web and trying stuff out, until I found a setup that so far I think I can work with. So I decided to share my solution here, may it be helpful to others in a similar position.

I have tested this configuration with both the 19" rack version ("8R", udev idProduct 2081) as well as the standalone device (udev idProduct 2080).

Any feedback is welcome.

The issues I was facing

The only part where it kind of failed so far was "run flawlessly". Because allthough the USB device is indeed supported by ALSA out of the box, that is only "kind of": alsamixer initially shows 120+ controls all ramped up to 100%, including all DSP effects the device offers. So in case you, like me, don't want everything to go in and come out of everything else and sound like farts in a cathedral, there's some additional configuration needed.

Adding to that, when PulseAudio sees the new device offering 8 output channels, it thinks it's smart and declares it a 7.1 surround sound system. And that's like the only analog output profile it offers for the device, there's no "neutral" multichannel profile or else to choose. The inputs are covered by a multichannel profile, which looks fine, though.

It seems some software like SIP clients is easily confused by PulseAudio's surround profile. At least, I couldn't get Ekiga, Linphone or Twinkle to simply use the FTU8R without repeatedly killing the apps and PulseAudio until I was finally able to hear others be be heard. A nightmare! I never had issues like this with the USB stereo device I was using before. There were no error messages or warnings, all audio was silently routed to nowhere.

What I want

The device has two headphone jacks with separate volume controls. Internally, the output channels 1+2 are routed to headphone 1 (L/R) and outputs 3+4 to headphone 2 (L/R). This is good to know for, e.g., Ardour sessions, so you know where to route your master for proper monitoring.

However, with the default ALSA mixing configuration, every input channel is being routed to every output, resulting in one large mono blowout on both headphones, also when it comes to audio playback from any application. I currently have two microphones plugged in on input channels 1 and 2, and then three stereo instruments on input channels 3+4, 5+6 and 7+8. So I want my mics to go to both stereo channels of both headphones (1+2 and 3+4), but analog inputs 3/5/7 on outputs 1 and 3 (i.e., left on heaphones 1 and 2) and analog inputs 4/6/8 on outputs 2 and 4 (i.e., right on heaphones 1 and 2).

I also want any playback from the system (digital inputs 1+2) to go stereo to both headphones.

For my SIP clients and similar software that seems to expect a simple mono/stereo in/out to not freak out and quit, I also want additional sinks: Two separate stereo outputs for the headphones, and a mono input for my main microphone.

Solutions

Routing

I found this configuration script to be very helpful in setting up a more usable default routing. I adjusted it to fit my needs, i.e., get a stereo signal on my headphones from two-channel instruments, while putting single channel inputs (microphones) on both channels of each headphone. My script now turns everything down to 0% first, and then these back to 100%:

## analog inputs
# mic 1 (mono)
AIn1 -> Out1
AIn1 -> Out2
AIn1 -> Out3
AIn1 -> Out4
# mic 2 (mono)
AIn2 -> Out1
AIn2 -> Out2
AIn2 -> Out3
AIn2 -> Out4
# instrument 1 (stereo)
AIn3 -> Out1
AIn3 -> Out3
AIn4 -> Out2
AIn4 -> Out4
# instrument 2 (stereo)
AIn5 -> Out1
AIn5 -> Out3
AIn6 -> Out2
AIn6 -> Out4
# instrument 3 (stereo)
AIn7 -> Out1
AIn7 -> Out3
AIn8 -> Out2
AIn8 -> Out4

## playback (stereo)
DIn1 -> Out1
DIn1 -> Out3
DIn2 -> Out2
DIn2 -> Out4

So this is what my setup script looks like:

card="$1"
if test -z "$card"; then
    exit 1
fi

declare -a TURNUP=(
    "AIn1 - Out1"
    "AIn1 - Out2"
    "AIn1 - Out3"
    "AIn1 - Out4"
    "AIn2 - Out1"
    "AIn2 - Out2"
    "AIn2 - Out3"
    "AIn2 - Out4"
    "AIn3 - Out1"
    "AIn3 - Out3"
    "AIn4 - Out2"
    "AIn4 - Out4"
    "AIn5 - Out1"
    "AIn5 - Out3"
    "AIn6 - Out2"
    "AIn6 - Out4"
    "AIn7 - Out1"
    "AIn7 - Out3"
    "AIn8 - Out2"
    "AIn8 - Out4"
    "DIn1 - Out1"
    "DIn2 - Out2"
    "DIn1 - Out3"
    "DIn2 - Out4"
)

# turn everything down
for i in $(seq 8); do
    for j in $(seq 8); do
        amixer -q -c "$card" set "AIn$i - Out$j" "0%"
        amixer -q -c "$card" set "DIn$i - Out$j" "0%"
    done
    amixer -q -c "$card" set "Effect Send AIn$i" "0%"
    amixer -q -c "$card" set "Effect Send DIn$i" "0%"
done

for i in $(seq 4); do
    amixer -q -c "$card" set "Effect Return $i" "0%"
done

# turn some up again
for i in "${TURNUP[@]}" ; do
    amixer -c "$card" set "$i" "100%"
done

# in case reconfiguration of audio devices turns out to be unreliable,
# try uncommenting the following line to force reloading of drivers
#alsa force-reload && sleep 5

# restart pulseaudio to redefine available sinks via ~/.config/pulse/default.pa
/usr/local/sbin/restart-pulseaudio

This solved the routing problems for me, and adding udev rules so that the script is run when the device becomes available automates this. I have also installed the FTU-Mixer, a standalone python script that gives you a basic GUI to check and change settings. It just needed the python3-wxgtk4.0 package, then you can chmod +x the script and call it from a console.

PulseAudio

The PulseAudio solution I am currently using will change as soon as I find a better approach. I had tried and failed to add a custom profile for the device to add to the 7.1 surround profile that is being used by default, as well as having these sinks and reroutes directly defined in the script triggered by udev events. To effectively get what I wanted I had to configure my setup in ~/.config/pulse/default.pa:

.include /etc/pulse/default.pa

.nofail
load-module module-remap-sink sink_name=FTU8R12 sink_properties="device.description='FTU8R Out 1+2'" remix=no master=alsa_output.usb-M-Audio_Fast_Track_Ultra_8R-00.analog-surround-71 channels=2 master_channel_map=front-left,front-right channel_map=front-left,front-right
load-module module-remap-sink sink_name=FTU8R34 sink_properties="device.description='FTU8R Out 3+4'" remix=no master=alsa_output.usb-M-Audio_Fast_Track_Ultra_8R-00.analog-surround-71 channels=2 master_channel_map=rear-left,rear-right channel_map=front-left,front-right
load-module module-remap-source source_name=FTU8RM source_properties="device.description='FTU8R mono in'" remix=no master=alsa_input.usb-M-Audio_Fast_Track_Ultra_8R-00.multichannel-input channels=1 master_channel_map=front-left channel_map=front-left
set-default-sink FTU8R12
set-default-source FTU8RM
.fail

.nofail
load-module module-remap-sink sink_name=FTU12 sink_properties="device.description='FTU Out 1+2'" remix=no master=alsa_output.usb-M-Audio_Fast_Track_Ultra-00.analog-surround-71 channels=2 master_channel_map=front-left,front-right channel_map=front-left,front-right
load-module module-remap-sink sink_name=FTU34 sink_properties="device.description='FTU Out 3+4'" remix=no master=alsa_output.usb-M-Audio_Fast_Track_Ultra-00.analog-surround-71 channels=2 master_channel_map=rear-left,rear-right channel_map=front-left,front-right
load-module module-remap-source source_name=FTUM source_properties="device.description='FTU mono in'" remix=no master=alsa_input.usb-M-Audio_Fast_Track_Ultra-00.multichannel-input channels=1 master_channel_map=front-left channel_map=front-left
load-module module-combine-sink sink_name=combi_all slaves=alsa_output.pci-0000_00_1b.0.analog-stereo,alsa_output.pci-0000_05_01.0.iec958-stereo,FTU12,FTU34 sink_properties="device.description='Studio, Wohnzimmer und Kopfhörer (FTU)'"
set-default-sink FTU12
set-default-source FTUM
.fail

The first line makes sure you are not completely replacing the system wide configuration, but append to it. I actually have another pair of set-default-sink and set-default-source before the .nofail condition to define the defaults I want to apply when the device is missing.

In order for that configuration to take effect while PulseAudio is already running, I am currently killing the running daemon and let it start again when the device becomes available (see last line of the setup-fast-track-ultra script above). That creates my new sinks. Getting rid of them again once the device is being turned off demands another forceful restart of the PulseAudio daemon. But udev needs to restart PulseAudio as the user running it. The approach outlined here turned out to accomplish the task to my satisfaction, after I adjusted the script to just kill the daemon, saving it as /usr/local/sbin/restart-pulseaudio:

#!/bin/bash
PUID=$(ps -C pulseaudio -o ruid= | awk '{print $1}')

if [ ! -z "$PUID" ]; then
  # environment variables to export
  export PULSE_RUNTIME_PATH="/var/run/user/$PUID/pulse"
  sudo -u "#$PUID" -E pulseaudio --check && sudo -u "#$PUID" -E pulseaudio -k
fi

This restart-pulseaudio script is called both at the end of my adjusted version of /usr/local/sbin/setup-fast-track-ultra (restarting PulseAudio when the device appears) as well as directly by udev when the device is removed. So to cover both, rack and standalone verions of the FTU, I have the following saved as /lib/udev/rules.d/80-fast-track-ultra.rules:

ACTION=="add", SUBSYSTEM=="sound", KERNEL=="controlC*", ATTRS{idVendor}=="0763", ATTRS{idProduct}=="2080", RUN+="/usr/local/sbin/setup-fast-track-ultra %n"
ACTION=="add", SUBSYSTEM=="sound", KERNEL=="controlC*", ATTRS{idVendor}=="0763", ATTRS{idProduct}=="2081", RUN+="/usr/local/sbin/setup-fast-track-ultra %n"
ACTION=="remove", SUBSYSTEM=="sound", KERNEL=="controlC*", ATTRS{idVendor}=="0763", ATTRS{idProduct}=="2080", RUN+="/usr/local/sbin/restart-pulseaudio"
ACTION=="remove", SUBSYSTEM=="sound", KERNEL=="controlC*", ATTRS{idVendor}=="0763", ATTRS{idProduct}=="2081", RUN+="/usr/local/sbin/restart-pulseaudio"

Wrap it up

Whenever I turn on my FTU8R, udev calls a script to adjust the routing of channels to my taste and then kills the PulseAudio daemon, which in turn restarts and adds the new audio sinks and source from the custom default.pa. When i turn the FTU8R off again, udev kills my PulseAudio daemon again which tears down the superfluous sinks and source again.

Four files were added/edited to accomplish this:

  • ~/.config/pulse/default.pa
  • /usr/local/sbin/setup-fast-track-ultra
  • /usr/local/sbin/restart-pulseaudio
  • /lib/udev/rules.d/80-fast-track-ultra.rules
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment