Skip to content
This repository was archived by the owner on Sep 10, 2024. It is now read-only.

Overview

Rob Bultman edited this page Jul 27, 2020 · 1 revision

Welcome to the raspberry-jam wiki!

Raspberry Jam

Raspberry Jam is intended to be a dedicated hardware device for connecting musicians together with low latency for collaboration online.
The minimum requirements to assemble a Raspberry Jam are:

  • A Raspberry Pi (and necessary accessories, such as an SD card and power supply) and a soundcard.
  • A soundcard that connects to the Pi via the 40 pin GPIO header is preferred but not required, but at least 1 input and 1 output on the card are required (a list of suggested cards can be found here).
  • A USB soundcard can be used, but performance (ie latency) will suffer.
  • The Raspberry Pi 4 has been the version most tested, but other versions of the Pi should also work.
  • An internet connection is also required. A wired connection is highly recommended.

This tutorial assumes a basic knowledge of working with a Raspberry Pi, such as how to load an SD card image onto an SD card, etc. If you are completely unfamiliar with a Raspberry Pi there are many resources available on how to get started.

We now have an SD card image that includes the realtime kernel for the Pi 3 and Pi 4, and the software necessary for Raspberry Jam. The image is located here. If you would prefer to recreate your own image starting with a stock Raspbian image, notes on how to do that can be found here

Once you have the image up and running, install your soundcard per the instructions from the manufacturer (which will most likely involve editing /boot/config.txt).

Raspberry Jam is dependent on 2 key pieces of software Jack and JackTrip. Jack is... well I'll just quote the website " It provides a basic infrastructure for audio applications to communicate with each other and with audio hardware." JackTrip is the software than makes connections via Jack over the internet. In a JackTrip connection one participant starts JackTrip as a server and the other participants connect to that user as clients. In order to achieve a connection there is one other bit of prepwork that whomever is going to be the server needs to do, and that is to enable port forwarding on their home router to forward a UDP port range starting at port 4464 to the local IP address of the Raspberry Jam. The port range to be opened depends on how many participants plan to connect. The default port offset is 10, so client 1 would connect on 4464, client 2 on 4474, and so on. So when you enable port forwarding, enable a range to cover the number of clients you are likely to connect with. In the long run we would love to eliminate the need to enable port forwarding, but for now it is a necessary step.

We are almost ready to start the Jack server, first lets check on our soundcard with this command:

cat /proc/asound/cards

Hopefully you see at least one soundcard listed, and hopefully at least one of them is the one you intend to use. The text inside the square brackets, ie [SOUNDCARD ] is the name of the soundcard. We will need this to tell Jack the soundcard you want to use.

Before we start Jack, you can run alsamixer to see what controls are available there for your soundcard:

alsamixer

Within alsamixer you can adjust parameters of the soundcard such as levels, routing and other options. As an example, for the Fe-Pi there is a switch for the input to come from either the headset MIC or LINE IN. If you are trying to use the MIC and the input is set to LINE IN your friend won't hear anything. Alsamixer can be run and adjusted at any point, even after the connection is made.

Now we are ready to start Jack, it is configured with command line switches as it is started, an example command would be:

jackd -P70 -dalsa -dhw:SOUNDCARD -r44100 -p128 -n2 -s -S &

The reason I say this is an example command, is that some of the switches may change depending on your setup. First off you'd substitute SOUNDCARD with the actual name you previously discovered, but the rate (-r) period (-p) and number of periods (-n) may also need adjustment. Note: jackd defaults to hardware device 0, so if you have disabled the onboard audio (which is done by default on the Raspberry-Jam image, and you only have a single soundcard and it is listed as device 0, you don't need to include the -dhw switch at all, jackd will default to using your soundcard).

The rate is the audio sample rate, and this needs to match between all participants. The rate I used here is 44.1kHz, which is CD quality. The rate can be increased to 48000 or 96000, etc, a higher sample rate will reduce latency while at the same time increasing bandwidth requirements.

The period, from the Jack manual is, "the number of frames between JACK process() calls. This value must be a power of 2, and the default is 1024. If you need low latency, set -p as low as you can go without seeing xruns. A larger period size yields higher latency, but makes xruns less likely. The JACK capture latency in seconds is --period divided by --rate." With the Pi 4, an I2S souncard and the realtime kernel a period setting of 128 seems stable, but YMMV. For a USB soundcard you'll probably want to start with 1024. This setting, like the rate, needs to be the same for all the participants. If it is not, you will get an error when jacktrip attempts to connect.

The number of periods is " the number of periods of playback latency. In seconds, this corresponds to --nperiods times --period divided by --rate. The default is 2, the minimum allowable." A setting of 2 works fine for the I2S cards, I have heard for usb devices that a setting of 3 is recommended.

The remaining switches are less likely to need adjustment, but you can see what they are here

With all that said, hopefully you now have Jack running, if you used the '&' switch you should be able to hit enter to get back to the command prompt so you can start jacktrip.

Starting jacktrip as a server is simple:

jacktrip -s -n 1

The -n switch is the number of channels transmitted. A setting of 1 will be the fastest, but the number of channels can be increased at the expense of latency. In order for clients to connect to the server, you will need to know the public IP address of the participant running jacktrip as a server (also remember they need to have port forwarding enabled). One way find this is to google 'IP' from a device on the same network and google will tell you your public IP. With that a client would start jacktrip with

jacktrip -c XXX.XXX.XXX.XXX -n 1

Where the Xs are the public IP of the server.

If everything goes according to plan the connection will be made. If both parties have all the audio settings correct and have mics connected and all that, they should hear each other.

A second participant would connect with the server with a port offset. The participant acting as the server would need to start another instance of jacktip in another terminal window like so:

jacktrip -s -o 10 -n 1

The second participant would connect with:

jacktrip -c XXX.XXX.XXX.XXX -o 10 -n 1

The -o switch is the port offset, any number of additional participants can be added by increasing the port offset, -o 20, -o 30, etc.

Once all of the participants are connected, the participant acting as the server should be able to hear all the participants (if everyone's audio is properly setup, routed, etc). Next the participant acting as the server needs to route the other participants audio to each other. This is done with the jack_connect command. In order to see the available endpoints and how they are connected run:

jack_lsp -c

In the case of a 3-way connection you should see something like this:

pi@raspberry-jam:~ $ jack_lsp -c
system:capture_1
   :send_1
   -01:send_1
system:capture_2
system:playback_1
   :receive_1
   -01:receive_1
system:playback_2
:send_1
   system:capture_1
:receive_1
   system:playback_1
-01:send_1
   system:capture_1
-01:receive_1
   system:playback_1

To connect the audio from the 2 clients in this example, the participant acting as the server would run

jack_connect -- -01:receive_1 :send_1

jack_connect -- -01:send_1 :receive_1

If that is successful then all 3 participants should hear one another.

Clone this wiki locally