Installing a Raspberry Pi as a Jamulus client for remote choir
During these lockdown times, London City Voices has been working hard to find ways for the choir to continue to come together and sing online. While systems like Zoom are great for chatting and listening to “one-way” singing, they don’t work well for group singing due to the significant audio delay and their in-built correction and “catch-up” algorithms. Richard Swan, our choir Director, discovered Jamulus, an audio collaboration tool designed for low-latency, and some of us have been experimenting with it, but it requires a computer to run, which excludes members who either don’t have a computer or only have a work computer on which they aren’t allowed to install software. Our mission was to create a low-cost solution to access Jamulus, so the Raspberry Pi seemed like a great starting point.
This article is intended for people familiar with installing and maintaining Linux systems who are looking to create a Jamulus “appliance” from a Raspberry Pi, either for themselves or for distribution to choir (or band) members using the automatic configuration described towards the end.
I’m assuming you’re familiar with, or at least curious about, configuring and using the Jamulus client. If you need guidance on setting up and running your own Jamulus server, please see my article on Creating and Running a Jamulus Server in Amazon EC2.
Having read some recent reviews (here and here) of which micro SD cards work best with the Raspberry Pi, I settled on the Samsung Evo Plus, and bought a 32GB card from Amazon. You will need either a micro SD card reader, or you can use a standard SD card reader and an adapter, one of which comes with the Evo Plus card I bought.
I downloaded and installed the Raspberry Pi Imager on my Mac.
I then inserted my new microSD card and adapter into the SD card reader on my Mac and started the Raspberry Pi Imager app, selected my OS as Raspberry Pi OS (32-bit) and selected my new SD card. It imaged the card in just a few minutes
Next I plugged everything into my Raspberry Pi:
- The micro SD card (now removed from the adapter)
- A network cable (remember, the point of this is low-latency music so we won’t be using Wifi)
- A USB keyboard
- A USB mouse
- A USB microphone (see advice below)
- A Micro-HDMI to HDMI adapter and into that I plugged the HDMI cable to my monitor (One can be purchased with your Raspberry Pi for under £4)
- Lastly, a USB-C power adapter. In my case, it was the one from my MacBook Pro, but many Android phones use the same standard or they can be purchased with your Raspberry Pi for under £10.
With the power attached, the Pi booted up. It automatically resized the partition on the SD card and rebooted. After this, the graphical desktop started and the Welcome to Raspberry Pi screen appeared and took me through the initial configuration of the system. Relevant parts included:
- When prompted, I changed the password for the “pi” user
- I skipped joining a wireless network (for Jamulus, we need to be wired)
- I performed the software update when offered
Once complete, I chose to restart and then the system came up as normal, booting into the graphical desktop.
I opened a Terminal from the menu and enabled SSH:
sudo systemctl enable ssh
sudo systemctl start ssh
The avahi-daemon runs by default, allowing me to connect easily with
ssh email@example.com a system on my local network running Bonjour (ie MacOS, Linux systems running avahi-daemon or from Windows running Bonjour services).
From here on, I found it easier to SSH to the Pi from my Mac and configure things. You could continue to configure on the Pi desktop itself if you wish.
We aren’t going to use the Pi’s onboard soundcard, so in order to give me more predictable audio device numbering within ALSA I disabled this device by adding a new file at
To force a graphical desktop to start, regardless of whether a monitor was connected to the HDMI, I uncommented the following to
I then rebooted for these settings to take effect:
I installed Jamulus following the instructions on the wiki: https://jamulus.io/wiki/Installation-for-Linux
sudo apt-get install build-essential qt5-qmake qtdeclarative5-dev qt5-default qttools5-dev-tools libjack-jackd2-dev qjackctl
tar -xvf latest.tar.gz
sudo make install
I played around with
qjackctl to determine the Jack settings I needed. You don’t have to do this if you use my startup script below. In summary, the settings recommended by the Jamulus wiki page resulted in:
/usr/bin/jackd -R -dalsa -dhw:1 -r48000 -p128 -n2
The choice of
hw:1 was mine so it always uses the first USB sound device connected, as we already disabled the onboard soundcard.
To make things start happening when the desktop starts, I created the following autostart application by adding a new file as root at
The above calls our main startup script, which I placed at
The only thing to configure in here is the address of the Jamulus server as
I then made this script executable:
chmod 755 /home/pi/lcv_startall.sh
After another reboot, the Pi will now boot and start jackd and Jamulus, automatically connecting you to your chosen server.
At this stage, we have a fully working Jamulus client, provided we have a monitor, keyboard and mouse attached. Sending these devices to choir members without this additional hardware will still work; they could plug in just a network cable, a suitable USB microphone (see below) and USB-C power, but will not have the ability to mute themselves or adjust their profile details or personal mixer settings.
Remote VNC Access (optional)
Being able to use the Pi without owning a monitor, keyboard or mouse was a desirable feature. Taking the steps from this ReadVNC guide, I registered for a free RealVNC account for personal use at https://www.realvnc.com/raspberrypi/#sign-up
I then enabled the VNC server on the Raspberry Pi:
- Go to Interface Options -> VNC
- Answer Yes to Would you like the VNC Server to be enabled?
- Confirm VNC has been enabled by clicking OK
- Select Finish to exit
Note, you cannot perform the following step if you intend to clone this Pi image for multiple users — you should wait and do it with the individual users to allow them to control their own RealVNC accounts. In the graphical desktop of the Pi, in the top-right (near the clock) a RealVNC logo appeared. I clicked on that icon and selected the link to sign in to enable cloud connectivity and logged in to the RealVNC account I created a moment ago. It then guided me to add this Raspberry Pi to my “team”, which will allow me to log into it remotely later.
I installed the RealVNC app on my iPhone (Android, Windows/Mac/Linux versions also available), and by logging into my RealVNC account, I was able to see my RaspberryPi appear in my “team”, then connect to it using the same login user and password that I set use for SSH (username pi and the password I set during the initial setup).
This allowed me to boot the Raspberry Pi with only the network cable and USB microphone connected, with no further need for monitor, keyboard or mouse. The graphical desktop still starts and Jamulus starts up and connects to our server. If we want to control Jamulus, we can connect to the Pi via RealVNC from our phone, tablet or laptop.
Now we have a choice whether to use the Raspberry Pi with a monitor, keyboard and mouse or to use it via the RealVNC client on another device.
And we’re done! Or are we…
Automatic configuration (optional)
At this point, I had an SD card which we could clone to create many Pis that would auto-connect to our Jamulus server, but they would all have blank user profiles with no name, no voice part (“instrument”), etc. While choir members could attach a monitor, keyboard and mouse, or use the RealVNC client to edit their Jamulus profiles, this requires them to either own this additional hardware or to make some quite fiddly changes via their phones/tablet screens.
I decided to add a config file to the
/boot partition to configure a few things. As the
/boot partition is of type VFAT, it means it can be easily edited on a Mac or Windows system before sending to the recipient. This config file was created as
/boot/lcv_config.txt and contains:
I added a parameterised template for Jamulus.ini at
/home/pi/Jamulus.ini.template (It’s too long to include here — full file available at https://gist.github.com/jal25jal25/cb2b3fb77594ebd0a6dcfbe1e789ac9d)
I then updated my main startup script (
/home/pi/lcv_startall.sh) to source the config file and to create a new Jamulus.ini from the template. It does this only if
lcv_config.txt is newer than the current Jamulus.ini to prevent constant re-writing. I allowed the server address and jackd frames-per-period to be specified in
lcv_config.txt, but I left configurable defaults in
lcv_startall.sh in case
lcv_config.txt couldn’t be read for some reason.
Do remember to update the value of
JAMULUS_SERVER_DEFAULT and optionally
Microphones / Interfaces
In terms of sound interface / microphone, we have tested this solution with the following:
- Blue Yeti (use the 3.5mm headphone on the Yeti)
- M Audio Fast Track Pro + microphone in the XLR jack + headphones plugged into the 1/4” headphone monitor port
- Behringer U-PHORIA UM2 interface with microphone and headphones
Tested, but not recommended for singing:
- A Cheap Plantronics “Blackwire C510-M” USB headset (sound quality too poor for singing)
- A $10 USB sound interface called “3D Sound” that has just two 3.5mm jacks, one for mic and one for headphones. This presents itself as “C-Media Electronics, Inc. Audio Adapter (Planet UP-100, Genius G-Talk)” and looks like this. I’m doubtful of the audio quality on this one.
I will add more hardware to this list as we confirm them as working.
Genuine singing with real people is something we’ve really missed over the last few months. Although we’re still physically remote, this is a much better experience despite the technical hurdles.
I hope some or all of this has been useful to you.