Software¶
The FluidPatcher software for the SquishBox turns it into a customizable MIDI sound module. The software is installed on Raspberry Pi OS by running a script from the command line. This downloads the code that runs the synth and a few other software dependencies, and sets up the interface to run on startup. These changes aren’t drastic – you don’t have to sacrifice your Raspberry Pi computer or buy a new one to use exclusively with the SquishBox! You can install the software on a working OS without wiping anything, and you can easily pop the Pi out of the enclosure and use it for something else as you need. You can view the source code for FluidPatcher at https://github.com/GeekFunkLabs/fluidpatcher and learn how it works if that interests you.
Setup¶
If you’re using a brand new Raspberry Pi or just want to start fresh you can get OS images and instructions on installing at https://raspberrypi.org/software, and information on how to set up your Pi at https://raspberrypi.org/documentation.
Log in, make sure your Pi is connected to the internet, and enter the following command:
curl -sL geekfunklabs.com/squishbox | bash
This will download and run an install script that will query you for options, then do all the configuration and software installation automatically. The first time running the script you will see the message
This script must reboot your computer to activate your sound card.
Once this is complete, run this script again to continue setup.
Reboot? ([y]/n)
Respond y
to reboot, then enter the above command again. The script will now query you for install options. You can just press enter for each option to choose the defaults (enclosed in square brackets) to install everything, but here is an explanation of each of the options.
What are you setting up?
1. SquishBox
2. Naked Raspberry Pi Synth
This software can be installed on a bare Raspberry Pi without the SquishBox add-ons, but you should choose option 1 here. The script may need to reboot your Pi in order to set up the sound card, after which you should run the script again to continue.
What version of SquishBox hardware are you using?
v6 - Green PCB with SMT components
v4 - Purple PCB, has 2 resistors and LED
v3 - Purple PCB, has 1 resistor
v2 - Hackaday/perfboard build
Different versions of the PCB have slightly different wiring. The PCB used in these instructions is v6.
Enter Install location [/home/user]
The code installs in your home directory by default, but can be installed in any location where you have write privileges.
Which audio output would you like to use?
0. No change
1. Default
2. Headphones
3. sndrpihifiberry
4. vc4hdmi
Choose [3]
Choose sndrpihifiberry from the list.
Install/update synthesizer software? ([y]/n)
This installs the base code that runs the SquishBox. You can also use this script to reconfigure some of the later optional extras, so if you want to do that without changing your code, reply no here.
Set up web-based file manager? ([y]/n)
Please create a user name and password.
username:
password:
When the SquishBox is connected to a network, its web interface provides a convenient way of editing your patches, banks, and config files, as well as uploading soundfonts. Choose a good password to protect your SquishBox settings from other users on the same network. To log in to the file manager, connect a computer/tablet/phone to the same network as the SquishBox and point a web browser to the IP address of the SquishBox (see “WIFI Settings” below).
Download and install ~400MB of additional soundfonts? (y/[n])
Responding y downloads a collection of extra soundfonts in addition to the general MIDI soundfont that is downloaded by default.
Update/upgrade your operating system? ([y]/n)
Any time you install new software on the Raspberry Pi, it’s a good idea to make sure your other software is all up to date, so you should probably say yes here.
Option selection complete. Proceed with installation? ([y]/n)
The terminal will start producing a bunch of output as it installs and configures the necessary software.
This may take some time ... go make some coffee.
If something does go wrong, this output can often be helpful in identifying the problem when seeking support, which can be found at geekfunklabs.com/support. Once finished, the software will ask if you would like to reboot. If you haven’t installed the Pi in the SquishBox yet, you can reply no and then enter sudo poweroff to safely shut down.
If you want to use the Pi for something else, you can enter sudo systemctl disable squishbox at the command line to stop the synth from running on startup. If needed later, you can enter sudo systemctl enable squishbox to get it back again.
Usage¶
When you plug in the SquishBox, the Pi will boot and start the synthesizer software. A splash screen will appear briefly with the squishbox software and hardware (PCB) versions. The current patch name, number, and total patches available are displayed on the LCD. Rotating the encoder cycles through patches. The encoder can also be tapped to advance to the next patch. The stompbutton sends MIDI messages that can be routed in banks or patches to act as a pedal, effects control, or perform other actions. The messages sent are control change 30 with a value of 127 and 0 on press and release, and control change 31 toggling between 0 and 127 with each press. Holding down the rotary encoder for one second opens the menu. In menus the stompbutton does not send MIDI messages. Instead, rotating the encoder scrolls through options, or tapping the encoder advances to the next option and tapping the stompbutton goes back. This makes it easier to use the SquishBox with feet if it’s placed on the floor. Holding the encoder for one second selects options, and holding the stompbutton for one second cancels or exits. Most menus will time out after a few seconds with no input. Some menus have specific interaction modes:
When asked to confirm a choice, it will be shown with a check mark or X next to it. Selecting the check mark confirms, X cancels.
Some menus allow changing a numerical setting. Rotating the encoder adjusts the value, and holding the encoder confirms it.
Some menus allow entering text character-by-character. The cursor appears as an underline for changing position and a blinking square for changing the current character. Holding the encoder switches between cursor modes. Holding the stompbutton exits editing, after which you will be asked to confirm or cancel your entry.
Below is a list of the menu options, with short descriptions of what they do.
Load Bank – Load a bank file from the list of available banks. The current bank is displayed first.
Save Bank – Save the current bank. Changing the name saves as a new bank.
Save Patch – Saves the current state of the synthesizer (instrument settings, control change values) to the current patch. Modify the name to create a new patch.
Delete Patch – Erases the current patch from the bank, after asking for confirmation.
Open Soundfont – Opens a single soundfont and switches to playing sounds from the soundfont’s presets instead of the patches in the current bank. Holding the encoder creates a new patch in the current bank that uses the selected preset on MIDI channel 1, after prompting you for a new for the new patch.
Effects.. – Opens a menu that allows you to modify the settings of the chorus and reverb effects units, and the gain (maximum output volume) of the SquishBox. Changes affect all patches in the bank – save the bank to make them permanent.
System Menu.. – Opens a menu with more system-related tasks:
Power Down – To protect the memory card of the SquishBox, this option should be used before unplugging. Allow 30 seconds for complete shutdown.
MIDI Devices – This menu can be used to view the list of available MIDI devices, and to interconnect MIDI inputs and outputs. By default, the SquishBox automatically connects to all available MIDI devices, but this menu allows more control. It also includes a MIDI Monitor option that displays incoming MIDI messages on the screen. Pressing any button exits the MIDI monitor.
WIFI Settings – Displays the current IP Address of the SquishBox, and provides a menu to scan for and connect to available WIFI networks. You can also enable/disable the wifi adapter here. It is useful to turn off the wifi adapter when you are out of range of any known networks, to keep the Pi from wasting CPU doing scans.
USB File Copy – Allows you to copy your banks, soundfonts, and config files back and forth between the SquishBox and a USB storage device. Files are copied to/from a SquishBox/ folder on the USB. The Sync with USB option will update the files to the newest available version on either device.
The SquishBox software and soundfonts collection include several banks with useful patches, and a large selection of soundfonts. However, a powerful feature of the SquishBox is the ability to configure it the way you need and create and your own patches. For information on how to edit the config and bank files for your squishbox refer to the README at:
github.com/GeekFunkLabs/fluidpatcher/blob/master/patcher/file_formats.md
There you can also find a link to a series of lesson videos on editing and creating patches, uploading new sounds, and configuring your SquishBox.
API Reference¶
The code in squishbox.py can be modified or imported to create other applications for the SquishBox. All the functionality is contained in the SquishBox
class.
- class squishbox.SquishBox¶
An interface for RPi using character LCD and buttons
- buttoncallback¶
When the state of a button connected to BTN_SW changes, this function is called with 1 if the button was pressed, 0 if it was released.
- wifistatus¶
contains either the WIFIUP or WIFIDOWN character depending on the last-known status of the wifi adapter
- __init__()¶
Initializes the LCD and GPIO
- char_input(text=' ', row=1, i=-1, timeout=5.0, charset=' abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_./\x00')¶
Allows user to enter text with a rotary encoder and button
There are two cursor modes, which are toggled using SELECT. The blinking square allows the current character to be changed using DEC/INC. The underline cursor changes position with DEC/INC. ESCAPE ends edit mode, and allows the user to confirm or cancel the input.
- Parameters:
text – the initial text to be edited
row – the row in which to show the input
i – initial cursor position, from end if negative
timeout – seconds to wait before canceling, forever if -1
charset – the set of allowed characters
Returns: the edited string, or empty string if canceled
- choose_file(topdir, last='', ext=None)¶
Lets user browse and select a file on the system
Finds files of a specified type on the file system and lets the user choose one using choose_opt(). Timeout is disabled and filenames can scroll. Can move up and down through the directory tree up to a specified limit. First two arguments must be pathlib.Path objects. Shows the current file on the bottom row and the current directory on the row above it.
- Parameters:
topdir – Path of the highest-level directory the user may see
last – Path of the file to show as the initial choice
ext – the file extensions to show, if None shows all files
Returns: Path of the chosen file or empty string if canceled
- choose_opt(opts, row, i=0, mode='rjust', timeout=5.0)¶
Lets the user choose an option from a list
Displays options from a list of choices. User can scroll through options with DEC/INC, choose with SELECT, or cancel with ESCAPE or timeout. Menu options can scroll.
- Parameters:
opts – list of strings to display as the choices
row – the row on which to show the choices
i – index of the choice to display first
mode – ‘rjust’ by default - see lcd_write()
timeout – seconds to wait, if -1 wait forever
Returns: index of option chosen, or -1 if canceled
- choose_val(val, minval, maxval, inc, fmt='>16', timeout=5.0, func=None)¶
Lets the user modify a numeric parameter
Displays a number on the bottom row of the LCD and allows the user to scroll its value over a range by specified increment using DEC/INC. A function can be called with the current value after each increment to demonstrate the result. User can set value with SELECT, or cancel with ESCAPE or timeout.
- Parameters:
val – the starting value
minval – the lower limit of the value
maxval – the upper limit of the value
inc – the step size to change when incrementing/decrementing the value
fmt – a format specifier for printing the value nicely
timeout – seconds to wait, if -1 forever
func – a function to call with the value every time it changes
Returns: selected value, or None if time expired or ESCAPE
- confirm_choice(text='', row=1, timeout=5.0)¶
Offers a yes/no choice
Displays some text and lets the user toggle between a check mark and an X with DEC/INC and choose with SELECT.
- Parameters:
text – string to write
row – the row to display the choice
timeout – seconds to wait, if -1 wait forever
Returns: 1 if check is selected, 0 if time expires or ESCAPE
- display_error(err, msg='', etype=None, tb=None)¶
Displays Exception text on the LCD
Reformats the text of an Exception so it can be displayed on one line and scrolls it across the bottom row of the LCD, and also prints information to stdout. Waits for the user to press a button, then returns if possible.
- Parameters:
err – the Exception
msg – an optional error message
- static gpio_set(pin, state)¶
Sets the state of a GPIO
Sets a GPIO high or low, as long as it isn’t being used by something else. PIN_OUT can be modified to add outputs, as long as they don’t conflict with those defined above for the LCD, buttons, and GPIOs 18, 19, and 21 (which are used by the DAC).
- Parameters:
pin – pin number (BCM numbering)
state – True for high, False for low
- lcd_blink(text, row=0, col=0, mode='', delay=0.1)¶
Blink a character/message on the LCD
Write text on the LCD that disappears after a delay. Text written by lcd_write() will reappear. Calling this with an empty string removes any current blinks. If a blink is already in progress when this is called, the new one is ignored.
- Parameters:
text – string to write, ‘’ to clear blinks
row – the row at which to place text
col – the column at which to place text
mode – if ‘ljust’ or ‘rjust’ pad with spaces, otherwise place text starting at row, col
delay – time to wait before removing text
- lcd_clear(now=True)¶
Clear the LCD
Sends a clear command to the LCD and clears the text and blink buffers.
- Parameters:
now – if False just clear buffers to reduce flickering, but requires an update to take effect
- lcd_write(text, row, col=0, mode='', now=False)¶
Writes text to the LCD
Writes text to the LCD starting at row, col. Characters are stored in a buffer until the user calls update(). Can be called with now=True if the LCD needs to be updated now, usually because another process would delay updates.
- Parameters:
text – string to write
row – the row at which to start writing
col – the column at which to start writing
mode – if ‘ljust’ or ‘rjust’ pad with spaces, ‘scroll’ scrolls text to the right if it is long enough, otherwise place text starting at row, col
now – if True update LCD now
- progresswheel_start()¶
Shows an animation while another process runs
Displays a spinning character in the lower right corner of the LCD that runs in a thread after this function returns, to give the user some feedback while a long-running process completes.
- progresswheel_stop()¶
Removes the spinning character
- static shell_cmd(cmd, **kwargs)¶
Executes a shell command and returns the output
Uses subprocess.run to execute a shell command and returns the output as ascii with trailing newlines removed. Blocks until shell command has returned.
- Parameters:
cmd – text of the command line to execute
kwargs – additional keyword arguments passed to subprocess.run
Returns: the stripped ascii STDOUT of the command
- update(idle=0.01, callback=True)¶
Polls buttons and updates LCD
Call in the main loop of a program to poll the buttons and rotary encoder, and update the LCD if necessary. Sleeps for a small amount of time before returning so other processes can run. Returns an event code based on the state of the buttons. If buttoncallback is set and callback=True, the stompswitch calls that function instead of sending an event.
NULL (0) - no event
DEC (1) - encoder step counter-clockwise or stompswitch tap
INC (2) - encoder step clockwise or encoder button tap
SELECT (3) - encoder button held for HOLD_TIME seconds
ESCAPE (4) - stompswitch held for HOLD_TIME seconds
- Parameters:
idle – number of seconds to sleep before returning
callback – if False ignores buttoncallback
Returns: an integer event code
- waitfortap(t=0)¶
Waits until a button is pressed or some time has passed
- Parameters:
t – seconds to wait, if 0 wait forever
Returns: True if button was pressed, False if time expired
- wifi_settings()¶
Displays a wifi settings menu
Shows the connection status and current IP address(es) of the Pi and a list of any available wifi networks. Allows the user to enable/disable wifi and enter passkeys for visible networks in order to connect.
- wifi_state(state='')¶
Checks or sets the state of the wifi adapter
Turns the wifi adapter on or off, or simply returns its current state. Does not determine whether it has connected to a network, only that it is enabled or disabled.
- Parameters:
setstate – ‘on’ or ‘off’ to set the state, empty string just checks the current state
Returns: ‘on’ or ‘off’