Professional audio
For audio production and processing, a system needs to be optimized for low latency using a sound server, such as PipeWire chosen in the Desktop Environment section of the Xfce guide, and audio hardware compatible with ALSA1 (refer to the ALSA SoundCard Matrix).
Today class-compliant2 USB audio interfaces are supported out of the box and most professional audio applications use JACK for low latency operation and signal routing. PipeWire supports these JACK clients. Linuxaudio.org provides extensive but partly outdated documentation about the system configuration, which may help to understand some principles and general guidelines when trying to setup a professional audio environment in general. One of the primary goals is to reduce latency3.
In this guide, I focus the following tasks:
- Perform #Preparations to inspect and adapt the system
- Optimize the #System configuration to reduce latency
- Setup a #Sound server using an USB audio interface
- Install and configure a #DAW with:
- #Latency tuning,
- my favorite #Plugins and
- public domain #Samples
- Use a notation applications for #Composing
Preparations
Based on the preconfigured Xfce desktop and a basic setup of the Sound system as described in the guide on Multimedia and web the first step in building a pro audio environment is to analyze the current system configuration to identify required adaptions. Some settings need to be tweaked for using full system resources and improving the performance for hardware access. Most of these optimizations are documented in the Professional audio article of the ArchWiki and rtcqs can check which of them are required.
Proaudio repository
Though there is an AUR package for rtcqs, I prefer and suggest to use the unofficial proaudio repository by OSAMC. I add the following lines to the /etc/pacman.conf
file:
[proaudio]
Server = https://arch.osamc.de/$repo/$arch
I download, import and sign the current signing key:
curl https://arch.osamc.de/proaudio/osamc.gpg | sudo pacman-key --add -
sudo pacman-key --lsign-key 762AE5DB2B38786364BD81C4B9141BCC62D38EE5
System analysis
Finally, I can install the rtcqs package via the OSAMC proaudio repo:
yay -Syu rtcqs
And execute it afterwards:
rtcqs
The tool provides a detailed overview on the system configuration regarding the latency and suggests adapations or refers to documentation for optimization.
System configuration
In my case, the rtcqs tool reported a WARNING
for:
- #Group limits
- #CPU frequency scaling
- #Preempt RT
- #Spectre/Meltdown mitigations
- #RT priorities
- #Swappiness
- #Filesystems
- #Power Management
The next sections describe the above warnings more detailed and evaluate, if adaptions to the system configuration are necessary or have to be traded off.
Group limits
User resources are limited through PAM4 by /etc/limits.conf
. However, the default settings are to low for typical audio applications and tools. Instead of manually adapting the configuration file I can escelate to install the package realtime-privileges, which creates a realtime
group:
sudo pacman -S realtime-privileges
Afterwards I can add myself to this new group using:
sudo gpasswd -a thisven realtime
and must re-login to apply changes immediatly.
CPU frequency scaling
CPU frequency scaling is used to save power or improve the performance on demand. However, switiching between different profiles during a recording can lead to xruns5. For this reason best practice is to statically set the scaling governor to performance. I prefer to use cpupower, a user space frequency scaler, to change the scaling governor in scripts extecuted before starting JACK and after shutting it down. I install the cpupower package:
sudo pacman -S cpupower
The command to set the scaling governor to performance
is:
sudo cpupower frequency-set -g performance
and the following command sets it back to powersave
:
sudo cpupower frequency-set -g powersave
I add its commands for setting the scaling governor to performance and powersave as a passwordless cmd in the /etc/sudoers
file right below the existing line configured in the Sudo, not su section of the Basic configuration guide:
# Allow group wheel to set cpupower governor
%wheel ALL= NOPASSWD: /usr/bin/cpupower frequency-set -g performance,/usr/bin/cpupower frequency-set -g powersave
Preempt RT
Since kernel version 6.0 there’s no need for Realtime kernel (RT kernel) as the mainline kernel can be configured to provide the level of preemption necessary to achieve lower latencies.
Kernel parameter threadirqs
Though threaded interrupt handlers are a specific feature of the Realtime kernel, the mechanism can be enabled for a mainline kernel at boot time. I add the parameter threadirqs to the options
line in the loader file, which has been created in the Systemd-boot installation section of the System preparation guide. My final /boot/loader/entries/linux.conf
looks like this:
title Linux
linux /vmlinuz-linux
initrd /initramfs-linux.img
options cryptdevice=UUID=<MyUuid>:lvg resume=/dev/lvg/swap root=/dev/lvg/root quiet rw threadirqs
Note that <MyUuid>
is just a placeholder for the actual UUID of my LUKS partition and the threadirqs
parameter is appended to the end of line. Reboot to enable threaded interrupt handlers before proceeding!
Manual IRQ handling
To adjust priorities of IRQ handling threads I install the rtirq package and the rtapp package from the AUR:
sudo pacman -S rtirq
yay rtapp
The rtirq service must be started and enabled manually:
sudo systemctl start rtirq
sudo systemctl enable rtirq
I connect my USB audio interface and wait for its initialization before using the following command:
sudo rtcards
In the output two devices are identified as AUDIO CARDS and in the USB INTERRUPTS AND DEVICES section my USB audio interface appears at USB3 IRQ=151 identified by a fragment of its NAME.
As this USB device is a xHCI host controller the configuration file /etc/rtirq.conf
needs to be adjusted to for realtime priority. I change the RTIRQ_NAME_LIST
line to:
RTIRQ_NAME_LIST="xhci"
and restart the rtirq service:
sudo systemctl restart rtirq
In the output of the command:
sudo rtstatus
the IRQ 151 of the USB audio interface should now get a higher priority.
Spectre/Meltdown mitigations
I choose to ignore this warning as the security of my system is more important than gaining some performance. The capabilities of modern CPUs are sufficient anyway.
RT priorities
This warning will be gone as I already configured #group limits as described before.
Swappiness
The swappiness6 (aka swap frequency) is a parameter to control when the Linux kernel escalates to disk space for swapping opposed to dropping pages from the system page cache. Setting it a lower value, such as 10
, makes the system wait much longer before trying to swap to disk. I reduce swappiness, increase inotify watches, and the RTC intermath: truerupt frequency by installing realtime-generic-setup from the AUR:
yay realtime-generic-setup
Afterwards the service has to be enabled and started:
sudo systemctl enable realtime
sudo systemctl start realtime
Filesystems
The boot partition is mounted at /boot
as configured in the System preparation guide (Formatting and mounting section) this warning can be ignored. This is also a good example of outdated information on linuxaudio.org as in the reference on filesystems the advice is to simply not use disk encryption at all to save CPU resources. Today these bottlenecks are rather negligible.
Power Management
Different sleep states and the wakening process in modern CPUs can cause latency and a #DAW can take advantage of controlling registering a value of 0
to tell the CPU to never got to sleep in order to avoid these latencies. For this reason a udev7 rule from the Ardour project is saved in /etc/udev/rules.d
:
sudo curl --output /etc/udev/rules.d/99-cpu-dma-latency.rules https://raw.githubusercontent.com/Ardour/ardour/master/tools/udev/99-cpu-dma-latency.rules
If you want to review the rules first, check the file contents at: https://github.com/Ardour/ardour/blob/master/tools/udev/99-cpu-dma-latency.rules
To make this rule work I verify that I am a member of the audio
group:
groups | grep audio
If there is no output, I need to add myself to the audio group using:
sudo gpasswd -a thisven audio
I reload the udev rules afterwards to immediatly apply the changes:
sudo udevadm control --reload-rules
sudo udevadm trigger
Sound server
In the center of audio applications the JACK audio server guarentees low latency operation, signal routing and connection management. The different versions of JACK8 originate from its history and may be one reason for a lot of confusion in this use case. However, since PipeWire supports JACK clients and is a drop-in replacement to it a best practice is to not install any JACK packages but keep working with the applications (the JACK clients). In the next sections I will refer to JACK a lot of times. Keep in mind that “under the hood” PipeWire or more specific pipewire-jack
, which has been installed in the Desktop environment section of the Xfce desktop guide, is managing audio as a sound server in the context of the sound system9.
PipeWire profile
With the Xfce panel applet xfce4-pulseaudio-plugin and pavucontrol installed in the #Sound system section of the Multimedia and web guide I can set the Pro Audio Profile for my audio interface in the Configuration tab of the mixer window. This profile preconfigures several hardware-related options10 and eases the process of #Reducing the quantum later to achieve a low latency.
Latency evaluation
The hardest part in achieving low latency is to evaluate optimal parameters depending on the capabilities of the audio interface. You should be familiar with the details about how latency occurs when using audio interfaces as Audio-to-Digital Converter (ADC) and Digital-to-Audio Converter (DAC).
The main parameters regarding to latency (frames, periods, sample rate) are described by this function:
$L = \frac{n \times p}{f}$
$L:$ Latency in miliseconds (ms),
$n:$ Frames11 or Quantum (multiples of 2, starting at 16),
$p:$ Periods (automatically set to 1 by PipeWire to reduce latency12),
$f:$ Sample or Clock rate in Hertz (Hz).
The capabilities of an audio interface define working combinations. You have to trial and error to find a working setup. The task is to find optimal settings to reduce latency as much as possible without xruns (audio drop-outs).
Using a high clock rate
Sure, it’s a trade-off between xrun prevention and higher latency, but most recent audio interfaces can be used at high sample rates (up to 384 kHz) decreasing the resulting latency through a high denominator value in the aforementioned function.
I can retrieve the sample rates for playback and capture of my plugged in USB audio interface using:
grep -E 'Playback|Capture|Rates' /proc/asound/card1/stream0
card0
). Keep in mind that your audio interfaces may be detected in a different order.
In comparison with the product specification of my audio interface the supported sample rates are indeed: 44100 Hz, 48000 Hz, 88200 Hz, and 96000 Hz. PipeWire uses a sample rate of 48000 Hz (48 kHz) per default. I can verify this with:
pw-metadata --name settings | grep clock.rate
However, to allow the other sample rates I create a /etc/pipewire/pipewire.conf.d/custom.conf
file containing:
context.properties = {
default.clock.allowed-rates = [ 44100 48000 88200 96000 ]
}
To actually change the default sample rate to 96 kHz this command can be used:
pw-metadata --name settings 0 clock.rate 96000
Reducing the quantum
The frames or buffer size is another parameter in relation to latency that needs to be tuned. In the context of PipeWire it is called Quantum. The default value of 1024 is rather high and can be read using:
pw-metadata --name settings | grep clock.quantum
As the default behaviour of PipeWire is to dynamically adapt the quantum size during runtime the clock.min-quantum
and clock.max-quantum
values define the range. However, PipeWire does not use this strategy for JACK clients. It rather leaves this task to the application itself or to the user. Consequently, each JACK client needs to be capable of changing these parameters when using pipewire-jack. Though this seems to be counter-intuitive when you are already used to the concept of a JACK server that guarantees fixed frames, periods and sample rate parameters, this allows you to run JACK applications more flexible.
You can either change and lock the buffer size to a fixed value, such as 128, by using:
pw-metadata --name settings 0 clock.force-quantum 128
or set the environment variable PIPEWIRE_QUANTUM=128/48000
to start the application using a sample rate of 48 kHz and a buffer size of 128. To further evaluate which quantum value is a good trade-off it is a best practice to simulate a recording session in the following section, for example.
Systemic latency
For recording overdubs in a #DAW the systemic latency13 must be set. It adds to the round-trip time (RTT) of an audio interface and can be measured through a loopback. Using a cable to feed the output to the input of the audio interface I can create a loopback to measure RTT and systemic latency.
First close Ardour opened in the previous section for #Quantum evaluation, and use the pw-metadata command to force the previously evaluated quantum size as parameter. For exmaple, I use this command:
pw-metadata --name settings 0 clock.force-quantum 128
The measurement is done using the jack_iodelay utility, which is part of the jack-example-tools package and installed via:
sudo pacman -S jack-example-tools
I use an instrument cable with 6.3 mm mono jacks on both sides as my USB audio interface only provides jack outputs. If your device has XLR outputs but a headphone jack, you may use this output to create the physical side of the loopback. In my case the instrument cable is plugged in into input 1 and output 1 (left output). I double check the gain and volume controls to ensure that sound can actually pass through.
Next, I open two terminals or two terminal tabs and first start jack_iodelay without any parameters:
jack_iodelay
It will repeatedly report Signal below threshold...
as there is no connection from a physical in- and output to the in- and ouput of the utility. For this reason, I use the second terminal window or tab for invoking:
jack_lsp
to list all available JACK clients and create the loopback as follows:
graph LR; input1-->jack_iodelay-->output1-->input1
In my case input 1 and output 1 of the audio interface are listed as AMS-24 Pro:capture_AUX0
and AMS-24 Pro:playback_AUX0
and the input and output of jack_iodelay are listed as jack_delay:in
and jack_delay:out
. I use the following command to create the appropriate connections:
jack_connect "AMS-24 Pro:capture_AUX0" "jack_delay:in"
jack_connect "AMS-24 Pro:playback_AUX0" "jack_delay:out"
In the terminal window that is running jack_iodelay, it now repeatedly reports the total roundtrip latency and extra loopback latency. I can interrupt it using the keystroke <Ctrl>+<C>
and note the recommended value to be used “for the backend arguments -I and -O”.
In my case jack_iodelay reported:
406.000 frames 8.458 ms total roundtrip latency
extra loopback latency: 150 frames
use 75 for the backend arguments -I and -O
In order to set these up I need to find out the node.name
property of the playback (output) and capture (input) device in PipeWire. The USB audio interface is managed by ALSA. For this reason, I can use the following command to list all values containing alsa_
followed by either input
or output
and ending with .usb
plus a variable string:
pw-cli list-objects | grep -E 'alsa_(input|output).usb*'
The command reports two candidates providing the devices:
node.name = "alsa_output.usb-ZOOM_Corporation_AMS-24-00.pro-output-0"
node.name = "alsa_input.usb-ZOOM_Corporation_AMS-24-00.pro-input-0"
I can set the ProcessLatency
to the value reported by jack_iodelay for each node using their names, respectively:
pw-cli set-param alsa_output.usb-ZOOM_Corporation_AMS-24-00.pro-output-0 ProcessLatency {rate: 75}
pw-cli set-param alsa_input.usb-ZOOM_Corporation_AMS-24-00.pro-input-0 ProcessLatency {rate: 75}
Afterwards, I can check the total latency (configured quantum size + systemic latency):
jack_lsp --total-latency
In my case it reports 203 frames ($128 + 75 = 203$) per playback and capture device. You can double check by running the jack_iodelay step again. It should now advise “use 0 for the backend arguments -I and -O”.
ProcessLatency
parameters are not persistent across reboots! For this reason, they will be later incorporated into the #Startup script of the DAW. If you want to use another approach, consider the WirePlumber session manager to apply ALSA extra latency properties via rules.
DAW
A Digital Audio Workstation14 is primarily used to record, edit, and mix music. It integrates a lot of features, such as a multi-track recorder and digital mixing console, to provide a professional audio studio environment. I use Ardour provided by the ardour package, which is installed by:
sudo pacman -S ardour
In the preferences, I like to change the Virtual Keyboard Layout to German QWERTZ
. And in the Media tab of the Session properties the File type can be set to FLAC in order to save disk space. If you want to apply this setting as default for new sessions, use the Button Use these settings as defaults in the Misc tab.
Latency tuning
After installation of the Ardour DAW it can be used to evaluate the optimal quantum size in a recording session. The following sections deal with this evaluation by creating a startup script and trying different quantum sizes with the PIPEWIRE_QUANTUM
environment variable. Additionally, the #Systemic latency of the audio interface is going to be analyzed and compensated. There is much information about latency and latency compensation in the Ardour manual, which I recommend to read to gain some background knowledge.
Startup script
I create a file called daw-rec
to toggle the CPU governor as described in the #CPU frequency scaling section and setting the #Systemic latency before using the environment variable method to start the DAW:
|
|
APP1
variable in line 12, if the Ardour version increases.
I make the script executable and run it:
chmod +x daw-rec
./daw-rec
Quantum evaluation
In Ardour I create some audio tracks, organize the routing and start recording to create load on the system. Refer to the manual or watch some tutorials to learn using Ardour. The task here is to watch the DSP percentage and the xruns number in braces next to it in the status bar while focussing on any noticeable audio drop-outs during recording.
In case of xruns I can increase the buffer size in Ardour’s I/O setup—keep in mind that this reconfiguration provokes a xrun while reconnecting as a JACK client—or close Ardour, double the value of BUFF=128
in the script above. Another strategy for compensation may be #Using a high clock rate. Remember to also repeat the measurement of the #Systemic latency and adapt the value of SMPL=75
to the number of samples jack_iodelay suggests before re-running the #Startup script.
For instance, I’m using a quantum size of $p=128$, a systemic latency of $75$ samples for playback and capture, and the default clock rate of $f=48000$. Recalling the function for #Latency evaluation I’m recording at a total roundtrip latency ($L_R$) of:
$L_R = \frac{(128 + 75) \times 1}{48000 Hz} + \frac{(128 + 75) \times 1}{48000 Hz} = \frac{406}{48000 Hz} = 8.458 ms$
In a mixing only setup I just go with PipeWire’s defaults and if I don’t have my USB audio interface at hand I can use my built-in audio interface.
Plugins
This is a comprehensive topic by itself and I won’t go into the details. I rather list my favorite LV215 plugins with a description based on how I use them:
Package name | Description | More info |
---|---|---|
cardinal-lv2 | Virtual modular synth | https://cardinal.kx.studio/ |
guitarix | Guitar gear emulation | https://guitarix.org/ |
lsp-plugins-lv2 | Compressors, EQs, etc. | https://lsp-plug.in/ |
sfizz-lv2 | Load sampled instruments | https://sfz.tools/sfizz/ |
x42-plugins-lv2 | Meters, limiters, etc. | https://x42-plugins.com/x42/ |
To install all of these packages use the following command:
sudo pacman -S cardinal-lv2 guitarix lsp-plugins-lv2 sfizz-lv2 x42-plugins-lv2
If you are looking for more easy to use or special plugins consider the following projects:
- ArtyFX: Artistic realtime effects for a fast, efficient workflow
- AVLdrums: Drum sample plugin to conveniently use AVL Drumkits.
- Dragonfly Reverb: Reverbs for hall, room, plate, and early reflections
- EQ10Q: Compressor and EQs with visualizations
- IEM Plug-in Suite: Ambisonics up to the 7th order
- Infamous plugins: Effects to add excitement to your productions
- Noise-repellent: Noise reduction with adjustable noise floor
- Rakarrack: Versatile and exotic guitar effects
- setBfree: Tonewheel organ emulator
- Yoshimi: Synthesizer forked from ZynAddSubFX
Find more plugins ready to install by listing the packages of the group lv2-plugins using:
sudo pacman -Sg lv2-plugins
Samples
An alternative to synthesizing sounds is to use sampling16. I use CC0 (public domain) samples for the following instruments:
After installation I can open their SFZ17 files using the sfizz-lv2 plugin installed in the #Plugins section before.
Drums
For acoustic drums I like to use the Tchimera Drum Kit. The installation can be done by cloning the repository:
git clone https://github.com/michaelwillis/tchimera-drum-kit
Alternatively, download an archive of the master and extract it using unzip
, for example.
Piano
The Salamander Grand Piano provides a realistic piano sound and is public domain as of 2022-03-0418. I prefer the sound bank containing the samples in FLAC format to save disk space. I use curl
to download the archive using the current direct link (as of writing this guide):
curl --output SalamanderGrandPiano-SFZ+FLAC-V3+20200602.tar.gz https://freepats.zenvoid.org/Piano/SalamanderGrandPiano/SalamanderGrandPiano-SFZ+FLAC-V3+20200602.tar.gz
The content of the archive can be extracted using:
tar afx SalamanderGrandPiano-SFZ+FLAC-V3+20200602.tar.gz
Orchestra
Public domain orchestral instruments (brass, percussions, strings, woodwinds, etc.) are available in the Community Edition of the Versilian Studios Chamber Orchestra library. I retrieve the samples and SFZ using git:
git clone --branch SFZ https://github.com/sgossner/VSCO-2-CE
Alternatively, download the source code archive of the most current version at the releases page.
You can find various other virtual instruments at FreePats, sfz instruments or in the list of this article by Nils.
Composing
Musical notation is done in a scorewriter19 application and for fretted string instruments, such as guitar, bass and mandolin, tablatures20 or tabs may be an efficient form of musical notation.
Tablatures
TuxGuitar is an alternative to GuitarPro for creating and editing tabs and supports many formats. It is included in the unofficial #Proaudio repository and can be installed using pacman:
sudo pacman -S tuxguitar
I saved many ideas as binary .tg
files. For printing and exchange TuxGuitar can export compositions into LilyPond and MusicXML21 formats. Since the integrated TuxGuitar Synthesizer is limited I like to use FluidSynth and its soundfont22. For this reason, I install the following packages:
sudo pacman -S fluidsynth soundfont-fluid
In TuxGuitar, I open the Plugins dialog in the Tools menu. I enable the FluidSynth output plugin by setting the checkmark in front of it. I use the Configure button to open another dialog.
In the Soundfonts tab I remove the default location and click the Add button to load /usr/share/soundfonts/FluidR3_GM.sf2
. I switch to the Synthesizer tab and set Sample Rate to 48000.0
(according to the sample rate evaluated in #Using a high clock rate) before hitting the OK button and closing the dialog.
Musical notation
In addition to a scorewriter that is dedicated to tabs or as an universal tool for any musical notation, MuseScore has become one of the most popular solutions. It also provides working with tablatures and is available in the official repositories:
sudo pacman -S musescore
In my opinion it probably makes sense to start composing and arranging with MuseScore to get used to a comprehensive suite for musical notation.
However, you might want to start with a less complex application or a more basic ABC notation, for example, depending on your needs and genre. Have a look at the list of applications in the ArchWiki and you may try Laborejo using the notes on installation and starting in its code repository.
To conclude this guide, remember to keep evaluating and improving your setup. Building your personal pro audio environment is a process. You may proceed with setting up a professional video environment. Or, if this is not your use case, go back to the overview and select another guide.
-
Advanced Linux Sound Architecture in the ArchWiki ↩︎
-
USB device classes in the Wikipedia ↩︎
-
Latency (audio) in the Wikipedia ↩︎
-
Swappiness in the Wikipedia ↩︎
-
Sound system in the ArchWiki ↩︎
-
What is the Pro Audio Profile in the PipeWire wiki ↩︎
-
FramesPeriods in the ALSA wiki ↩︎
-
ALSA properties section in the pipewire-devices man page ↩︎
-
Systemic latency configuration by Robin Gareus ↩︎
-
Digital audio workstation in the Wikipedia ↩︎
-
Project site of the LV2 plugin standard ↩︎
-
Sampling (music) in the Wikipedia ↩︎
-
SFZ (file format) in the Wikipedia ↩︎
-
Scorewriter in the Wikipedia ↩︎