wanderings/content/posts/midi-on-rpi.md

5.2 KiB

+++ title = "Arch on a Raspberry Pi - sound and MIDI" date = 2020-09-26 tags = ["raspberry pi"] toc = true +++ This post follows a first one on [basics of Arch onto a Raspberry Pi][arch-basics]. Now we will see how to have high quality, low latency sound and a MIDI keyboard on this beautiful but still useless system.

MIDI keyboard with JACK

To reliably output sound using a MIDI keyboard and have a reasonable latency, consider dropping pulseaudio, installing and setting up JACK, and setting up fluidsynth to use JACK.

Disable pulseaudio's autostart with systemd

Run as the relevant user :

$ systemctl --user mask pulseaudio.socket

Setup JACK

First install the jack2 package, and enable it at login with :

$ systemctl --user enable jack@lowlatency.service

The @ argument sets a JACK configuration file that will be searched in the following places, first match wins :

~/.config/jack/lowlatency.conf
/etc/jack/lowlatency.conf

If you use a DAC, drop a second conf file in ~/.config/jack/MYDAC.conf. For instance HifiBerry-style DACs are identified as device hw:sndrpihifiberry. In this case create ~/.config/jack/hifiberry.conf as follows, and instead of the former, enable jack@hifiberry.service :

# The name of the JACK server
JACK_DEFAULT_SERVER="default"
# Options to JACK (e.g. -m, -n, -p, -r, -P, -t, -C, -u, -v)
JACK_OPTIONS=""

# Audio backend (e.g. alsa, dummy, firewire, netone, oss, portaudio)
DRIVER="alsa"
# Device name (used by the audio backend) - defaults to "hw:0"
DEVICE="hw:sndrpihifiberry"

# Specific settings for the audio backend in use
DRIVER_SETTINGS="-n2 -p128 -r48000"

Note that JACK_OPTIONS is empty ; all the useful options go in DEVICE_SETTINGS. I suppose it's a bug of the JACK service file.

More about DACs at the end of the post.

Setup fluidsynth

Install the fluidsynth package ; it comes with a default user service that will connect to the JACK service if you tell it to in its conf file ~/.config/fluidsynth. First do :

$ systemctl --user enable fluidsynth

You will need a soundfont in /usr/share/soundfonts/default.sf2. I actually made it a symbolical link to a soundfont file in my home dir. If you're desperate about soundfonts install the soundfont-fluid package.

JACK2 is said to need package a2jmidid to detect MIDI keyboards. I've noticed that in fact fluidsynth was very capable of detecting them on its own with the option -o midi.autoconnect=1, be it at boot or hotplugged.

A useful feature is that it can read a command file with the -f option ; an arguably preferable strategy is to create and load one in

/usr/share/soundfonts/fluidsynth.command

Finally my ~/.config/fluidsynth reads as follows :

# Mandatory parameters (uncomment and edit)
SOUND_FONT=/usr/share/soundfonts/default.sf2

# Additional optional parameters (may be useful, see 'man fluidsynth' for further info)
# -C0 disables chorus
# -R0 disables reverb
# -g0.2 would be the default gain
# -m can be jack, alsa, alsa_seq or raw ? jack should be more efficient
# -K number of MIDI channels (minimum 16)
# -f command file input
OTHER_OPTS="-a jack -j -f /usr/share/soundfonts/fluidsynth.command -o midi.autoconnect=1 -o synth.polyphony=64"

Its systemd service's default target used to be "multi-user" whereas it should have been "default" (bug resolved as of version 2.1.5-2). One can now enable it with On older versions of the program, you had to do instead : systemctl --user add-wants default fluidsynth

Autostart

If you want the systemd user services started at boot do as root :

# loginctl enable-linger YOURUSERNAME

Deal with latency

To optimise latency, you will want to use a realtime process for jackd.

You can follow [instructions for Arch][aw-instr] to have the right to make your process prioritary on system tasks. Eventually, you should belong to the realtime group. After that jackd should detect it's able to run a realtime process and proceed. You can check that it does with

journalctl --user -u jack@hifiberry -e

(replace hifiberry with the config name you gave at the beginning of this post). The -e option jumps at the end of the logs.

I was only able to use the alsa-seq MIDI plugin with JACK, but some people report more effectiveness with jack's own plugin. You can check [Archwiki's JACK page][aw-jack-midi] for detailed instructions.

Another [Archwiki page on professional audio][aw-pro-audio] mentions a -Xalsarawmidi option in JACK used with a2jmidid to enhance MIDI jitter.

Use an external sound card

For Phat DACs, follow these [instructions][dac-instr]. What's a Phat ? It's a small cardboard that fits above a Raspberry Pi, plugged into its IO pins. And a DAC ? Digital to Analog Converter - in other words, an audio card.

[arch-basics]: {{< relref arch-on-rpi >}} [aw-instr]: https://wiki.archlinux.org/index.php/Realtime_process_management#PAM-enabled_login [aw-jack-midi]: https://wiki.archlinux.org/index.php/JACK_Audio_Connection_Kit#MIDI [aw-pro-audio]: https://wiki.archlinux.org/index.php/Professional_audio#MIDI [dac-instr]: https://www.hifiberry.com/docs/software/configuring-linux-3-18-x/