Sonntag, 29. Oktober 2017

Advanced audio setup in Linux

Contrary to the blog's name, this is not a Haskell post

Doing audio on Linux is a constant fight against Pulseaudion and Phonon. These obnoxious layers are not really needed, but more and more programs rely on them. The only thing you really need is Alsa and possibly Jack if you do professional audio work. This is how I solved these issues.

My computer has access to the following audio devices:

  • The HDA Intel soundchip, which sits on the motherboard.
  • An ES1938 soundcard, which primarily serves as a MIDI device
  • A high quality M Audio Audiophile 24/96 soundcard, which can also do MIDI
  • A Firewire device which connects to my Phonic mixing console
What I want to achieve is the following
  • For professional audio work, I want to use Jack and Jack shall use the Firewire device
  • Audio from websites shall use one the Audiophile soundcard and I want to have a Compressor to normalizes the volume.
  • For regular music playback is also want to use the Audiophile soundcard, albeit without the Compressor.

Jack

For my purposes, I needed the jackd-firewire package. All the audio-production software I use is capable of using jack, and their setup is quite straightforward. Other than that, there is nothing special to say about Jack. It just works as intended.

Alsa

None of my Soundcards can serve more than one client at a time. This problem can be overcome with Pulseaudio or Phonon. However, I want to keep these additional bureaucratic layers at bay, and it turns out there is an Alsa plugin, which solves this problem just as well: the dmix plugin.

The second issue is the compressor. Again there is an Alsa plugin, called ladspa, which allows using ladspa plugins with Alsa. In my case. I use the sc4 compressor plugin.

All this Alsa magic manifests itself in the ~/.asoundrc file.  

Since I want to use a compressor for the crappy sound from web pages and clean sound for my own music playback, I need to expose two Alsa devices. I call them duplex and clean, where

  • duplex compresses audio and is the default device, whereas 
  • clean does not compress. 
Both eventually use my Audiophile sound card. See my .asoundrc at the end of this post.


Pluseaudio

Some applications insist on using pulseaudio, most notably firefox and Skype. That would be enough reason for switching to google-chrome or any other sensible browser. But chrome comes with its own set of problems, so this may not be an option.

The solution is a nifty utility called apulse. It fools applications into believing they are using pulseaudio, where in reality, sound is routed to Alsa. If a utility can add Alsa support to firefox, how difficult can it be to uphold Alsa support in firefox itself? Anyways, you may have to compile apulse yourself, at least this is what I did. It is painless.

Apulse looks at the environment variable APULSE_PLAYBACK_DEVICE to determine which device to use. Since this is only intended for crappy web or Skype sound, I want it compressed, so I set APULSE_PLAYBACK_DEVICE=plug:duplex.Where to set enviroment variables is another issue. I'll come to that.

Then you need to start firefox as something like

apulse /usr/local/bin/firefox $*,

and you'll have Alsa sound in firefox. You can put this into a wrapper script.

Still, convincing your system to always start firefox this way, e.g. even when you click on a link in an email, isn't easy.  I haven't figured that out yet. However, if firefox is already running, the system will reuse that instance, so this is only a problem when you click on an email link before you started firefox.

Clementine

I am using Clementine as my audio player. Formerly I used amarok, but it became too pixilated and Clementine was a much appreciated leaner alternative. Unfortunately Clementine is now going down the same route and requires some tweaking to behave well.

Clementine offers you some choices for your audio output, which are not easy to understand. I have no idea what "Default device on Plays audio to an A2DP device" stands for. This isn't even English, or is it? Furthermore the chosen output device always pops back to "Choose automatically". I did get it to play sound, but I never understood why and I did not know which device it actually used.

Fortunately, you can just edit  ~/.config/Clementine/Clementine.conf and tell it to use the Alsa device of your choice (clean in my case):

[GstEngine]
sink=alsasink
device=plug:clean
...

You better make a backup of thus file, since you never know when some magic will kick in and do something for your own good, thereby overwriting the config file.

play

The play command, which I believe comes with sox,  is a neat utility for playing a soundfile without having to launch a GUI. I could not find a way to tell it the device to use at the commandline. However, you can control this with environment variables. I want it to use the clean device, so I set

AUDIODRIVER=alsa
AUDIODEV=plug:clean

aplay

In constrast to play, aplay has commandline options to select the device. Good,

aplay  -Dplug:clean  dynamics.wav # clean
aplay  -Dplug:duplex dynamics.wav # compressed


Testing the Compressor

To test if the compressor works, it is best to have an audio meter around. In my case the Mudita24 and the envy24control utilities do this for my Audiophile card. If you have another card, then alsamixer may do the trick.

I prepared a test-tone which decreases its volume in 6dB steps and then increases it again. When you play it uncompressed, the meter should jump in 6dB steps. When you play it compressed, the meter should jump only right at the volume change, and then show how the volume is gradually adjusted.

Compressed, it should look something like thuis:





Environment Variables

It is best to set environment variables in your ~/.xsessionrc file for graphical applications and possibly in your ~/.bashrc in case you log in via a text console.


Downloads

You can download my .asoundrc and the test-tone here.