As much as I enjoy working on code and game design for game jams, recently I've been having a lot of fun working on audio and music: I think game music is really cool to work on, because like with film, the music has to support the themes, atmosphere, pacing and story that's going on in the game. I think game music is fun too, because it's easy to draw from lots of different genres and styles of music, and people accept that game music can sound a bit quirky.
I've worked on music for a couple of recent jams:
https://soundcloud.com/user-349094787/improbable-mission-force-medley
"Improbable Mission Force" (https://pyweek.org/e/pw---__/) was a PyWeek 28 Entry for the theme "Tower" that I worked on with some PyWeek veterans: I did the music/audio and a bunch of 2D artwork, plus some script and voice-acting: was super fun. Game started off in a sort of Die Hard-like 2D shooter, but then halfway through the jam our graphics-guy showed us the player character art, which was a bit more like xXx so the music made a bit of a turn from action-orchestra to punk and guitars, and some how synths got in there and it was lots of fun.
https://soundcloud.com/user-349094787/bunker-builder
"Bunker Builder" (https://alakajam.com/8th-alakajam/874/bunker-builder/) was an Alakajam #8 entry I worked on the audio for: I took a lot of inspiration from the the soundtrack to WarGames.
https://soundcloud.com/user-349094787/el-ratto
"El Ratto" (https://karhal.itch.io/el-ratto) was an entry to the Historically Accurate Game Jam #2, in April 2020 for the theme "Black Death": this one was fun because I got to do a bit a research on medieval music, and had a go at playing with traditional instruments.
https://soundcloud.com/user-349094787/hackr0ute
"Hack::R0ute" (https://alakajam.com/scorespace-alakajam/961/hackr0ute/) was an entry to the ScoreSpace x Alakajam Game Jam in June 2020 for the theme "Connections". I worked on audio/music for the game.
I'll keep posting new music I do for jams and other games to my Soundcloud page here:
https://soundcloud.com/user-349094787
Showing posts with label Music. Show all posts
Showing posts with label Music. Show all posts
Saturday, June 27, 2020
Sunday, December 15, 2019
Arduino Power Moon
I wanted to add a bit of light and sound, so I started digging through spare Arduino boards to see what I could make work with battery power in a minimal footprint. I ended up using a Adafruit Gemma m0, as it's small, has a battery JST input, on/off switch and a single Dotstar three-colour LED mounted on the board already. All I needed to fit in with it was a small lipo battery and 8ohm speaker for sound and it was good to go.
I wanted the power moon to be able to change colours (as they appear in various colours in the game, depending on which kingdom you are in), so I 3D printed the moon using transparent filament and designed a little cavity inside the moon to house the electronics and light. The resulting effect with the LED on is that the filament catches the light and creates a nice glowing effect.
For music, I wanted to go just a little step beyond a series of single tone beeps, so I did a little research on how to get timer counters and interrupts going on the Gemma m0 (and other SAMD boards), mainly by studying the existing Arduino "tone" implementation for this chip. I ended up creating a modified set of tone functions that use both timer 4 and 5 to generate two pulse wave voices so I could play some very basic polyphonic music. There are three I/O pins on the Gemma and I wanted to keep one free as a switch to control the activation of lights and sound, hence just two sound channels.
For the electronics, I soldered the Gemma pins directly to each end of the speaker (via a pair of resistors) and wired up a vibration-activated switch between one of the digital inputs and ground, so that I could trigger light/sounds shows without having to put in a button, or open up the case. I fit a small lipo battery in between the Gemma and the speaker, so everything is together in a small disc-shaped package.
For music, I composed some two part tunes using Musescore and wrote a little python script to convert Musescore mscx files (XML formatted files that contain the music data in terms of the note pitches, timing and durations) into data embedded into a header file I could compile straight into the Arduino code. I then wrote a system in for pulling out the appropriate note data at the appropriate time to pass on to the modified tone code.
The moon is made up of two halves that need to be able to come apart (in order to switch it on/off and take the battery out for re-charging), so in order to have something that can open and close easy, I glued some small magnets to the inside of each side of the case that hold the moon together. Seems to work pretty well!
Here's a video of the moon in action: Merry Christmas!
Design Files:
3D Printed Case STL files:
https://www.thingiverse.com/thing:4047914
Code for running the power moon:
https://github.com/mit-mit-randomprojectlab/power_moon
Tuesday, July 10, 2018
Pentasynth: A homebuilt pentatonic keyboard and synth (part 2)
This is part two (see part one) of a post on a custom-built Arduino-based synthesizer and keyboard called “Pentasynth”. Pentasynth uses a keyboard based on a five note pentatonic scale, so it’s easy to play for people with limited background in music (such as young kids) and encourages experimentation and improvisation. Pentasynth creates a user-selectable accompaniment including different drum patterns, bass lines and chord progressions and allows the user to play a pentatonic melody line over the top. Under the hood, Pentasynth runs on an Adafruit Metro Mini (using the same ATmega328 microcontroller as the Arduino Uno) and generates three channel audio (two square-wave tones and one pseudo-random noise drum beat), which is passed through and onboard amplifier and speaker, while simultaneously passing all outputs as MIDI messages via the USB for either a lo-fi or hi-fi audio experience. Pentasynth has controls for volume, tempo and selection of different accompaniment patterns. The keys and case components are 3D printed, with the main case panelling carved from clear acrylic using Carvey. Custom PCBs containing switches for detection of key presses were also carved on Carvey.
In the previous post, I discussed the hardware development of the keyboard including 3D printed keys and CNCed case and key switch PCBs, and the use of a wavetable synth for audio. I wasn't that happy with the audio quality from the wavetable synth, so I re-wrote my own system using hardware PWM square-waves for audio, with a bit of re-jigging to add MIDI output. I'll also discuss the electronics in a bit more details and the code running on the Arduino.
The ATmega328 has three hardware timers that can each be used to drive interrupt routines or run a hardware Pulse Width Modulation (PWM) signal. Since I wanted to keep the main program on the microcontroller free to managing key and control inputs and running an accompaniment system, the hardware timers were the only way to generate audio signals. By default, two of these timers (Timer 1 and 2) are unused, and the other (Timer 0) is set to run at 1kHz and controls functions such as millis() and delay(): any change in this frequency would mess with these. I've setup Timer 2 to run a square-wave output based on the note pressed on the keyboard and Timer 1 to run a square-wave from an accompaniment baseline. In order to get a pseudo random noise signal for a drum beat, I've piggy-backed an interrupt routine on the existing 1kHz to generate a pseudo random square-wave (i.e. randomly ordered series of LOW/HIGH) using a Galois linear feedback shift register (see this nifty little post). The random signal switched at 1kHz sounds a bit like a snare or open high-hat, so makes for a decent (lo-fi) beat.
I ended up re-jigging the electronics to account for the changes in signal generation (I'm glad now I had left everything breadboarded on the final keyboard :) ). The three audio channels are generated as separate square-waves on three digital output lines (pins 9 and 11 on the metro mini, corresponding to the hardware PWM outputs) and pin 13 for the drum beat. The separate signals are then all connected together via 220 Ohm resistors to a potentiometer pin used for volume control. This output is then fed through a single NPN transistor, which is also connected the the 5V output, acting as an amplifier which is then connected to a 3W, 4 Ohm speaker. The ten keys and four control buttons are connected to the remaining digital input pins, and a second potentiometer connected to an analog input pin which is used as tempo control for the accompaniment.
In terms of code, the microcontroller polls the switches corresponding to each key and send the appropriate tone via both the audio output (hardware PWM) and a MIDI message. The code also implements an accompaniment system. This consists of a drum beat, base line pattern and four-step chord progression that runs along at the user selected tempo. The control button for each of the drums/bass/chord is used to cycle through the available patterns: the player can therefore experiment and choose a combination of drums, bass pattern and chord progression that they like and then improvise a melody over the top of this using the keys. A fourth control panel button is used to switch between different pentatonic modes (at this stage either a major or minor pentatonic scale).
The video shows the keyboard in action. My five year old son has been having fun playing around on it: I think he mostly likes that he can ramp the tempo up to crazy speed and mash the chord progression button to create havoc :).
Arduino code for Pentasynth can be found at:
https://github.com/mit-mit-randomprojectlab/pentasynth
The 3D models of printed parts and carvey SVG design files can be found here:
https://www.thingiverse.com/thing:2975555
Edit (October 2018): Pentasynth also made it to the semi-finals of the 2018 Hackaday Prize, for which I won $1000! Pretty chuffed :) see:
https://hackaday.com/2018/10/16/these-twenty-projects-won-the-musical-instrument-challenge-in-the-hackaday-prize/
https://hackaday.io/project/161671-pentasynth
Sunday, June 24, 2018
Pentasynth: A homebuilt pentatonic keyboard and synth (part 1)
I’ve been working on another music project: it’s a custom-built Arduino-based synthesizer and keyboard called “Pentasynth”. Pentasynth uses a keyboard based on a five note pentatonic scale, so it’s easy to play for people with limited background in music (such as young kids) and encourages experimentation and improvisation. Pentasynth creates a user-selectable accompaniment including different drum patterns, bass lines and chord progressions and allows the user to play a pentatonic melody line over the top. Under the hood, the audio generation is performed using a four channel, 10kHz playback of wavetables (sine, pulse, sawtooth, triangle and random noise) using a micro-controller generated PWM that is then passed through a low-pass filter and into a small amplifier and speaker. The microcontroller is programmed in Arduino, with code based on “The Synth”, a wavetable synth library by DZL/Illustron. Pentasynth has controls for volume, tempo and selection of different accompaniment patterns. The keys and case components are 3D printed, with the main case panelling carved from clear acrylic using Carvey. Custom PCBs containing switches for detection of key presses were also carved on Carvey.
My local makerspace (Thinkspace) got in some carvable PCB blanks for Carvey last year, and I had been thinking about trying them out. A while ago, I had picked up a broken kids toy electric guitar from the side of the road (I like picking up random electronics junk I find :) ). I ripped it apart just out of curiosity to see how it worked. The guitar was controlled by little buttons: the buttons were basically bits of plastic that held a little piece of clear rubber with a little bit of conductive material in it. When the button is pressed, it would push the conductive material across a PCB with a criss-cross of conductive tracks that close a switch, that is then detected by a little microcontroller to produce a sound:
I salvaged out the little clear rubber bits and decided to try and carve my own PCB “criss-crosses” for the keys on my own keyboard. The advantage of designing it this way, instead of using some off-the-shelf buttons (the usual “clicky” kind) is that the keys then have a nice, soft tactile feel to them and don’t make a horrible “clicky” sound, that interferes with the music (I had regretted using clicky switches in a previous handheld video game project I made).
For carving the PCBs, I used these 2-by-3 inch PCB blanks and designed the circuit as an SVG with paths to cut out the ground and positive voltage paths for each of the ten switches (ten keyboard keys). I had to split the pads across three separate PCBs. I used a V-shaped milling bit (20 degrees) to mill the cuts into the PCB at a cutting depth of approximately 0.2mm. I found that in practice the height wasn't super accurate on Carvey, so had to experiment with different height each and every time I setup a new board to mill. Once the tracks were milled, I used a 1/16in to drill holes for screws and through holes for soldering connections to the PCB pads, and a 1/8in flat milling bit to cut out the final board.
I 3D printed banks of keys in different colours: I designed the “neck” of each key to be a 1mm height layer which produced the flex that allowed the key to swivel when pressed (printed in PLA). The keys were coloured in lots of three and two per octave, to give the feeling of the black keys on a normal piano (which also follow a major pentatonic scale). Originally I intended to design the entire case as a single 3D print, but found it was going to be fairly big (and hence take forever to print), so I ended up changing the design. I created one big baseplate out of clear acrylic (which I carved on carvey, with drill holes) and connected everything to this with screws and a screwdriver. I 3D printed an array of standoffs and other knick knacks to hold the assembly together. I also carved from clear acrylic a top panel which held two dials (one for volume, one for accompaniment tempo) and four control buttons for the accompaniment. This panel also had the small speaker mounted to it.
For the electronics, I used a Adafruit Metro Mini 328 (running at 5V/16MHz), an Arduino compatible board that uses the same ATmega328 chip as the Ardunio Uno. Each of the ten keys is connected to separate digital-in pins, and the remaining GPIO pins are connected to buttons and pots for the controls. The digital PWM output from the micro is then connected to an RC/low-pass filter (to create the waveforms from the PWM pulses) and the output sent to a 4-ohm, 3W speaker after amplification. Originally I had a small D-class audio amplifier I had left over from another project, but I accidentally broke it while desoldering an existing header off it, and so had to put together a simple, single stage transistor amp (which is very soft, and a temporary fix until I get another amp).
Instead of hard-soldering everything into the arduino, I got a bit lazy and decided to glue a small breadboard in and connect everything up via the breadboard. The advantage with this is that I can plug and swap-in a different microcontroller/synths/amplifiers in the future (which I am intending to do).
I'm pretty happy with the look and feel of the keyboard (it's a bit raw looking, but kind of cool), but not super happy with the sound at the moment: I need to get a proper amp for a bit of amplification, and I've found that the audio from the arduino synth library I'm using is not super nice sounding (it sounds a bit like a bad/cheap kids toy piano at the moment). I'm going to do some brainstorming for updating the audio, hence a probable part two post on the project: stay tuned!
The 3D models of printed parts and carvey SVG design files can be found here:
https://www.thingiverse.com/thing:2975555
Sunday, April 29, 2018
Python-based MIDI Keyboard Visualisation
On my walk home from work the other day, I came upon a discarded electric piano keyboard on the side of the road. It looked to be in fairly decent condition except for a layer of dust that had built up on the top of the case; it had probably been sitting inside unused for quite a while. I brought it home, thinking that it was probably broken, but that I would salvage the main keyboard and any other nice working bits inside (including a pitch bend wheel). When I got home, I chucked a couple of AA batteries in a switched it on and voila, working perfectly; all keys in working order, and the USB MIDI interface too.
It seemed like a bit of a waste to rip it all apart, so I got thinking about interfacing something interesting to the MIDI interface. I did a bit of research looking for video games that had been designed with a piano keyboard as an input device: I found a reasonable number of projects involving adapting existing games to use a piano input as a bit of a novelty (i.e. this and this), but I couldn't find much in terms of games that explicitly designed with piano input from the start.
I started off by coding up a relatively simple rainbow fireworks display linked into key presses using pygame running through a laptop connected to the midi keyboard and into a TV via HDMI. I coded little fireworks to go off at horizontal positions corresponding to pitch of the pressed key, cycling through colours in the rainbow and handed it to my five year old son to let him have a bit of fun. He seemed to like it; it was a bit like an experiment for him to see how it worked.
I might end up expanding on this idea: I've found products like this that create a whole game out of playing the piano.
Code available at:
https://github.com/mit-mit-randomprojectlab/midi_piano_visual
It seemed like a bit of a waste to rip it all apart, so I got thinking about interfacing something interesting to the MIDI interface. I did a bit of research looking for video games that had been designed with a piano keyboard as an input device: I found a reasonable number of projects involving adapting existing games to use a piano input as a bit of a novelty (i.e. this and this), but I couldn't find much in terms of games that explicitly designed with piano input from the start.
I started off by coding up a relatively simple rainbow fireworks display linked into key presses using pygame running through a laptop connected to the midi keyboard and into a TV via HDMI. I coded little fireworks to go off at horizontal positions corresponding to pitch of the pressed key, cycling through colours in the rainbow and handed it to my five year old son to let him have a bit of fun. He seemed to like it; it was a bit like an experiment for him to see how it worked.
I might end up expanding on this idea: I've found products like this that create a whole game out of playing the piano.
Code available at:
https://github.com/mit-mit-randomprojectlab/midi_piano_visual
Friday, December 15, 2017
Teensytune: A Teensy-based MIDI controller/keyboard
Teensytune is a homebuilt MIDI controller/keyboard built around an old broken keyboard using the Teensy microcontroller. It features 49 keys, a programmable 16 beat drum machine, pitch bend/modulation control and two recordable loop channels with controllable tempo. It outputs MIDI signals along a USB, so you can plug it into a laptop or any other MIDI synth to generate the actual sounds. It is constructed from a wooden frame with custom sideboards and control panels made using Carvey, a programmable 3D carving machine.
This post is a continuation of previous post on rebuilding an old broken electric piano. I last touched this project about 12 months ago, where I had a Teensy reading the keyboard state and passing MIDI messages to a Raspberry Pi which was running a synthesiser and outputting sound to an amplified speaker. I ended up having a lot of troubles getting the sound output from the RPi working reliably: I could never really find an acceptable balance between getting nice stutter-free sounds with low latency, even after trying custom firmware and playing with countless settings. I got frustrated and moved on to other projects.
12 months later I decided that it's time I moved on with this: I've dropped the RPi synth for now and have just focussed on getting a workable MIDI instrument up and running, leaving space inside the case for expanding the project to include a synth, amplifier and speaker at a later stage.
Implementing the Controls:
After I got the basic circuit and code setup on the Teensy for reading the keyboard state, I started to focus on developing some cool controls. I started by adding a simple drum accompaniment function using a single on/off switch and a potentiometer for controlling the tempo. The beat is run through an interrupt using a PIT timer on the Teensy that sends a MIDI note for the current beat in a static 16 beat pattern, that is looped on repeat. Changes in the tempo pot are used to reset the interrupt interval time. I added an old two axis joystick I had sitting around and read the values using two analog inputs on the Teensy and translated these into pitch bend and modulation MIDI messages.
In order to provide a bit of feedback to the player, I decided to try and add in some Neopixels for coloured, flashy fun and a two-line character display. I plugged in a Neopixel to test everything was working fine: all good. I got this two-line character display which interfaced to the Teensy via I2C to display out data, for example, on the instrument selection and provide feedback for the programable drum machine. The display is a 5V device, so I used a logic level convertor to convert to/from the 3.3V signals on the Teensy. I2C on the Teensy 3.1 requires that both SDA and SCL data lines be connected to 4.7KOhm pull-up resistors, which I did. I used this library to control the display: tested I could display some basic text and instrument number, and all is working well. I ended up using the character display to provide visual feedback for programming the 16 beat drum pattern: one line of the display shows the instrument number assigned to each beat, and the position of the current working beat flashing on the screen. I added two extra buttons for scrolling the working beat left or right, and setup the beat to be programmed to a new drum instrument by pressing one of the bottom 10 keys on the keyboard.
Finally, I implemented two recordable loop channels. The idea with this was that I could play an input sequence to the keyboard over the 16 beat period of the drum machine, and the loop channel would record and playback this sequence on repeat, while the drum machine was switched on. I could also playback these sequences at a variable tempo using the drum machine's tempo knob, providing the ability to record complex patterns at slow speeds, then ramp this up to a fast speed at playback which would otherwise be impossible to play manually. Each channel is controlled by a single button: when the button is initially pressed, the recording begins and starts to playback the input sequence in a loop. Subsequent button presses turn the playback for this loop on and off, and holding the button down for 1 second deletes the sequence, making the channel open for re-recording a new sequence. To implement the record and playback, I created two arrays in memory that contain the note pressed and the sampling time over the time period of the 16 beats. During recording, these arrays are written to using the main program loop with timing provided using Teensy's "elapsedMillis" type. Playback is achieved by using two PIT timers with interrupts to ensure playback timing is smooth regardless of what is happening in the main program.
I linked one of the two channels to have additional pitch control using the bottom octave of the keyboard during playback, gaining inspiration from this project. During recording, the first note of the pattern becomes the "root" note of the sequence. During playback, keys pressed in the bottom octave of the keyboard are used to re-assign the root note of the sequence, which acts to shift the pitch of the entire sequence up or down by a fixed amount. This provides that ability to make this sequence a "baseline" and have the player manually control a chord progression in a song with a single key press.
Designing the Case:
I bought some 19 mm thick dressed pine for building a new housing for the keyboard, because the old plastic one looked ugly, and I wasn't looking forward to 3D printing new panels to fit the controls I wanted. I put together the base and back board by hand: glued two bits of timber together and screwed them in for good measure. I then designed side panels and top panels to be cut out and decorated using Carvey. I designed the panel to hold all of the controls to be carved also using Carvey. I had to use two different milling bits to get the right combination of cutouts and fine detail in the lettering on the panels, and I had to carve first on the front and then on the back to complete the design/housing for the display, joystick and electronics PCBs.
Putting it all together:
I wired up the Teensy and connections to the keyboard on a perma-protoboard, tested this was working well leaving the other components on a breadboard. I connected up two neopixels to use as part of the visual feedback to the player: I mounted these to be facing up through the top control panel adjacent to each of the loop channel control buttons. These light turn yellow for standard operation, pink when the player is selecting a new instrument, blue to indicate a loop channel has a recorded sequence available, green to indicate this channel is currently playing and red to indicate the channel is currently being recorded. I then wired up and soldered on the remaining components to the back of the control panel, connected everything up to the keyboard and screwed it into the wooden frame.
This is a video of Teensytune in action playing an interpretation of "Rainbow Road" from Mario Kart 64 (I love that game). Starts off by programming the drum machine, then recording two loops: a baseline and a little flourish. The actual song starts about 1:27. When playing with the right hand, the left hand is controlling the chord progression by shifting the baseline. Sorry about my poor piano skills :).
I'm hoping to expand the project by using the available space to install a small embedded computer to perform the synthesis, and add in an amplifier and speaker, so that the Teensytune can operate independently of a laptop. Stay tuned!
Teensytune Code:
The code that runs on the Teensy can be found at:
https://github.com/mit-mit-randomprojectlab/teensytune
There are a few required libraries for the neopixels, two-line display and port expander, listed in the readme.
Wednesday, November 16, 2016
Electric Piano Part 2: Raspberry Pi SF2 Synth
This is a continuation of a previous post on re-building the electronics for an old, broken electric piano keyboard. After getting the keyboard working as a MIDI device, I decided to add in a Raspberry Pi to act as a synthesiser to actually generate out different instrument sounds based on the MIDI data from a Teensy which is used to read the keyboard state.
I found some good instructions here for running Fluidsynth, an open-source, command-line based synth on the Pi that uses Soundfont sf2 files. The great thing about soundfont is that I can download and pick and choose form thousands of different instruments for free in the internets, which will make for a more interesting playing experience than the simple square waves that I can generate on the Teensy. After install Fluidsynth, I connected up the MIDI/USB connection from the Teensy into a Raspberry Pi 2 model B, and ran: "fluidsynth -a alsa /usr/share/sounds/sf2/FluidR3_GM.sf2". I then put Fluidsynth into the back ground using cmd-z and ran: "aconnect 20:0 128:0" to route the MIDI input from the Teensy (client 20, port 0) to Fluidsynth (client 128, port 0 on my machine). I could now hear a standard piano instrument when playing the piano, but the sound is fairly delayed through the HDMI audio (a latency of maybe 250 ms by my guess). Tried changing audio output to headphones using "amixer cset numid=3 1", and the delay is slightly less noticeable, but the sound quality is dreadful.
A bit of digging around on the internets regarding Raspberry Pi audio quality, and I came across this, an experimental firmware update for improved headphone jack audio quality, using a different DAC interface. I ran "sudo rpi_update" (I ran it on Oct 12th) and went and added two lines to my /boot/config.txt file: "audio_pwm_mode=2" and "dtparam=audio=on", rebooted and re-tested audio. The quality improvement is very noticeable; at least through my headphones, the quality of sound is now acceptable.
I turned my attention to trying to get amplified audio out of my setup. I connected up a class D audio amp I had left over from a previous project to the 3.5mm audio jack on the RPi, powered it using the 5V out from the RPi GPIO and connected it up to a 4 ohm 2.5W speaker that was inside the original piano keyboard. After configuring the RPi audio volume to 80% using "amixer cset numid=1 -- 80%" I was getting a reasonable sound coming out when playing. I ramped up the volume to 100% on the gain pot on the amplifier and played again: now quite loud and a little bit distorted. When I power cycled the RPi I was getting a fairly loud popping sound coming from the speaker, and also when the RPi booted up again. When I had the volume up to max I was getting a little lightning bolt brown out warning coming up on my screen too ... I decided to tune the volume down to a slightly more modest level of 80% again. Didn't notice the brown out issues again. I added a pot to the signal line coming out of the RPi and into the amplifier for volume control.
I did a bit of configuring in my /etc/rc.local file on the Pi to start everything up automatically:
amixer cset numid=3 1
amixer cset numid=1 -- 80%
fluidsynth -s -i -a alsa -z 256 -c 6 -f fs_config.txt /usr/share/sounds/sf2/FluidR3_GM.sf2
sleep 10
aconnect 20:0 128:0
The -c and -z flags are for controlling audio buffer sizes and number of buffers in fluidsynth/alsa: setting these I'm able to find an acceptable middle ground between low latency and infrequency of audio stuttering: I still sometimes get a little bit of stutter on instruments with complex, long lasting waveforms, but the latency is now at an acceptable level (I haven't figured out yet how to measure it precisely, but I mean from a playing/responsive feel perspective). I also setup a configuration file for Fluidsynth so I can automatically set the instruments for different channels (fs_config.txt).
Next thing I'm going to do is add some more controls onto the Teensy and then package the whole thing up in a new custom designed case. Stay tuned!
Wednesday, October 12, 2016
Electric Piano Part 1: Turning an old piano into a simple synth and MIDI device
Recently, my father in law donated an old electronic piano keyboard for me and my son to play around with, an old Yamaha PSR 8 from the 1990s. When we brought it home, my son accidentally pulled off the tip of the 9V DC adaptor that came with it and when I plugged it back on I got the polarity wrong and we broke it (sad face). Yah, I know, I know ... I got lazy and thought I definitely had it the right way (who knew there was no standard for the polarity of DC power pack tips? Now I do) ... will always check with the multimeter from now on.
So I opened up the case and had a peak around. Can't see any obvious physical damage (no burnt out or broken components). Had a search online for some repair manuals for this keyboard and found a few pages, but to be honest wasn't that keen on trying to find replacements parts. So ... only one thing left to do: gut it and rebuild the electronics again from scratch!
I unscrewed and pulled away the actual keyboard assembly from the rest of the case. Had a look at the keyboard itself and contacts for keys. Running along the back of the keys is a single long PCB with contacts for each key and a bunch of diodes on it (one for each of the 49 keys) that all map back to a 15 pin connector. A bit of googling and it looks like this is a switch matrix. I found this helpful reference which seems to explain how this circuit works: keys are grouped into nine rows, each with a set of six keys (except for the last row which contains a single key), where each key in a row shares a common ground, and the first pin of each row shares a common contact on the other end of a diode, as does all the second pins etc. The state of each of the 49 keys can be read by selectively reading from 6 digital input pins while incrementally setting 9 output pins to ground one at a time.
I decided to use my Teensy 3.2, which I hadn't previously used, to do the reading of keyboard state. I installed the teensyduino add on for Arduino 1.6.11, tested out an LED blink code and got a 4 ohm speaker working with simple melody. I then got a simple, single switch working with a INPUT_PULLUP mode, all good, lighting up pin 13 LED. Then I wrote a sketch to flick back and forward between two pins, both in INPUT_PULLUP mode and to a common ground, by setting the other pin OUTPUT/HIGH while reading the other (diodes built into the keyboard to stop current pulling between pins when both keys are down). Working well.
I snipped and stripped the ribbon cable I found connected to the 15 pin connector coming off the key switch PCB, plugged it into my breadboard and connected to 15 digital pins on the Teensy. I wrote a sketch to implement a basic matrix to read out all 49 keys. I found I had to add in a 10 us delay between setting Teensy pins to INPUT_PULLUP mode and reading them (as suggested by the Teensy instructions on their website) and also found I had to add a 50us delay between subsequent reads of each key on the matrix to get things to work such that more than one key could be read at a time. Once all keys read, wrote a program to output the tone corresponding to the highest key. Basic monophonic piano implemented!
I decided to round off this design my modifying the Teensy built in tone function to produce four simultaneous tones using the 4 PIT timers available. I modified the standard Teensy tone implementation to use up to four timers simultaneously and prioritised timers to the higher keys on the piano. I used four pins each connected through a 330 ohm resistor back to the speaker and I also chucked on a potentiometer for volume control. Working fine, and I could now play polyphonic tunes pretty well (up to four simultaneous key presses). The square waves sounded pretty ordinary through the little 4 ohm/500mW speaker, so I also tried connecting the ends to an RCA co-axial cable and plugging it into an external amplifier, which was a little better.
The code for running this all can be found at:
https://github.com/mit-mit-randomprojectlab/keyboard_multitone
At this point I decided to try an alternative direction for the design: instead of doing the sound synthesis on the Teensy, what if I used an additional computer or micro to do it for me? I decided to try and get the keyboard working as a MIDI device. I changed the code to output MIDI "noteon" and "noteoff" messages on key presses and configured the teensy to output MIDI, using the options available in the Arduino IDE. The teensy library in teensyduino makes this very easy: there are a bunch of send/receive midi functions built in, no need for any additional code or external libraries.
The code for running this all can be found at:
https://github.com/mit-mit-randomprojectlab/keyboard_midi001
Once i got the keyboard working as a MIDI device, I downloaded and installed "Fluidsynth" on my macbook to read in the MIDI messages and play sounds. I used the "General User GS v1.47" font by S. Christian Collins and started up Fluidsynth from the command line using the following settings: ./fluidsynth GeneralUser_GS_v1.47.sf2 -o midi.driver="coremidi" -o audio.driver="coreaudio"
I then used a software package called "MIDI Patchbay" to patch the output from the Teensy to Fluidsynth, and voila! I can play synthesised piano through my laptop. Once in fluidsynth, I used "prog <channel> <inst>" to set different instruments.
So thus far I've managed to (a) make a simple synth (square waves) which is OK, but lets face it, my son will only find squares waves interesting for a short amount of time! and (b) make a MIDI keyboard, which can play all sorts of cool sounds, but only when connected to and setup on my laptop, so my son can't really go and turn it on and play himself. I am going to try and keep going down both design routes and (a) get a synth working on the teensy that can play a wider variety of tones/waveforms and (b) try connecting the MIDI keyboard up to a dedicated raspberry pi for doing the audio synthesis. Stay tuned!
Subscribe to:
Posts (Atom)



























