Recently I posted about my successful attempt to get LinuxSampler running on the Raspberry Pi. I’ve taken this a bit further and produced a script that turns the Raspberry Pi into a fully fledged piano. Don’t expect miracles, the sample library I used is good quality so the RPi might choke on it every now and then with regard to disk IO. But it’s usable if you don’t play too many notes at once or make extensive use of a sustain pedal. I’ve tested the script with a Class 4 SD though so a faster SD card could improve stability.
Edit: finally got around buying a better SD card and the difference is huge! I bought a SanDisk Extreme Class 10 SD card and with this SD card I can run LinuxSampler at lower latencies and I can play more notes at once.
Before you can run the script on your Raspberry Pi you will need to tweak your Raspbian installation so you can do low latency audio. How to achieve this is all described in the Raspberry Pi wiki article I’ve put up on wiki.linuxaudio.org. After you’ve set up your RPi you will need to install JACK and LinuxSampler with sudo apt-get install jackd1 linuxsampler. Next step is to get the Salamander Grand Piano sample pack on your RPi:
cd
mkdir LinuxSampler
cd LinuxSampler
wget -c http://download.linuxaudio.org/lau/SalamanderGrandPianoV2
/SalamanderGrandPianoV2_44.1khz16bit.tar.bz2
wget -c http://dl.dropbox.com/u/16547648/sgp44.1khz_V2toV3.tar.bz2
tar jxvf SalamanderGrandPianoV2/SalamanderGrandPianoV2_44.1khz16bit.tar.bz2
tar jxvf sgp44.1khz_V2toV3.tar.bz2 -C SalamanderGrandPianoV2_44.1khz16bit
--strip-components=1
Please note that decompressing the tarballs on the RPi could take some time. Now that you’ve set up the Salamander Grand Piano sample library you can download the script and the LinuxSampler config file:
cd
mkdir bin
wget -c https://raw.github.com/AutoStatic/scripts/rpi/piano -O /home/pi/bin/piano
chmod +x bin/piano
wget -c https://raw.github.com/AutoStatic/configs/rpi/home/pi/LinuxSampler
/SalamanderGrandPianoV3.lscp -O /home/pi/LinuxSampler/SalamanderGrandPianoV3.lscp
Almost there. We’ve installed the necessary software and downloaded the sample library, LinuxSampler config and piano script. Now we need to dot the i’s and cross the t’s because the script assumes some defaults that might be different in your setup. Let’s dissect the script:
#!/bin/bash
if ! pidof jackd &> /dev/null
then
sudo killall ifplugd &> /dev/null
sudo killall dhclient-bin &> /dev/null
sudo service ntp stop &> /dev/null
sudo service triggerhappy stop &> /dev/null
sudo service ifplugd stop &> /dev/null
sudo service dbus stop &> /dev/null
sudo killall console-kit-daemon &> /dev/null
sudo killall polkitd &> /dev/null
killall gvfsd &> /dev/null
killall dbus-daemon &> /dev/null
killall dbus-launch &> /dev/null
sudo mount -o remount,size=128M /dev/shm &> /dev/null
echo -n performance
| sudo tee /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor &> /dev/null
if ip addr | grep wlan &> /dev/null
then
echo -n "1-1.1:1.0" | sudo tee /sys/bus/usb/drivers/smsc95xx/unbind &> /dev/null
fi
jackd -P84 -p128 -t2000 -d alsa -dhw:UA25 -p512 -n2 -r44100 -s -P -Xseq
&> /dev/null &
fi
This is the first section of the script. An if clause that checks if JACK is already running and if that’s not the case the system gets set up for low latency use, a simple check is done if there is an active WiFi adapter and if so the ethernet interface is disabled and then on the last line JACK is invoked. Notice the ALSA name used, hw:UA25, this could be different on your RPi, you can check with aplay -l.
jack_wait -w &> /dev/null
jack_wait is a simple app that does nothing else but checking if JACK is active, the -w option means to wait for JACK to become active.
if ! pidof linuxsampler &> /dev/null
then
linuxsampler --instruments-db-location $HOME/LinuxSampler/instruments.db
&> /dev/null &
sleep 5
netcat -q 3 localhost 8888
< $HOME/LinuxSampler/SalamanderGrandPianoV3.lscp &> /dev/null &
fi
This stanza checks if LinuxSampler is running, if not LinuxSampler is started and 5 seconds later the config file is pushed to the LinuxSampler backend with the help of netcat.
while [ "$STATUS" != "100" ]
do
STATUS=$(echo "GET CHANNEL INFO 0" | netcat -q 3 localhost 8888
| grep INSTRUMENT_STATUS | cut -d " " -f 2 | tr -d 'rn')
done
A simple while loop that checks the load status of LinuxSampler. When the load status has reached 100% the script will move on.
jack_connect LinuxSampler:0 system:playback_1 &> /dev/null
jack_connect LinuxSampler:1 system:playback_2 &> /dev/null
#jack_connect alsa_pcm:MPK-mini/midi_capture_1 LinuxSampler:midi_in_0 &> /dev/null
jack_connect alsa_pcm:USB-Keystation-61es/midi_capture_1 LinuxSampler:midi_in_0
&> /dev/null
This part sets up the necessary JACK connections. The portnames of the MIDI devices can be different on your system, you can look them up with jack_lsp which will list all available JACK ports.
jack_midiseq Sequencer 176400 0 69 20000 22050 57 20000 44100 64 20000 66150 67 20000 &
sleep 4
jack_connect Sequencer:out LinuxSampler:midi_in_0
sleep 3.5
jack_disconnect Sequencer:out LinuxSampler:midi_in_0
killall jack_midiseq
This is the notification part of the script that will play four notes. It’s based on jack_midiseq, another JACK example tool that does nothing more but looping a sequence of notes. It’s an undocumented utility so I’ll explain how it is invoked:
jack_midiseq
<command> <JACK port name> <loop length> <start value> <MIDI note value> <length value>
Example:
jack_midiseq Sequencer 176400 0 69 20000 22050 57 20000 44100 64 20000 66150 67 20000
JACK port name: Sequencer
Loop length: 4 seconds at 44.1 KHz (176400/44100)
Start value of first note: 0
MIDI note value of first note: 69 (A4)
Length value: 20000 samples, so that's almost half a second
Start value of second note: 22050 (so half a second after the first note)
MIDI note value of second note: 57 (A3)
Length value: 20000 samples
Start value of third note: 44100 (so a second after the first note)
MIDI note value of second note: 64 (E4)
Length value: 20000 samples
Start value of third note: 66150 (so one second and a half after the first note)
MIDI note value of second note: 67 (G4)
Length value: 20000 samples
Now the script is finished, the last line calls exit with a status value of 0 which means the script was run successfully.
exit 0
After making the script executable with chmod +x ~/bin/piano and running it you can start playing piano with your Raspberry Pi! Again, bear in mind that the RPi is not made for this specific purpose so it could happen that audio starts to stutter every now and then, especially when you play busy parts or play more than 4 notes at once.
Using a Raspberry Pi as a piano: quick demo