Using a USB midi keyboard on Ubuntu
I've been using Ubuntu since 2006, but even after 13 years I still dual boot with Windows. There's still a few things that keep me from going Linux-only. Mostly that's games, but there's a few other things that Linux unfortunately does not excel at. One of those things is anything related to music and sound.
While sound in general has dramatically improved over the last 13 years, connecting any musical instrument typically spells trouble.
I have an M-Audio Keystation Mini32 that I like to use for, well, simply playing some notes. On windows, it's pretty much plug-and-play. On Linux, that's not quite the same experience, tho it was less cumbersome than I initially thought it would be.
My system
First some details about my system. I'm using Kubuntu 18.04. That probably means this guide will also work on other Ubuntu variants, as well as Ubuntu derivatives such as Linux Mint.
Large parts of this guide may also work on other linux distros, but YMMV.
Getting started
While not exactly plug-and-play, when connecting the keyboard, the machine does immediatelty detect the keyboard and key presses are in fact registered. This even works before installing any packages.
You can check whether your MIDI device was detected with the following command:
aconnect -i |
This should list all connected MIDI devices. On my machine, with my keyboard plugged in the USB port, this returns:
client 0: 'System' [type=kernel] |
So we can see the Keystation Mini32 show up. We can now see the key presses being registered by running:
aseqdump -p <client_id_of_the_device> |
When I press and release a C, this shows:
Waiting for data. Press Ctrl+C to end. |
This is all nice and well, but we don't hear anything yet. For that, we need to install some packages.
Installing required packages
To actually hear some notes we need to install a number of packages.
- qsynth
- jackd
- qjackctl
All three live in the default repositories, so can simply be installed with
sudo apt install qsynth jackd qjackctl |
Qsynth
Qsynth is a GUI wrapper around the fluidsynth software synthesizer.
This will be the application that actually converts MIDI signals to
audible sound. You will need at least one soundfont file to be able
to hear anything. Thankfully, the qsynth
package on Ubuntu comes
with the fluid-sountfont-gm
package which provides a soundfont file.
jackd & qjackctl
Jackd is where things get hairy.
Jack is an 'audio connection kit', that allows applications to connect
sound streams to other applications. It comes with a server, jackd
,
that performs all the routing between applications (which then function
as jack clients).
It is unfortunately not the most intuitive application. Hence, we need
a small GUI, qjackctl
to configure, start, and stop jackd.
Configuring jackd
After installing the required packages, we need to configure jackd.
Open the jack GUI by typing qjackctl
in a terminal. This should give
you something like this:
In here, we need to go to "Setup" to change some settings.
- Untick the realtime radio button (more info at the bottom of this page)
- Change the number of frames per period to 512.
- Go to the "advanced" tab and tick the "soft mode".
Stay in the the "advanced" tab, while opening a terminal. By default, jackd is assuming your output device lives on card 2, with subdevice 0. This isn't always the case, and in my case, actually changes at each reboot. Unfortunately this means I may have to re-configure jackd at each reboot.
To check what your current output device is, run aplay -l
in a terminal.
This returns something like:
**** List of PLAYBACK Hardware Devices **** |
Which device you are looking for depends on your situation. If you
have connected your PC to a TV, it's going to be one of the HDMI
devices. If you used the headphone jack, it's going to be the Analog
device. In any case, the format is going to be hw:{card},{subdevice}
.
E.g, with headphones connected, in this case it's going to be hw:0,2
.
Fill in this string in the "advanced" tab under "Output device".
Your setup should now look like:
Getting ready to play some notes
You can now close the Setup screen and start jackd. You may hear an audible thump.
If, at this stage, you get an error stating Cannot write socket fd = {x} err = broken pipe
,
that means your setup uses the wrong output device. It may be a bit of trial
and error figuring out which output device you need.
Once jackd is started, you can finally launch qsynth.
A window grossly looking like the following should open.
Go to Setup, and load the soundfont file in the Soundfonts tab.
If qsynth was installed through apt, you'll have a soundfont file in
/usr/shares/sounds/sf2
Now, we are almost done configuring things. We now need to go back to qjackctl. Now, hit connect. Go to the Alsa tab - strangly not the Midi tab. You'll see your midi device listed on the left side, and qsynth listed on the right side. You'll want to connect both. Select both, then hit the connect button, and a line connecting your midi device to qsynth should show up.
Now, finally, you should be able to hear you play a nice piano sound on your midi keyboard! Wooohoo, playing with a midi keyboard on Linux!
But wait, now I can't hear anything else?!
Yes, now you are able to use your midi keyboard, but that'll be the only sound you'll now hear. We've broken audio. Oops.
This is due to jackd not working nicely with pulseadio. Pulseadio is the sound server that practically all other applications use. While jackd is active, applications using pulseadio will not produce any audio.
There is a way to fix this. We need to install yet another package.
sudo apt install pulseaudio-module-jack |
This will install a pulseaudio module that allows one to tell pulseaudio to send its output streams to jackd.
Once installed, go back to qjackctl, and re-open the setup screen.
Now go to the Options tab, and enter the following under the
Execute script after startup
radio button:
pactl load-module module-jack-sink channels=2; pactl load-module module-jack-source; pactl set-default-sink jack_out |
This will, just after startup of jackd, tell pulseaudio to send its output to jack.
Restart the jack server, reconnect your keyboard to qsynth, and lastly
run pulseaudio -k
. This will restart pulseadio.
Now you should have regular sound (you may have to reload YouTube videos), while simultaneously using the midi keyboard :-).
Conclusion
So it is possible to use a USB midi keyboard on Linux without horribly breaking the sound system, but some things could definitely be a bit smoother.
For one, I don't understand why pulseaudio-module-jack
doesn't come as
at least a recommended package when installing jackd
. It seems to me that
running jackd and pulseaudio at the same time on a modern Linux desktop is
a very logical thing to do. It would be even greater if jackd would come
preconfigured with pulseaudio working out of the box.
Anyway, I am happy with getting my midi keyboard to work. One reason less to keep dual booting!
Addendum: latency and real-time
We unticked the 'realtime' radio button in our jackd setup. That makes it more probably that jackd boots up, but may not be optimal.
While playing instruments, we usually want our latency to be as low as possible. To get the lowest latency possible, you should grant realtime priority to jack (or actually, you should use a realtime kernel as well). Doing so, however, means you have to configure your user to be able to grant realtime priority.
To do so, you need to create the /etc/security/limits.d/99-realtime.conf
file with
the following contents:
@realtime - rtprio 99 |
Add your user to the realtime
group, and start a new session (log out and back in).
If realtime priorities are misconfigured, jackd will not start.