Wire up a series of buttons that play particular sounds when pressed.
The Axia® iQ radio console system can be used to build custom consoles of sizes from 8 to 24 faders. A basic system consists of one iQ 8-Fader Main Frame and one QOR.32 integrated console engine, a DSP- based mixing engine which also incorporates analog and digital audio I/O, GPIO and a custom, zero- configuration Ethernet switch. Today we're looking at how to set up a Raspberry Pi 3 to record audio using the latest version of Reaper. We look at Raspbian, NOOBS and installing using a Terminal.
Getting started
First we'll create a Python program, import the GPIO and PyGame libraries, and play a sample sound file.
- Boot your Pi and log in with:
- Boot to the desktop with the command
startx
- Open LXTerminal from the desktop.
- Type the command
ls
and you should see the files and folders in your home directory. - Create a new folder called
musicbox
with the following command: - Enter the folder with
cd musicbox
We're going to need some sample sound files for this project so we'll use the ones from Sonic Pi. - Make a copy of Sonic Pi's sound samples folder with the following command:This will copy the samples folder (
-r
means recursively which means all the files and folders inside the folder) to yourmusicbox
folder. - Type
ls samples
and you'll see a list of.wav
audo files. - Create a new Python file with
touch musicbox.py
. - Open the Python file in IDLE with the command
sudo idle musicbox.py &
.This opens the Python application IDLE with superuser permissions, as you'll need these to use GPIO.You'll see a Python prompt window. It will contain some information about Python then a new line starting with>>>
. There will be another window, which will be blank. - In the blank window, enter the following code to get started:Here, we import the audio mixer module of the PyGame library and initialise it.Then we create a reference to one of the sample sound files.The
while True
is a continuous loop containing a command to play the sound file. It will keep playing the drum sound repeatedly until the program is terminated. - Save the file with
Ctrl + S
and run withF5
.It should play the drum sound repeatedly. - Click into the Python prompt window and press
Ctrl + C
on the keyboard to force it to end.If you can't hear the sound, or it's coming out of the wrong speakers, you can change your audio configuration. Return to the terminal window and type the following command:to switch audio to the headphone jack, orto switch to HDMI.You only need to do this if your audio is coming out of the wrong speakers.
Wire up first button
Now we've configured the audio and tested playing sound in Python, we'll connect the GPIO button.
Firstly, observe the following GPIO diagram. You'll be using a single ground pin (marked
GND
) and several GPIO pins (marked GPIO
):3V3 | 5V |
GPIO2 | 5V |
GPIO3 | GND |
GPIO4 | GPIO14 |
GND | GPIO15 |
GPIO17 | GPIO18 |
GPIO27 | GND |
GPIO22 | GPIO23 |
3V3 | GPIO24 |
GPIO10 | GND |
GPIO9 | GPIO25 |
GPIO11 | GPIO8 |
GND | GPIO7 |
DNC | DNC |
GPIO5 | GND |
GPIO6 | GPIO12 |
GPIO13 | GND |
GPIO19 | GPIO16 |
GPIO26 | GPIO20 |
GND | GPIO21 |
Note that if you have an older Raspberry Pi model you'll only have 26 pins but they have the same layout, starting at the top row (
3V3
and 5V
and ending at GND
and GPIO7
).- Find a ground pin (marked
GND
) on the diagram of the Raspberry Pi's pin layout above. - Attach a wire to a ground pin on the Raspberry Pi and connect it to the ground rail on your breadboard like so:
- Place the button on the breadboard and connect one of its feet to the ground rail.
- Connect the button's other foot (on the same side) to GPIO pin 2 like so:If you're using a mini breadboard without a designated ground rail, you'll have to use one of the rows as the ground rail. Connect a row to a ground pin and the other points in that row will be connected to ground like so:
Connect first button to sound file
Now we've connected a GPIO button, we'll make the sound play when the button is pressed.
- Return to the code window and amend the code to add the GPIO library and set up pin 2, so it looks like this:This sets up GPIO pin 2 as an input, so you can trigger an event with the button.
- Now add a function for playing the sound. This will be the code than runs when the button is pressed:The
print
will tell you when the function has been called, so you know what's going on. - Create a GPIO event that will call the
play
function when the button is pressed:The arguments passed to the function are:- the GPIO pin number (
2
) - the type of voltage change (
FALLING
) - the function to be used as the callback (
play
) - the amount of time allowed between button presses (
1000
milliseconds)
- the GPIO pin number (
- Add a line to print
ready
once it's all been set up, and add awhile True
loop to wait for a button press: - Run the program again and once you see
ready
printed to the screen, press the button and you should hear the drum sound played. Each time you press the button it should printplaying
to the screen and play the sound.If you do not see the wordplaying
when you press the button, check you have it wired to the ground rail and pin 2, and that the cables are securely connected.
Add second button with a different sound
Now that we've added an event for the first button to trigger the drum sound, we'll connect a second button and map that to a different sound.
- Add a second button to the breadboard and wire it up to the ground rail and to GPIO pin 3 like so:
- In the code, add a cymbal sound in the same way:We also need to perform the
GPIO.setup()
on pin 3 as well as pin 2. Rather than just copy this line, we'll automate the process.Normally we'd use a list likepins = [2, 3, 4, 5]
and use a loop to run the setup for each item in the list. However, as this time we also need a list of sounds that correspond to GPIO pins, we'll use another data structure called a dictionary which is used to store relationships between items. - After the
cymbal
line, create a dictionary mapping the two GPIO pins to their respective sounds, like so:This means you can look up which sound to play by passing in the pin number; for examplesound_pins[2]
yieldsdrum
andsound_pins[3]
yieldscymbal
.Now where we previously had theGPIO.setup()
line for pin 2, we'll use a loop to set up all the pins in thesound_pins
dictionary. - Use the following loop to set up each pin:Looping over a dictionary like this yields the dictionary keys (the left hand side), and passing a key into a dictionary yields the corresponding value. For the pin setup all we need is the pin numbers.The other thing we want to do for each pin is set up the event detection.We could write a new function to play each particular sound, and add each event detection separately mapped to the appropriate function. However, it is possible to use a single function that determines which sound to play according to which pin was triggered.
- Move the previously used
add_event_detect()
line into this loop, replacing the hard-coded value of2
for the loop variablepin
:Now theplay
function will be called when pins2
or3
are triggered (by their connected buttons being pressed). However, we need to amend theplay
function to make it play the right sound according to which button was pressed. - Amend the
play
function like so:Because the event detection callback sends the GPIO pin number to theplay
function, we can look it up in thesound_pins
dictionary, setsound
to the appropriate sound and then play it. - Now run the program again and when you see the ready message, try pressing each button. Different sounds should be played when each button is pressed.
Connect more buttons
Now we've done all the hard work, it's really easy to connect more buttons to make more sounds!
For each extra button, all you need to do is:
- Connect the button to the breadboard and wire it to the ground rail and another GPIO pin. Make sure it's a pin marked GPIO in the pin diagram above.
- Add a reference to the new sound file:
- Add the pin number and sound variable to the
sound_pins
dictionary:And that's it! Re-run the program and the new buttons should make new sounds!
What next?
- Try some more sounds from the
sample
folder. - Leaving the code as it is, you could make a presentation box with big colourful buttons that don't need a breadboard, and attach speakers to the side.
- Try recording your own sounds and use them instead!
I have just purchased my rpi and very new to python and linux in general. I have been able to get my audio to stream from my iPad using shairport to rpi. However I am having difficulties trying to control the volume/mute on the rpi from the GPIO inputs. Can this be done using python? I tried writing a program to start by muting the output by importing the alsaaudio module and trying the following.
import alsaaudio
![Raspberry pi zero audio Raspberry pi zero audio](/uploads/1/2/5/8/125858226/870212467.jpg)
m = alsaaudio.Mixer()
m.setmute(1)
I was going to add the GPIO inputs after I am able to get this to work. Am I going about this correctly? Should I be using something other than python?
Please help.
rbeck