This is the audio setup for my hardware. Goals are:
- Use systemd user sessions, so the sound settings are persistent across logins.
- Use Pulseaudio for non-realtime audio but bridge it to Jack.
- Get my Focusrite Scarlett 8i6 interface to work as good as possible, because it suffers from minor bugs in the kernel driver. Of the 6 mixes only 4 are working, looks like on offset by 2 error. After initialization some channels need to be toggled on/off, or switched to another input and back until they route audio.
These are the cards for my hardware:
cat /sys/class/sound/card*/id
- Nvidia
- NVIDIA HDMI, Card 0, 4 Devices
- Generic
- Motherboard HD Audio (ALC 1220), Card 1, 2 Devices
- Adapter
- USB Rocksmith Guitar Adapter, Card 2, 1 Device
- USB
- Focusrite Scarlet 8i6 in, Card 3, 1 Device
and here is the configuration for kernel modules and alsa. The kernel module options make sure that the modules are loaded in the same order every boot.
# Alsa kernel modules' configuration file. # ALSA portion alias char-major-116 snd options snd major=116 cards_limit=5 slots=snd_aloop,snd_hda_intel,snd_hda_intel,snd_usb_audio,snd_usb_audio # Loopback alias snd-card-0 snd_aloop options snd_aloop index=0 # Internal Audio and NVidia HDMI Audio alias snd-card-1 snd_hda_intel alias snd-card-2 snd_hda_intel options snd_hda_intel index=1,2 # USB: index 3 = Scarlett 8i6, 4 = Rocksmith Adapter alias snd-card-3 snd_usb_audio alias snd-card-4 snd_usb_audio options snd_usb_audio index=3,4 vid=0x8002,0x00ff pid=0x1235,0x12ba
The alsa config snippet gives some nicer names to the hardware cards. We use these later.
pcm.hdmi0 { type hw card NVidia device 0 hint.description "HDMI Audio Output" } ctl.hdmi0 { type hw card NVidia device 0 } pcm.hdmi1 { type hw card NVidia device 1 hint.description "HDMI Audio Output" } ctl.hdmi1 { type hw card NVidia device 1 } pcm.hdmi2 { type hw card NVidia device 2 hint.description "HDMI Audio Output" } ctl.hdmi2 { type hw card NVidia device 2 } pcm.hdmi3 { type hw card NVidia device 3 hint.description "HDMI Audio Output" } ctl.hdmi3 { type hw card NVidia device 3 } pcm.analog { type hw card Generic device 0 hint.description "Internal HD audio, analog" } ctl.analog { type hw card Generic device 0 } pcm.digital { type hw card Generic device 1 hint.description "Internal HD audio, optical digital" } ctl.digital { type hw card Generic device 1 } pcm.scarlett { type hw card USB device 0 hint.description "Focusrite Scarlett 8i6 USB" } ctl.scarlett { type hw card USB device 0 } pcm.rocksmith { type hw card Adapter device 0 hint.description "Rocksmith USB Adapter" } ctl.rocksmith { type hw card Adapter device 0 } pcm.default pulse ctl.default pulse
The alsa-setup.service
restores the alsa cards settings from a file
in ~/.config/alsa/<CARD_ID>.state
. Unfortunately this is not enough for my
Focusrite Scarlett 8i6, the Channels are muted unless they are
toggled on/off one time. So the alsa-setup
script also calls
~/.config/alsa/<CARD_ID>.setup
with the CARD_ID
as parameter to
do any further necessary setup.
Jack is started after pulseaudio, to give pulseaudio the chance to load its Jack bridging modules. It might be wise to disable the ALSA cards Jack should use in pulseaudio via pavucontrol.
In case jack can not switch to realtime mode when started from a user session systemd service, but does it just fine from the X11 session dbus, check if /etc/pam.d/systemd-user contains the line
session required pam_limits.so
and, if not, add it.
jack.service
starts the DBus variant of Jack (Jack2). It stores
its configuration in ~/config/jack/conf.xml
. For ease of importing
these settings into dependent service unit files, the settings are
exported into a shell variable like environment file in
~/.config/jack/conf.env
.
Additional services for a ALSA-MIDI/Jack-MIDI bridge and the import of the ‘digital’ ALSA card into Jack exists, which read this environment file.
I want Pulseaudio for the ease of integrating non Jack-aware desktop applications. It is bridged to Jack via module-jack-source and module-jack-sink. Pulseaudio writes an error about not beeing able to set realtime scheduling for the jack modules into the journal, despite the correct parameters in the service files. There is an open issue for this in the PulseAudio bugtracker. I think this is only on issue if you run Jack in sync-mode.
Systemd and DBus need to support User-Session semantics for this
setup to work. In Gentoo they need to be emerged with the
user-session
USE flag.
The package uses environment generators to make plugin paths and to
put jack parameters into the environment for usage in dependent
services. I also makes a file ~/.profile.env
, with these variables
and the ones from ~/.config/environment.d/*.conf
, which can be
sourced from a shell startup script.
Copy or link user-environment-generators/audio-plugin-path-generator
into
/etc/systemd/user-environment-generators
and enable
pulseaudio.service, jack.service and any other services you like.