Keytar Hero (Using a Wii Guitar Controller As a Synthesizer)
by analogsketchbook in Circuits > Raspberry Pi
3397 Views, 17 Favorites, 0 Comments
Keytar Hero (Using a Wii Guitar Controller As a Synthesizer)
The Guitar Hero games were all the rage a dozen years ago, so there's bound to be a lot of old guitar controllers lying around gathering dust. They have a lot of buttons, knobs, and levers, so why not put them to good use again? The guitar controller doesn't normally make any sound on its own, but in this tutorial I'll show you how to convert a Wii Guitar Hero Controller so it can be played as a synthesizer.
Supplies
- Guitar Hero Wii Controller
- Nunchucky breakout board (available on Adafruit here)
- 4ea jumper wires (female to female)
- 2ea crimp connectors (optional)
- Raspberry Pi (3 B+ or 4 preferred)
- 16GB MicroSD card
Step 1: Raspberry Pi (Initial Setup)
A Raspberry Pi is the brains and brawn of this project, so the first thing we'll need to do is to set one up for our project. I've tried this project on both a Raspberry Pi 3 B+ and a 4, and they both seem to work fine.
Raspberry Pi's are microcomputers which store everything on a microSD card instead of a hard drive...including the OS. The typical way to use them is to download the latest OS and burn an image of it onto a microSD card as follows:
- On a separate PC or laptop, go to https://www.raspberrypi.org/downloads/raspbian/
- Download the latest Raspbian OS. (Buster at the time of this writing). There are multiple versions available on the page which give more or less included software depending on your preference. They should all work fine, but I like to use the option "Raspbian Buster with desktop and recommended software" because it includes some programming IDEs and other handy apps. Easiest way is to download the zip version.
- Burn Raspbian image to microSD card. There are many applications you can use to burn the Raspbian image to your microSD card but I used the balenaEtcher program which you can get here. Insert the microSD card into your computer and run balenaEtcher. For the disk image, select the zip file you downloaded, then select your SD card, and hit flash. The tool will unzip the disk image files and burn them to the SD card. IMPORTANT: Make sure the drive you're selecting is the microSD card...the tool will overwrite whatever drive you specify so make sure you've chose the correct one.
- Fire up your Raspberry Pi. Insert the microSD card into your Raspberry Pi. Connect up your power, mouse, keyboard, and speakers. If you follow the prompts, it's pretty self-explanatory...set your location/time, set a password, and connect the WiFi.
This is all standard setup for a Raspberry Pi so if you need more details, you can find them here. We'll be doing the rest of our steps on the Raspberry Pi.
Step 2: Enable I2c
The Guitar Hero Controller uses i2c to communicate (i2c is a fairly common protocol used by electronic devices to talk to each other), so we need to enable this feature on the Raspberry Pi:
- Install libraries for i2c. The i2c libraries now seem to be part of the Buster standard build, but just in case, we'll run the installer for them. Open a shell (there's an icon for it on the taskbar at the top) and type the following:
- sudo apt-get install -y python-smbus
- sudo apt-get install -y i2c-tools
- Enable i2c on Raspberry Pi. In your shell type: sudo raspi-config. This will bring up your configuration window. Arrow down to InterfacingOptions->I2C to enable i2c for the device. To get out of the window, right arrow to Back and then to Finish to save the settings.
- Reboot. In your shell, type: sudo reboot
- Set custom i2c parameters. The default i2c baudrate (100k) seems to confuse the guitar occasionally, so we'll slow it down to 50k as follows:
- In a shell type: sudo nano /boot/config.txt
- This will open your config file in a text editor. Arrow down and find the line that says dtparam=i2c_arm=on. If it is commented out, uncomment it. If you don't have that line, add it. Below that line also add the following:
- dtparam=i2c1=on
- dtparam=i2c1_baudrate=50000
- Hit Ctrl + O to save the config file and then hit Ctrl + X to exit.
-
Reboot. In your shell, type: sudo reboot
Step 3: Install Pure Data
For the synthesizer sounds we'll use a program called Pure Data. This is a generative sound and interactive display tool that has been around for quite a while. It has a couple of features that make it ideal for this project...it has a node-based UI which is fairly easy to use, and it can receive signals from external sources such as python scripts.
- Install Pure Data. In a shell type: sudo apt-get install puredata
- This should install the software on your Raspberry Pi, but if it complains in the shell about not being able to locate all the files it needs, try this:
- sudo apt-get update
- Then run the install command again: sudo apt-get install puredata
- During install it will prompt you if you want to create directories for extensions, you can say Yes.
- This should install the software on your Raspberry Pi, but if it complains in the shell about not being able to locate all the files it needs, try this:
- Launch Pure Data. If it installed correctly you should see the program listed in the Desktop Start Menu under Sound & Video. Run it to make sure it launches.
- Set up Pure Data audio. The audio in Pure Data isn't usually on by default so you'll need to enable it.
- Set audio output to ALSA. When Pure Data launches you should see it's console window. Go the Media menu and Select ALSA as your output. You might see warning messages in the console shell that say it can't find certain files, but you can ignore this.
- Turn on DSP audio. In the console window, check the checkbox that says DSP.
- Test audio output. In the Pure Data console window, go to Media->Test Audio & MIDI. This will open a test file we can use to make sure Pure Data is working and that we can hear the audio. Turn on your speakers but keep them at a low volume at first (sometimes the audio can be very loud by default). In the test file, on the left side you should see a section called Test Tones. Click on the box that says 60 first and see if you hear any sound from your speakers. If not, try clicking the 80 box and then turn up your speakers until you hear sound. If you hear sound, try dragging in the box that says Pitch to the right of the Test Tones where you can change the frequency of the tones and see what happens.
If you are able to launch Pure Data and hear a sound from the test patch, then you're ready to go on to the next step. But Pure Data can get a bit finicky about the audio output the first time, so if you still aren't getting audio try the following:
- It's possible that the audio is routing through the HDMI cable, so to force it to use the headphones jack:
- In a shell type: sudo raspi-config
- Go to Advanced Options->Audio->Force 3.5mm ('headphone') jack
- Try rebooting. Sometimes this does the trick.
- Check your speakers and connection to the Raspberry Pi.
Step 4: Connecting the Guitar
The easiest way to connect the guitar controller to the Raspberry Pi is with an inexpensive breakout board such as the Nunchucky*. This board allows you to access the signal coming from the guitar without cutting off the plug or breaking open the guitar. On one side of the board are flat traces designed to fit perfectly into the plug coming from the guitar. There are also two small notches that allow the plug to click into place thus preventing it from coming loose. The traces lead to four header pins on the opposite side of the board.
Note: The Nunchucky comes with header pins but they are not soldered on so you'll need to do this yourself. For mine, I used 90 degree header pins instead which allows it to lay flat in the final project.
You'll need four wires to connect the Nunchucky to the Raspberry Pi. Connect the wires from the Nunchucky header pins to the Raspberry Pi's GPIO pins as follows:
- 3.3v -> Pin 1
- Data -> Pin 3
- Clk -> Pin 5
- Gnd -> Pin 9
In my project I used crimp connectors for the wires so that they didn't pull out as easily. But if you don't have crimp connectors, four individual female-to-female jumper wires will work fine. If you DO use the crimp connectors, make sure you pay attention to the order of the wires on the header pins and the GPIO pins. Also note, that on the GPIO pins, we skip pin 7. To account for this, I used a five-wire crimp connector on one end and skipped one slot.
To verify that your Raspberry Pi can detect the guitar controller, open a shell and type: sudo i2cdetect -y 1
It should print a grid in the shell with mostly double dashes in them. If the computer can detect the guitar, you should see the guitar's ID# 52 in one of the slots...on my machine it showed up in column 2, row 5...but it doesn't matter which one, as long as you see the number 52 somewhere in there.
If the computer can't detect it here are some things to try:
- Make sure your wires are tightly connected.
- Make sure you've got everything connected to the right pins.
- Flip the Guitar plug around. The Nunchucky doesn't prevent you from connecting the plug upside down, so it might but inverted.
- Make sure i2c is enabled on the Raspberry Pi (as shown in step 2)
*If the plug on the guitar controller looks familiar, it's because it is the same as the standard Wii Nunchuck controller...hence the name Nunchucky! This also means that you can use this same breakout board to connect to nunchuck controllers as well.
Step 5: Putting It All Together
Now that everything is set up on the Raspberry Pi we just need a little bit of code to make it work. You can download the code and other necessary files as follows:
- To download the code and other files onto the Raspberry Pi, open a new shell and type the following command (you might need to put 'sudo' before it): git clone https://github.com/analogsketchbook/keytarHero.git
- This will create a directory in your home directory called keytarHero (i.e. /home/pi/keytarHero) and download the files into it.
There are three main files in this package:
- WiiGHController.py: This is a python script opens up an i2c connection to the guitar and returns the values of the various controls. By default it also prints the values it's reading to the shell so you can see what it's doing.
- keytarHero.pd: This is the Pure Data patch file I created to create the music you'll hear. It is set up to read the values coming in from the guitar and routes them to various nodes to generate the sounds. I'll discuss the details of the patch in the next step, but ultimately you could modify this to do whatever you want from here.
- keytarHero.py: This is the script that kicks off the whole process and glues everything together. It launches Pure Data and opens the keytarHero.pd patch. It opens up a connection to the patch and passes the values from guitar to the patch.
The moment of truth! Make sure the guitar is connected to the Raspberry Pi and then your ready to go. To kick it off, you just need to run the keytarHero.py script. To do this:
- Open a new shell and type: cd keytarHero
- Then run the command: python keytarHero.py
That's it! If everything is working correctly Pure Data should launch and start playing the patch. You should hear a sequence of notes being played, and when you press buttons on the guitar, it should respond to it.
Troubleshooting
If it's not working, here's a few things to check:
- Pure Data patch not launching or getting an error about not finding files? The keytarHero.py script has the path to the Pure Data patch file hardcoded to '/home/pi/keytarHero/keytarHero.pd'. If you've moved your keytarHero folder or that patch file somewhere else, you'll need to update the script to use your path instead. To do this, open up the keytarHero.py file and look for the variable called PD_PATCH_PATH and change it to point to the directory where your keytarHero.pd file lives. Save the script and re-run it and you should be good to go.
- Is the guitar emitting a signal? The script should be printing the signal it's getting from the guitar to the shell continuously as a string of numbers, each representing the value of a control on the guitar. When you use a control on the guitar it should cause these numbers to change. If not, check that you've done the i2c setup and guitar connections correctly in the steps above.
- Is Pure Data audio turned on? The Pure Data patch provided in this package should automatically turn on the audio but verify that the DSP checkbox in the Pure Data console is checked on. Also check your audio settings as shown in Step 3.
- Is Pure Data receiving the signal from the guitar? In the upper right corner of the patch is a bunch of nodes responsible for reading the signal from the guitar and transmitting it to the rest of the patch. As you press the buttons on the guitar, the numbers in this section should update as well telling you that it is receiving the signal properly.
- Initializing variables in the patch. Pure Data can be a bit finicky about values in the patch not getting initialized. I've added mechanisms to trigger variables when it opens but it might be worth just clicking on some of the message boxes (the ones that look like they've got a bite taken out of them). This causes them to initialize and can wake them up.
A Tour of the Pure Data Patch
The setup described so far in this tutorial will get things working for you but one of the nice things about using Pure Data for this project, is that it can be customized to do whatever you want. When the patch is open if you hit Ctrl + E it puts the patch into Edit mode and you can change the patch. The details of using Pure Data are beyond the scope of this tutorial (there's lots of tutorials online for that) but it can be fun to tinker with it, so here's a general tour of what is happening in the keytarHero.pd patch in case you want to customize it:
- Guitar communication: In the upper right of the patch is a tree of nodes responsible for handling the signal from the guitar. The values from the guitar are a long string, so these nodes break up the string into individual values for each control, convert them to numbers, and then pass them to 'send' nodes (the ones that start with an s). Send nodes are assigned a name and emit the signal to 'receive' nodes of the same name. For example the 's whammy' node, emits the values coming from the guitar's whammy bar and the 'r whammy' node in the middle of the patch receives that signal and uses that signal to halt the sequencer. Send/receive nodes help reduce clutter of connection lines in the patch. I don't recommend messing with this section as it's kind of fussy to get right, but you can definitely add additional receive nodes throughout the patch as needed to receive signals from it as needed.
- Sequencer section: The middle section of the patch controls the sequencer. On the left side is a bar with a moving black square that shows you which note of a 16-note sequence it is playing. The strum key controls whether the sequence is playing forward or backward. The plus/minus buttons increase/decrease the speed. On the right side are five sets of numbers that control which notes play during each step. Each sequence is assigned to play when one of the five buttons on the fret is pressed. These numbers are MIDI values and you can change them to play whatever notes you want...just give them values between 0 and 127.
- Oscillator/FX section: In the lower left are the oscillator and FX nodes that actually make the sound. The primary oscillator is on the left. The midi values from the sequencer section are converted to frequencies and fed to the oscillator. It is mixed with a second oscillator coming from the right side. It's frequency is also controlled by the midi values but with an additional frequency offset driven by the X-axis of the joystick. This causes a detuned or whistling effect when you move the joystick to the left or right. In the lower right there is also a low pass filter node whose cutoff frequency is tied to the joystick's Y-axis. A low pass filter determines how much high frequency sound is removed from the sound. When the the joystick is moved to the downward position it cuts off much of the high frequencies which results in a muffled sound. When moved to the upward position it passes all the frequencies through resulting in a brighter sound.
- Initialization: In the upper left of the patch there are a series of nodes that initialize the patch when it launches such as turn on the audio and 'touch' various nodes to wake them up. Again you probably don't need to mess with this section, but if there are things you want to have happen when the patch launches, connect them to the node called 'loadbang'.
- I've tried to document the patch with comments in the patch itself, so hopefully that will give you enough information to explore different options from here.
Enjoy!
Additional Things to Try
Running the guitar 'headless'
It should be possible to run this project without being connected to a monitor/keyboard/mouse if you ran your Raspberry Pi off of a suitable portable power source. The Raspberry Pi doesn't quite fit into the opening on the back of the guitar but if you're feeling brave, you could make modifications to the guitar to fix that...or just mount the Pi to the back with screws and have it sticking out a bit. There are plenty of tutorials online about how to run scripts on the Raspberry Pi headless, but basically you'd want to run the command 'python /home/pi/keytarHero/keytarHero.py&' when it boots up. Theoretically then, you'd have a guitar with only one cable coming out of it to the speaker...just like a real electric guitar!
Additional Pure Data modifications
I had some other ideas for how the guitar could control the Pure Data patch but didn't get around to trying. These would be changes in the patch that might be fun to experiment with:
- Whammy bar: In the current patch the whammy bar simply halts the sequence playback, but I think it'd be better if the whammy bar also pitched up frequency at the same time just like a real whammy bar would. I tried to make it work for a while, but it was trickier than I thought. I think it might just be a matter of of adding an expression down in the oscillator section that adds a bit higher frequency to oscillator based on the value coming from the whammy bar.
- Strum bar: Currently the strum bar plays the sequence forward when pressed down and backwards when pressed up, but might be better to have it cycle through different sequencing options such as random step, etc.
- Plus/minus buttons: The plus/minus buttons change the beats-per-minute but it's a bit underwhelming unless you hit them several times. Might be good to have it increase by a greater amount each time. Or perhaps have it switch the sequencer between 16-beat, 8-beat, 4-beat, triplet playback.