Ted's Linux MIDI Guide

By: Ted Felix

Introduction

Linux is a great OS for MIDI. The problem is that you've got to understand a lot about Linux to get started. This guide is intended to help ease the transition.

audio group

Audio software needs to run at a higher priority and with memory locked so that it doesn't swap out to the hard disk. To give a user that power, we create an "audio" group, give that group some special privileges, then add the user to that group.

In case your system doesn't have an "audio" group, try this to make sure:

sudo groupadd audio

The chances are good you'll see a message indicating that the group 'audio' already exists. That's fine. Next we'll give the audio group some elevated privileges. For this we need to make some changes to the /etc/security/limits.conf file. Edit this file with your favorite editor. I usually use nano:

sudo nano /etc/security/limits.conf

Now add the following lines to the end of the limits.conf file:

@audio           -       rtprio          100
@audio           -       nice            -10
@audio           -       memlock         429612

Those lines give the audio group the ability to elevate nice priority up to -10 (the highest is -20), and real-time priority to 100 (the highest is 99). The memlock line lets a member of the audio group lock 430MB worth of memory.

Now we need to add ourselves to the audio group. We can use usermod to do this. Assuming your user ID happens to be "ted":

sudo usermod -a -G audio ted

This change will not take effect immediately. You must logout then log back in again. Use the "groups" command to see if you were successfully added to the audio group.

ALSA

ALSA, the Advanced Linux Sound Architecture, is the part of the Linux kernel that talks to your sound-related hardware, like sound cards and MIDI interfaces. It is made up of device drivers and other kernel modules that provide useful audio-related functions. Many distros already have all the ALSA-related parts of the kernel built-in, so all you have to do is plug in your hardware and use it.

pulseaudio

pulseaudio sits on top of ALSA and allows more than one program to access the audio hardware. Many distros have pulseaudio installed by default. Try it. Try listening to an Internet radio station via an online player, then launch your favorite media player (Banshee, Rhythmbox, etc...) and play something. If pulseaudio is running, you'll hear both.

fluidsynth

fluidsynth is a software synthesizer or "softsynth". It can convert MIDI data into sound by using a "soundfont". On an apt-based distro (Ubuntu, Debian, Mint...), you can do the following to get fluidsynth and a soundfont installed:

sudo apt-get install fluidsynth
sudo apt-get install fluid-soundfont-gm

Other distros should have similar packages available. To play a MIDI file called "song.mid":

fluidsynth --audio-driver=alsa /usr/share/sounds/sf2/FluidR3_GM.sf2 song.mid

For testing, there are many sites with free midi files to download. Just search on "midi files".

To stop fluidsynth, type "quit" at its ">" prompt. We'll need to stop fluidsynth for the next section.

aplaymidi

Instead of having fluidsynth play a MIDI file, we can also have fluidsynth make music from MIDI data that comes from other programs. To test this, we'll use the program aplaymidi which is part of the "alsa-utils" package. In apt-based distros:

sudo apt-get install alsa-utils

Now we'll run fluidsynth as a server. This means that it will run and wait for other programs to connect to it and send it MIDI data.

fluidsynth --server --audio-driver=alsa /usr/share/sounds/sf2/FluidR3_GM.sf2

You'll want to leave that running and bring up another terminal window. There you can use aplaymidi to find out what port number fluidsynth is waiting on:

aplaymidi -l

Here's what mine shows:

 Port    Client name                      Port name
 14:0    Midi Through                     Midi Through Port-0
128:0    FLUID Synth (2825)               Synth input port (2825:0)

Note that fluidsynth is on port 128:0. We'll need to use that to let aplaymidi know where to send MIDI data:

aplaymidi -p 128:0 song.mid

To stop fluidsynth, type "quit" at its ">" prompt. We'll need to stop fluidsynth for the next section.

qsynth

Getting fluidsynth to do things takes a lot of typing. In true Unix/Linux fashion, you can put those long commands into a script. Or you can use qsynth which provides a GUI frontend for fluidsynth. To install:

sudo apt-get install qsynth

Now launch qsynth in the background:

qsynth &

You'll need to wander through the GUI to get the proper settings in place. First, you may have received some error messages regarding JACK. For now, ignore those as we are going to use ALSA. Go to "Setup..." and switch to the "Audio" tab. Under "Audio Driver:" pick "alsa". We'll also need a soundfont loaded, so switch to the "Soundfonts" tab and open the soundfont that we've been using with the command line. Now test with aplaymidi as usual:

aplaymidi -p 128:0 song.mid

A Virtual MIDI Keyboard

In case you don't have a physical MIDI keyboard, you can use a virtual one. For this tutorial, we'll use vmpk, the Virtual MIDI Piano Keyboard. To install and run:

sudo apt-get install vmpk
vmpk &

It's not going to work until we connect it to fluidsynth. We'll use the "aconnect" command to do that. First, we need to check which MIDI ports fluidsynth and vmpk are on. "aconnect -i" will show us the MIDI "input" ports:

$ aconnect -i
client 0: 'System' [type=kernel]
    0 'Timer           '
    1 'Announce        '
client 14: 'Midi Through' [type=kernel]
    0 'Midi Through Port-0'
client 129: 'VMPK Output' [type=user]
    0 'VMPK Output     '

From this we can see that "VMPK Output" is on port 129:0. Note that the "0" on the 'VMPK Output' line is the 0 after the colon. Next we use "aconnect -o" to make sure fluidsynth is where it usually is:

$ aconnect -o
client 14: 'Midi Through' [type=kernel]
    0 'Midi Through Port-0'
client 128: 'FLUID Synth (3206)' [type=user]
    0 'Synth input port (3206:0)'
client 130: 'VMPK Input' [type=user]
    0 'VMPK Input      '

Sure enough, fluidsynth is at 128:0. Now to connect the two together:

aconnect 129:0 128:0

And you should hear piano when you play the keys on vmpk. If not, try changing the instrument in the "Program:" field. Sometimes fluidsynth needs a reminder of what instrument to play.

patchage

If you prefer something a little more graphical when connecting MIDI devices, try patchage:

sudo apt-get install patchage
patchage &

patchage shows your MIDI devices as boxes. You can make connections by drawing lines between the boxes. You may see many errors related to JACK. Ignore them for now as we are focusing on ALSA.

A Hardware MIDI Controller

There are several MIDI controllers on the market that connect via USB. I have the Akai LPK25. When I plug it in and take a look at my MIDI devices, I see the following:

$ aconnect -i
client 0: 'System' [type=kernel]
    0 'Timer           '
    1 'Announce        '
client 14: 'Midi Through' [type=kernel]
    0 'Midi Through Port-0'
client 20: 'LPK25' [type=kernel]
    0 'LPK25 MIDI 1    '

So 20:0 is the LPK25. I can connect it to fluidsynth (which happens to be at 129:0 for me right now) using patchage or aconnect:

aconnect 20:0 129:0

Since the LPK25 is a very simple little controller I need to go into qsynth to set the instrument for it. The "Channels" button brings up a window where I can select the instrument for channel 1.

A Hardware MIDI Interface

If you want to connect external MIDI devices like keyboards with MIDI ports, you'll need a hardware MIDI interface like the M-Audio Uno MIDI Interface. When I plug mine in, I get the following new port:

client 20: 'USB Uno MIDI Interface' [type=kernel]
    0 'USB Uno MIDI Interface MIDI 1'

Once you've got the port showing up, you can connect a keyboard or other MIDI device to the interface and talk to it through that port.

JACK

Up to now we've been avoiding JACK. I've had a lot of trouble with JACK, so I figured it would be a good idea to show how some things can be done without JACK. This way you'll have a better idea whether JACK is causing trouble, or something else.

You can think of JACK as an improved pulseaudio. Like pulseaudio, JACK lets more than one program send sound to the soundcard. Unlike pulseaudio, JACK is designed to meet the demanding needs of audio professionals.

There are two versions of JACK: JACK1 and JACK2. These are interchangeable, but you'll find that certain versions don't work well with other programs like fluidsynth. I've found that JACK1 version 0.121.2 and fluidsynth 1.1.4 work well together. It's a good idea to learn how to build software so you can always run the latest versions. Although JACK1 is the main version of JACK, I've found JACK2 to be a bit less version sensitive. So, let's install it:

sudo apt-get install jackd2

To run the JACK Daemon (jackd) do the following:

jackd -d alsa --period 256 --device hw:0 --rate 44100

To run fluidsynth with JACK:

fluidsynth --server --audio-driver=jack --connect-jack-outputs /usr/share/sounds/sf2/FluidR3_GM.sf2

Setting the period to 256 when starting jackd is important for reducing latency and it also helps fluidsynth work better. To see what I mean, try setting the period to 2048 and play something through fluidsynth using aplaymidi. The timing will be completely messed up. You should experiment with your hardware and see how low you can set this number without having a negative effect on the sound. It is a power of two, so the next smallest is 128.

Stopping JACK isn't as easy as stopping fluidsynth. You'll need to use killall. First, stop fluidsynth by entering the "quit" command at fluidsynth's ">" prompt. Then use killall to stop JACK:

killall jackd

JACK and Headphones

On my laptop (an HP G62) I noticed that whenever I plugged in my headphones, the speakers would go off, but there would be no sound on the headphones. It turns out that my particular laptop has separate output channels for the speakers and the headphones. If you happen to be unlucky enough to have the same problem, see my JACK and Headphones page for details. Later versions of the Linux kernel fixed this for me.

qjackctl

If you prefer a nice GUI, qjackctl provides one for JACK. Install it and run it:

sudo apt-get install qjackctl
qjackctl &

You'll need to configure JACK through qjackctl before using it. Press the "Setup..." button to get the Setup dialog. Many of the settings will be set to "(default)" and that should be ok. Just make sure "Frames/Period" is set to 256, and "Sample Rate" is set to 44100. Close the Setup dialog and press the "Start" button to start JACK.

Now you can use qsynth to launch fluidsynth. Launch qsynth and press the "Setup..." button to get qsynth's setup dialog. Under the "Audio" tab, change the "Audio Driver" field to "jack". Make sure the "Auto Connect JACK Outputs" checkbox is checked. Click on Ok and restart the server.

At this point, qsynth hangs for me. This is why I stick to the command line. These GUI tools tend to be unreliable.

My Audio Script

Here's the script I use to get JACK and FluidSynth up and running:

#!/bin/bash

# Script to launch audio servers for music making.

case $1 in

  start )
    # Start JACK
    # fluidsynth and jackd only seem to get along at period 32 or 256.
    # At other periods, they both just crash and disappear.  I get a lot
    # of gaps (xruns) at 32.  So 256 is safest.
#    jackd -d alsa --period 256 --device hpfix --rate 44100 \
#      1>/tmp/jackd.out 2>/tmp/jackd.out &
    # As of Ubuntu 11.10, headphones are fixed for the G62.
    jackd -d alsa --period 256 --device hw --rate 44100 \
      1>/tmp/jackd.out 2>/tmp/jackd.out &

    # Start fluidsynth
    fluidsynth --server --no-shell --audio-driver=jack \
      --connect-jack-outputs \
      /usr/share/sounds/sf2/FluidR3_GM.sf2 \
      1>/tmp/fluidsynth.out 2>/tmp/fluidsynth.out &

    sleep 1

    if pgrep jackd && pgrep fluidsynth
    then
      echo Audio servers running.
    else
      echo There was a problem starting the audio servers.
    fi

    ;;

  stop )
    killall fluidsynth
    killall jackd
    echo Audio servers stopped.
    ;;

  * )
    echo Please specify start or stop...
    ;;
esac

I call it "audio" and keep it in ~/bin. To use it, just tell it whether you want to start or stop the audio servers:

audio start
audio stop

It's not perfect (piping the output to a fixed name in /tmp is never a good idea), but it's a start. Feel free to make improvements and send them to me. It is licensed under the GPLv3+.

MIDI Sequencers

Once you've figured out how to get all your MIDI hardware and softsynths set up, you can install and use a MIDI sequencer for serious music composition work. Two of the best are Rosegarden and Hydrogen.

Rosegarden is a MIDI sequencer that offers multi-track recording and playback along with notation editing.

Hydrogen is a drum sequencer. It has its own softsynth built in, so it comes up ready to go.

Audio Software

Audacity - Sound editor. Also does multi-track recording.

Ardour - Digital audio workstation.

Building Software

If things aren't working right, don't be afraid to download, build, and install the latest source for JACK, fluidsynth, or anything else. While writing this, I couldn't get many things to work. The solution was to build and install the latest source. Then everything was working fine.

This isn't always an easy process, but once you get the hang of it, it isn't too bad.

Real-Time Kernels

You may hear talk of using a real-time kernel when doing audio work. While you can do this if you want, it's not usually necessary. Modern Linux kernels on fast machines usually work just fine for audio applications. That said, there are three things that I always adjust when I build my own kernel. All three of them are under the category "Processor type and features." The first is the "Processor family". I set this to the latest processor that is closest to the processor in my machine. As an example, my current laptop is a Core i3, so I set the Processor family to "Core 2/newer Xeon". This should give better performance. I set "Preemption Model" to "Preemptible Kernel (Low-Latency Desktop)". This gets the kernel a little bit closer to real-time performance. Finally, the "Timer frequency" should be set to 1000Hz for decent audio performance.

My steps for building my own kernel are in my Linux Kernel Build HOWTO.

License

Copyright (C) 2011-2012, Ted Felix

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. See http://www.gnu.org/licenses/fdl.html for the full text of this license.

<- Back to my Linux page.

Copyright ©2011-2012, Ted Felix. Disclaimer