This guide describes my build of a Raspberry Pi based synthesizer. My goal was to create something ultra-portable that will run Miller Puckette's very wonderful block-and-wire sound synthesis package, Pure Data. I wanted something that would operate without a keyboard, mouse or monitor, and I wanted some analog controls (knobs and buttons or switches) to control the sound in real time. My plan was to prototype and develop Pure Data patches (instruments) using my laptop PC, and then load them onto the Pi and have it operate as a stand-alone instrument. I have summarized all references and links in a section at the bottom of this guide.
Musically, the type of stuff I like to work on is very abstract. In my youth I was inspired by a demonstration from an engineer with the BBC Radiophonic Workshop of an EMS Synthi AKS suitcase synth. I also became obsessed with the movie "Forbidden Planet", and consequently have always been interested in atonal, arrhythmic sci-fi noise. I make patches that play themselves in a sense although they are typically not completely generative. Take a listen to some of my output on SoundCloud if you're interested (just don't listen in the dark!) Latency is not a big worry for me because of the type of sounds I create - more about this later, but suffice to say for now that I'm using an off-the-shelf version of Raspbian rather than trying to compile a real time operating system.
I used a Raspberry Pi model B+ that I already owned as the foundation of the project. I added to this an analog input "hat" (or "shield" in Arduino parlance) - the "Lots Of Pots" board from Modern Device, which has 8 analog rotary inputs plus four push buttons, and break-outs for other GPIO connections in case you want to add more buttons, switches or outputs of some kind. I had considered using a pre-built USB MIDI controller, but couldn't find anything small enough and with the right type and number of controls.
I used a laptop PC with Windows 10 to prepare the SD card with the operating system for the Pi. I also used this laptop for the remainder of the preparatio work on the Pi (via VNC and SSH) that I describe in this guide.
I'm proficient in Linux and in a couple scripting languages, and I can scrape by with difficulty in C++. My goal was to make this project work as out of the box as much as possible - I did not want to have to write reams of code to support it.
I have tried to make this guide as self-contained and complete as possible. It's a distinct advantage if you're comfortable with Linux and using the command line, although you can probably muddle through this even if you're not. I have added all references (links) at the very bottom of the guide.
Lastly, I was inspired by several other projects (the first couple of which I have built) including the MintySynth, Jan Ostman's O2 drum machine (based on Arduino and using MP7 sounds), the Pi-FX pedal board, the OWL pedal board from Rebel Technology, Critter and Guitari's Organelle, and the Teensy polyphonc synthesizer (as well as the wonderful OP-1 synth from Teenage Engineering which most of my SoundCloud output is based on, and which I sold a couple years ago for reasons that I'm still trying to comprehend).
Assemble the hardware
Create the Raspbian (operating system) image ready for installation
Install Raspbian on your Pi and boot for the first time
Set up VNC
Install Pure Data
Make the system shut down properly when you press one of the GPIO buttons
Learn how to set the volume from the command line
Run Purr-Data and open a patch automatically when you boot
Get comfortable with logging into the Pi using SSH
Test the whole thing before you commit
Log into the Pi via SSH and turn off the desktop and VNC
What's next?
The Lots Of Pots (LOP) board comes either with potentiometers (this is the version that you want) or with headers instead of pots. The SMD devices are pre-soldered onto the board, but you will need to solder the eight potentiometers and the socket that attaches the board to the Pi. Be aware that the potentiometers that came with mine have a center detente which would not have been my first choice, but they work OK in my application. The pots snap into the board (with a little persuasion) on either side - be careful to align the pot's pins into the holes so you don't bend them. The pots mount on the same side as the switches (this should be fairly obvious) but you must mount the header socket on the opposite side (underside) of the board so it can hook up with the Pi.
I used a rubber band to hold the header socket square to the board just so I could solder the first couple pins (or you could use a little hot glue to keep it in place as you solder it).
I added a little electrical tape under the buttons on the LOP board because it looked as if there was a danger of some of the GPIO pins shorting against the metal bodies of the USB ports.
The images on the Modern Device site show (I think) a model B - mine is a B+ which has more GPIO pins, so I was a little confused at first about where to plug the LOP board in - it needs to be oriented to the SD card end of the Pi board, not to the USB socket end (or anywhere in the middle).
I used a blob of hot glue on top of the Ehernet port to keep the plugged-in board steady, and also to provide some insulation. I also kept the base from my original plastic case on the Pi board to insulate it from whatever surface I will be using it on, and I secured this with a little hot glue.
I chose not to use NOOBS for the install because it can take a long time to install on the Pi and I knew I would need to do several iterations to get this right.
a) From the Raspbian downloads page (see at the bottom for all links and references), download "Raspbian Buster with desktop" - I downloaded this as a ZIP file.
b) Format an SD card - note that you can't use the WIndows native formatter for this - I used the SD card formatter from the SD Card Association
c) Create the Raspbian image on the formatted card. I used balenaEtcher for this. On the left, select the ZIP file that you just downloaded. It should automatically recognize the formatted card. Hit "Flash!" to create the image on the card. If you're using Windows then it might pop up a file explorer window or two during the process - you can just close these as they pop up.
a) Eject the SD card properly from your PC and put it in the slot at the bottom of the Pi.
b) Connect the Pi to a USB keyboard, mouse and monitor. I just use a TV with an HDMI cable, and a tiny wireless USB keyboard with a track pad (which would be annoying if I had to use it every day, but just for the setup it's fine). Search for "raspberry pi mini keyboard" on your favorite online shopping site and you should see plenty of choices for between $10-15. They all seem pretty generic - mine is branded "CanaKit CK-KB-101" although I can't find that model on Amazon any more. Mine is 100% plug and play - there's a little USB dongle and to the Pi it looks just like a regular keyboard and mouse.
c) Power up the Pi. The screen will go blank a couple times but don't panic - after a minute or two it should boot up into the desktop. You will get a "welcome" pop-up - click on "Next" to set up localization, enter a new password for the default "pi" account and confirm the screen settings. The setup program will then look for your wifi network - connect to yours, and then hit "Next" again on the next screen to check for updates. Don't worry if it comes back with an error message at the end of this (mine did). Restart the pi (without disconnecting anything) when it asks.
On the reboot, you should see a splash screen followed by a flashing cursor, blank screen for a while and finally the desktop.
a) As soon as the Pi is set up for the first time and connected to the wifi, I disconnect the keyboard and monitor and do everything else via a VNC session (remote desktop) from my laptop. Be aware though that the Pi will want to try and figure out the resolution of the monitor it's connected to. If it's not connected to a monitor then it will choose a ridiculously tiny window as its default (which is safe I suppose). So set your screen resolution before booting the Pi without its monitor because it's hard to do this through the ridiculously tiny VNC window. From the raspberry icon in the top-left of the screen, choose "Preferences" -> "Raspberry Pi Configuration". Hit the "Set Resolution..." button and change from "Default - preferred monitor settings" to something that will work well on your laptop and on the connected monitor (I use "CEA mode 16 1920x1080 60Hz 16:9"). It will ask to reboot after you change this.
b) Now set up the VNC server on the Pi. Open the "Raspberry Pi Configuration" app again. Click on the "Interfaces" tab. Next to where it says "VNC", click "Enable". While you're here, also enable SSH, SPI and I2C because you will also use these later. Click on "OK" to save your changes. You should now see a VNC logo at the top right corner of the screen. Right-mouse on this and choose "Options...". Where it says "Authentication" choose "VNC password" and then click OK. It will ask you to choose a password (I use the same password as the one I chose in step 3c above). Then click on OK to close the window.
c) You should now be able to control the Pi remotely using a VNC client on your laptop (or other computer connected to your network). I use the UltraVNC Viewer client on my PC, but any VNC client (RealVNC, for example) should work. You will need to give your VNC client the IP address of the Pi so it can connect. You can find this by logging into your router (I have Google mesh routers at home, so I use the Google wifi app to find my Pi and its corresponding IP address) but you can also find it by left-clicking on the VNC icon. Be aware that your router probably dynamically assigns IP addresses so it's likely that the IP address of your Pi will change from time to time. For example if you find that your IP address is 192.168.1.123 then enter 192.168.1.123:0 into your VNC client (note the trailing :0 which is the VNC display name), then enter your password and you should see the Pi's desktop on your laptop. Moving the mouse around on my laptop and seeing the cursor move on the display attached to the Pi still seems like black magic to me.
At this point, so long as you set a default screen resolution in step 4a, you can shut down the Pi (left click on the raspberry icon) and power it up again with the screen and keyboard/mouse removed, and still be able to get in via VNC from your laptop.
a) OK so I lied - I'm actually using a program called Purr-Data which is a derivative of Pure-Data. I will use "Pure Data" interchangeably with "Purr-Data" in the remainder of this guide. The reason I chose Purr-Data specifically is because it comes with pre-configured utilities ("externals" in Pure Data parlance) that interface with the LOP control board.
Open a terminal on your Pi (black box on the top bar with ">_" in it) and enter the following commands to install Purr-Data:
sudo su
wget -nv https://download.opensuse.org/repositories/home:aggraef/Raspbian_10/Release.key
apt-key add Release.key
echo 'deb http://download.opensuse.org/repositories/home:/aggraef/Raspbian_10/ /' > /etc/apt/sources.list.d/home:aggraef.list
apt update
apt install purr-data
exit
b) Set the audio output - right-click on the speaker icon at the top-right of the Pi's desktop and flip the output from its default (HDMI) to Analog, which will send the audio output out through the headphone jack which is next to the HDMI port.
WARNING: test your audio output levels carefully before you try anything on the Pi. Don't put on your headphones before you turn on the Pi, before you run Purr-Data or before you load or try out any patch. Start everything with your headphones off and bring them slowly closer to your ears until you're confident that it's not too loud. You're going to set the system volume to 90% and control volume from within Pure Data so it's very important to always have something between your Pure Data output and the DAC to attenuate the sound (e.g. a multiplier linked to a 0-1 slider control). Also be aware that slider controls have a default range of 0-127 so make sure that you change their properties before joining them to a multiplier.
c) To test the installation - I'm not going to turn this into a tutorial for Pure Data (the excellent YouTube tutorials from Dr. Rafael Hernandez are an great place to start for this) but you can test the audio out from Pure Data by opening the app and creating a simple oscillator patch.
Open a terminal and enter:
purr-data
This will open a Purr-Data main window. Select "File" -> "New" to create a new patch. Create the following patch - adjust the properties of the volume slider so that it ranges from 0 to 1 (not 0 to 127 which is the default!)
Back in the main Purr-Data window, click on the DSP switch to turn audio on. Slowly bring up your volume slider until you hear a tone. Don't panic if you hear some unintended clicking! This just means that you need to adjust the latency. Hit "Edit" -> "Preferences" and under the "Audio" tab, increase "delay" by 5ms and hit "Apply". Repeat this until the audio output is stable (on my Pi B+ this happened at 30ms). This is the aforementioned latency setting. It's probably possible to get this lower than 30ms by using a custom real-time operating system, but some latency is inevitable although it's not a big deal to me because of the (weird) type of stuff I like to create.
Make a note of the "delay" setting - purr-data doesn't seem to remember this as a default, so you will need to use the -audiobuf command line option to set it every time you run purr-data.
You will still hear some crackles if you move the volume slider up and down quickly, but this is because you need to smooth the volume changes inside Pure Data using a "line" object (but like I said this isn't a Pure Data tutorial!)
Congratulations - you just built your first synthesizer!
I want to be able to use this synth completely independently from any kind of keyboard and monitor. Also I don't want to have to connect either via VNC or SSH for anything while I'm using the synth. When I started thinking about this, I realized that I would need a way to shut the Pi down properly. It's not a good idea just to pull out the power cord - just the same as you wouldn't yank the power cord out of a running desktop computer. So I needed a way to shut the system down using only the controls on the LOP hat. Fortunately, the wonderful people at Adafruit have made some C code available which does the trick: you can make the system shut down just by connecting one of the GPIO ports to ground (which is exactly what the four buttons on the LOP board do!) The disadvantage of this is that this means there's one of the buttons that I won't be able to use in my Pure Data patches. I'm planning eventually to modify the C code so that it only shuts down when I press two or three of the buttons simultaneously, but right now I'm going to stay focused on getting this thing up and running.
Download the C code from Adafruit's Github repository, compile it and then start the resulting binary as a service which will run in the background every time you boot your Pi. To download the code requires that "git" is installed on the Pi - it was included with my installation of Raspbian Buster. The following instructions are duplicated from Michael Horne's guide, link is at the bottom of this guide.
Download the C code from Adafruit:
git clone https://github.com/adafruit/Adafruit-GPIO-Halt
This will create a directory "Adafruit-GPIO-Halt" that contains the code and the makefile that you need to build it. Change into this directory, compile the code and move the binary into /usr/local/bin
cd Adafruit-GPIO-Halt
make
sudo make install
I use a utility called "systemd" to run the binary as a service every time the Pi boots. To do this, you will create what's called a "unit file" which contains a series of directives for systemd. I used the vi editor for this, but you can use nano or whatever line editor you prefer:
sudo vi /lib/systemd/system/gpio-halt.service
Enter the following contents in the unit file:
[Unit]
Description=Press button IO27 (top button on the LOP board) to shut down the Pi
After=multi-user.target
[Service]
Type=idle
ExecStart=/usr/local/bin/gpio-halt 27 &
[Install]
WantedBy=multi-user.target
Note that the unit file tells systemd to invoke the gpio-halt binary with the argument 27. This tells the binary to look for a signal on GPIO pin 27, which corresponds to the top button on the LOP board.
Make the unit file executable:
sudo chmod +x /lib/systemd/system/gpio-halt.service
Now you will need to set this up as a service which will run whenever you boot the Pi.
sudo systemctl daemon-reload
sudo systemctl enable gpio-halt.service
Now reboot the Pi using "sudo reboot". When it comes back up, open the VNC session again and press the IO27 button to test it. I did this once or twice just because I thought it was so cool!
Now you're no doubt familiar with how to change the volume using the GUI controls, but of course when you're booting in headless mode these won't be available. You probably don't want to get to a performance and realize that you left the volume turned way down with no way of accessing it, so the following will show you how to change the volume from the command line. Before you start, check in the GUI that the audio output is being sent to "Analog" (the headphone jack) and not the default which is the HDMI port - right-mouse on the speaker icon in the top-right of the desktop window to do this.
Next find out the name of the control on your Pi.
amixer scontrols
On my Pi, this returns:
Simple mixer control 'PCM',0
...so in my case PCM is the name of the volume control, and my command line to change the volume is:
amixer sset 'PCM' 100%
...this turns the volume all the way up. Try this again with a couple different values and watch the speaker icon change accordingly. It's like magic!
Again, I wanted to be able to run the Pi synth with no monitor, keyboard, VNC session, SSH, nothing. This implies a couple things: (a) that I need to make Pure Data run automatically and load a patch when I boot the Pi, and (b) I need to run Pure Data in "headless" mode (no GUI). The second of these things is very easy - more in a minute. Running Pure Data automatically on boot proved to be way more difficult than I anticipated. I tried a few different methods, but eventually settled on using the same "systemd" utility that I used in section 6. My method undoubtedly still isn't perfect, but suffice to say after about 50 reboots I was happy to find a solution that actually worked.
The next few steps show you how to set up a script that will look for a Pure Data patch called "boot.pd" on an inserted USB memory stick when the Pi boots, and load it up into purr-data as soon as the script finds it. This way, you will be able to develop patches on your laptop, transfer them to the USB stick and run them on the Pi when you're ready. You won't need to SSH or VNC into the Pi to start Pure Data when you boot the Pi.
Open a new shell window and create a script in your home directory (/home/pi) to run Purr-Data (Pure Data):
vi start-pd
Put the following in the file:
#!/bin/bash
# Script to run purr-data when it finds a USB stick that has a patch
# called boot.pd
# Loop until we find a boot.pd file
until [ -n "$PDBOOTFILE" ]
do
# Wait for a short while before looking again
sleep 1
# Look for the first instance of the boot.pd file on any USB drive
PDBOOTFILE=`find /media/pi -name boot.pd -print -quit`
done
PDLOGFILE=/home/pi/start-pd.log
echo $PDBOOTFILE > $PDLOGFILE
USBPATH=`dirname $PDBOOTFILE`
# Set volume to 90% to avoid distortion
amixer sset 'PCM' 90%
# Run purr-data
sudo purr-data -nogui -audiobuf 30 -path "$USBPATH" -open "$PDBOOTFILE" &>> $PDLOGFILE
exit 0
A few notes about this file:
The first line tells the pi to expect bash shell commands in this script.
It seems to take a while after booting the Pi before it sees the USB stick, so I use a loop to look for the first instance of a file called "boot.pd" that it finds on any media that is inserted. This way, I don't need to worry about what the name of my USB stick is.
I found that setting the system volume to 100% results in severe distortion (which could be OK for you - I'm not going to try to limit your creativity) so I set it to 90% by default which is plenty for the headphones I use. Remember that you're going to control overall volume from inside the Pure Data patches.
I'm using a few environment variables for brevity, clarity and maintainability.
I'm sending the output of the script to a log file called "start-pd.log" that resides in the home directory for the default user.
I'm running purr-data as super user because this is needed to enable the external (function) to read the GPIO buttons.
"-audiobuf 30" is the "delay" setting that you discovered in step 5 above.
"-path" tells purr-data to also look on the USB stick for any sub-patches (e.g. lopread.pd) that might be needed by the boot.pd patch.
Now make the script executable:
chmod +x start-pd
Next you're going to make the script run very time the Pi boots, using the same "systemd" utility that you used to run the gpio button shutdown service in section 6.
Create a new unit file that will direct the systemd utility to run the start-pd script:
sudo vi /lib/systemd/system/start-pd.service
Enter the following contents in the script:
[Unit]
Description=Run the script /home/pi/start-pd when the Pi boots
After=multi-user.target
[Service]
Type=idle
ExecStart=/home/pi/start-pd
[Install]
WantedBy=multi-user.target
Make the unit file executable:
sudo chmod +x /lib/systemd/system/start-pd.service
Now set this up as a service which will run whenever you boot the Pi.
sudo systemctl daemon-reload
sudo systemctl enable start-pd.service
Now reboot the Pi using "sudo reboot".
I want to be able to use this system in a mode where I seldom need to actually log into it. I expect to do all of my patch development on my PC, and transfer my patches to the Pi via the USB stick. So I'm going to shut down VNC access, and also disable the graphical desktop interface. This is admittedly scary stuff - my only access to the system after this will be via the command line, either by connecting the Pi to a monitor and keyboard again, or by using a SSH utility like "PuTTY". Of course it will be possible to turn everything back on again, but it's important to get comfortable using PuTTY to access the Pi via SSH before committing to turning off the desktop.
Download and install PuTTY (link at the bottom). Enter the IP address of the Pi into the box marked "HostName (or IP address)" and hit "Open". Do not enter the :0 display name at the end of the IP address - this is only for VNC. You will see a window prompting you to log in. Log in as pi (the default user that you have been using all along) and use the password that you set up in the initial steps of installing the operating system on the Pi. Note that this may or may not be the same as your VNC password!
If all of this is successful, you will have access to the Pi now through a shell, and you will be able to enter Linux commands including things like "sudo raspi-config" to change configuration options.
If you were paying attention in step 4b, you will already have enabled the SPI and I2C interfaces (which are needed for the LOP board) using the "Raspberry Pi Configuration" app. If not, then you will find that this step does absolutely nothing, so go back to 4b and enable the SPI and I2C interfaces.
Download the following patch. Save a copy to your Pi, and another copy to the USB stick (so Pure Data will be able to find it when it loads the boot.pdb patch also on the USB stick):
It's necessary to run Purr-Data as root if you want to make the buttons work. To do this, type the following in a terminal:
sudo purr-data -audiobuf 30 -open lopread.pd
The number 30 in the above is the "delay" setting that you discovered in step 5 above. You will need to use "sudo" because although the pots will work if you don't run as root, the buttons won't.
The patch should open in the GUI. Twiddle the knobs and push the buttons and you should see the corresponding values change in Pure Data. Pretty cool! A few things to note:
The range of the LOP pot values is 0-1023. Compare this with the default range of a slider control in Pure Data, which is 0-127. Make sure that you appropriately scale the values from the pots before you use them as controls in your patches. For example, if you're using a pot value to implement a volume control, then remember to divide by 1023 before you multiply your audio signal by the pot value, or things will get very loud (and distorted!) very fast.
The buttons are "active-low" which means that they normally output a 1, and they output a 0 when you press them.
The lopread patch includes a bunch of "send" objects. My intent is to make an instance of this utility in each of my patches, and have it send the pot and button values to the remainder of my patch. Remember that sends in Pure Data are global, so you can use a corresponding "receive" object anywhere else in your patches to read the value from the pots or buttons. But you must have an instance of this utility sitting somewhere in your top-level patch.
Close the lopread patch when you're done testing the controls.
At this point, I switched to using my PC (rather than the Pi) to edit and create Pure Data patches, since this is basically the flow that I want to use when everything is up and running on the Pi. So open Pure Data on your PC (I am using Pure Data "Vanilla" - links at the bottom of this page). In the Pure Data main window, use "File -> New" to create a new patch. Make the following patch, which consists of the following:
An oscillator whose frequency is controlled by the Analog 0 pot.
A control that divides this frequency by 2 if you press button IO18.
A volume control.
A message that turns DSP on (so you can hear a sound) when you load up the patch - this is important since you will be running in headless mode so you won't be able to turn on DSP via the GUI.
An instance of the lopread utility which will send the values of the pots and buttons to the patch - this will do nothing on your PC and in fact will create an error message when you create it (create a dummy empty Pure Data patch on your PC named lopread.pd if you want to avoid this).
OK so this is a very contrived patch which does nothing interesting other than proving that the whole thing will work when you boot the Pi. Save it on the USB drive as "boot.pd". Eject the USB stick from your PC, and insert it into your powered-down Pi. Ensure that all the pots are turned all the way counter-clockwise. Insert headphones into the Pi but don't put them on until you are sure of the volume coming out of the Pi. Now power up the Pi.
a) Log into the Pi using PuTTY as in step 9 above. Open the config utility using the following command:
sudo raspi-config
Select "5 Interfacing Options" and then "P3 VNC" and then "<No>"
Next select "3 Boot Options" then "B1 Desktop / CLI" and then "B1 Console"
Finally select "<Finish>", and reboot the Pi.
b) OK so there's one more problem. Normally, the desktop program does the job of mounting the USB stick for us, but since you're no longer using the desktop you will need to mount it manually.
Firstly find out the device name of the USB stick. On mine, it's /dev/sda1 but you can confirm this using the following:
ls -l /dev/disk/by-uuid
It's a bit hard to decypher the output of this, but on my Pi one of the lines it produces is:
lrwxrwxrwx 1 root root 10 Dec 29 12:06 08AC-7B13 -> ../../sda1
...so I am going to say that my device name is /dev/sda1 and I'm going to try and mount the USB stick using this device name and give it a try.
Create a mount point for the drive:
sudo mkdir /media/pi/usb
...and change its ownership so that the default user pi owns it:
sudo chown -R pi:pi /media/pi/usb
...and now manually mount the drive:
sudo mount /dev/sda1 /media/pi/usb -o uid=pi,gid=pi
Check the drive to see if it looks like the right files are on it. You should see the boot.pd and lopread.pd patches:
ls -ltr /media/pi/usb
...and also if everything has gone well, the start-pd script which was looping patiently in the background should have started purr-data with the boot.pd patch loaded.
You will now need to make sure that this happens reliably every time you boot the Pi, without needing to log in and manually mount the USB stick. Probably the easiest way to do this is to add the mount command to the start-pd script. Insert the following command immediately before the "until" loop in the start-pd script:
sudo mount /dev/sda1 /media/pi/usb -o uid=pi,gid=pi
Now finally reboot the pi using "sudo reboot". When it comes back up, the boot.pd test patch should be running in purr-data. Shut the Pi down properly using the IO27 button on the LOP board when you're done.
Actually my original plan for this project was to create an effects unit for my Korg / Little Bits synth kit. This, of course, requires audio in which the Pi doesn't have. So I bought a little USB audio adapter made by "Plugable" (available from Amazon for about ten bucks) but haven't got round to making it work until now.
You'll need to VNC into your Pi to make this work - so turn VNC back on if it's off at the moment.
Turn the Pi on and plug in the USB audio adapter. In a shell, use "aplay -l" (that's a lowercase L, not a one) to show a list of your audio adapters:
I can see my Plugable audio card in this list (card 1) so I know all is well. Next job is to make sure I can see it from within purr-data. You can do this in a couple different ways. Either use "purr-data -listdev" from the command line and look in the PD console window for something like the following (you will need to scroll back up to see this:
From here I can see that my Plugable device shows up as #3 for audio input and for audio output. The correct option to select is "hardware" - don't ask me why, it works for me.
From this point, you have three options for selecting the USB audio adapter as the default when you run a PD patch:
1) Select it from Edit->Preferences-> Audio in the GUI (except we're not using the GUI, so that rules this out for anything other than experimentation)
2) Select it on the command line (in this case I would add "-audiodev 3" to my list of command line options in my start-pd script). I don't like this as an option because it means I would need to edit the script on my Pi (remember I'm storing it on the Pi, not on the USB stick) any time I wanted to change the audio output option.
3) Select it from inside a patch. Now we're talking! There's a really neat trick to do this (found here: https://forum.pdpatchrepo.info/topic/7187/changing-audio-settings-with-loadbang/2) - create the following patch:
[r pd]
|
[print]
...now go to the Edit->Preferences-> Audio tab in the GUI and select the USB soundcard from the pull-downs for input and output devices
Now go back to the PD console window - you should see some output like this:
print: audio-dialog 2 0 0 0 2 0 0 0 2 0 0 0 2 0 0 0 44100 100 -1 64
Add a message object to the boot.pd patch - add everything after the "print:" to this, but preface it with a semicolon, newline and pd (this sends a message to PD itself - you have probably seen this trick in the help windows to turn DSP on and off)
Trigger this in the boot.pd patch with a [loadbang] and this will set the audio in and out just for this patch. Remember to disable this (e.g. disconnect the [loadbang]) if you are not using USB audio. Otherwise PD will think that anything you plug into USB is an audio device (including MIDI USB keyboards) and you will lose audio. Yes, it took me a couple hours of head-scratching to figure that out! How to use USB audio and USB MIDI at the same time? Haven't looked at that problem yet...
I am using ALSA to connect between my MIDI USB keyboard and Purr-Data. With Purr-Data running and your MID USB keyboard plugged in, use the "aconnect -l" command to see which MIDI devices are visible to ALSA:
Edit your start-pd script and add "-alsamidi" to your command line options for starting Purr-Data:
pi@raspberrypi:~ $ aconnect -l
client 0: 'System' [type=kernel]
0 'Timer '
1 'Announce '
client 14: 'Midi Through' [type=kernel]
0 'Midi Through Port-0'
client 20: 'microKEY2-25 Air' [type=kernel,card=1]
0 'microKEY2-25 Air MIDI 1'
client 128: 'Pure Data' [type=user,pid=2611]
0 'Pure Data Midi-In 1'
1 'Pure Data Midi-Out 1'
pi@raspberrypi:~ $
This tells me that my MIDI USB keyboard is showing up as device 20, and Purr-Data as device 128. I need to use the ALSA "aconnect" command to connect the two of these. I can do that using the numbers:
pi@raspberrypi:~ $ aconnect 20 128
...or I can use the first few characters of the names of the devices:
pi@raspberrypi:~ $ aconnect microKEY2-25 Pure
The numbers seem to be stable, but I opted to use the names. You will need to make two changes to your start-pd script:
1. Add "-alsamidi" to the command line options for starting Purr-Data:
sudo purr-data -nogui -audiobuf 30 -alsamidi -path "$USBPATH" -open "$PDBOOTFILE" &>> $PDLOGFILE
2. Add one of the "aconnect" commands as above:
# Connect MIDI keyboard to purr-data
aconnect microKEY2-25 Pure
Close Purr-Data and restart after making these changes. Start Purr-Data without the "-nogui" option so you can test this before you commit.
Now the system should be set up so you can develop new patches "offline" on your PC and transfer them via USB stick to the Pi to run them.
Possible next steps for me are:
Try the system out at my local open mic.
USB battery power for total portability! (I have been using a "PKCELL" USB Battery Pack - 2200 mAh Capacity - 5V 1A Output from Adafruit quite successfully)
Figure out how to control the system volume from within Pure Data (using the "shell" object).
Modify the GPIO shutdown script so that it requires two buttons to be pressed simultaneously to shutdown (so I can use the IO27 button in my Pure Data patches).
Implement a "patch switcher" in Pure Data so I can load multiple independent patches on the Pi and switch between them without rebooting.
Audio input via USB (I initially started this project as a processor to add effects to my Korg Little Bits setup - the self-contained synth thing is a bonus of sorts). (See section 12 above)
Add some LEDs and possibly more push buttons. (Although I'm very much on the fence about this one - there's a great quote by Jack White in the movie It Might Get Loud - paraphrasing: "ease-of-use is the enemy of creativity" - and in any case it's probably more productive for me to focus on making patches rather than endlessly tweaking hardware, regardless of how much I enjoy it).
Second version of the hardware using rotary encoders instead of pots.
Thanks for following along. Best of luck if you decide to build one of these yourself. Do please let me know if you figure out how to do any of this better (or just different) than I have!
Of course I have used a lot more reference material than listed here. I have tried to capture my main sources of data here - if you recognize any of your own work above that's not credited here then please let me know and I will put it right. I owe a debt to the Raspberry Pi community and particularly to the Linux community in general, so I hope that I am able to pay this back in some small way with this guide.
My material on SoundCloud: https://soundcloud.com/plasticdub
MintySynth: https://mintysynth.com
Pi-FX pedal board: https://medium.com/@atippy83/guitarix-the-pi-dle-board-8d6298ca8e42
Teensy-based polysynth: https://www.pjrc.com/teensy-polyphonic-synth
Lots Of Pots analog input board from Modern Device: https://moderndevice.com/product/lots-of-pots-lop-board-for-raspberry-pi
Raspbian downloads page: https://www.raspberrypi.org/downloads/raspbian
Raspbian installation guide: https://www.raspberrypi.org/documentation/installation/installing-images/README.md
SD card formatter: https://www.sdcard.org/downloads/formatter
Balena Etcher: https://www.balena.io/etcher
Purr-Data installation page: https://github.com/agraef/purr-data/wiki/Installation#linux
Pure Data tutorials on YouTube: https://www.youtube.com/watch?v=rtgGol-I4gA
How to change volume from the command line: https://raspberrypi.stackexchange.com/questions/37131/change-volume-via-single-command
How to shut down using the GPIO port: https://www.recantha.co.uk/blog/?p=13999
How to run a script on startup: https://www.stuffaboutcode.com/2012/06/raspberry-pi-run-program-at-start-up.html
PuTTY (for SSH login to Pi) download page: https://www.putty.org
How to manually mount USB drives: https://www.raspberrypi-spy.co.uk/2014/05/how-to-mount-a-usb-flash-disk-on-the-raspberry-pi