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

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


Wednesday, May 23, 2018

Ships and Dynamites: A father and son made video game

My son is five years old now, and as he has got older I have begun to share my love of video games with him. He has taken a keen interest in my last two or three PyWeek entries, as so after the last comp he asked if he could help me make a video game. I told him "sure! why don't you design the game and make the graphics and sound, and I can do the programming". I asked him what the game should be about, what does the player do? He told me "You jump out of a big spaceship and jump over lots of dynamite and then get in another spaceship and shoot all the dynamite with your lasers". Sounded good so far. I asked him to draw me a picture of what the game looked like. He drew this:

I then got him to draw a few additional assets on paper: a dynamite box exploding, the word "level", the numbers 0-9 and a titlescreen for the game. I asked him "what about the player's character before they get into the ship? what do they look like?" He drew me this:

I took all of the pictures he drew, scanned them and then chopped them all up in Gimp. I wrote a quick bit of prototype code in python and pygame with the player running around in the game world, with the big ship in the background, little ships that you can jump in and shoot with, and dynamite blocks. My son gave some feedback on how the levels should be structured and gave the nod of approval.

Next I told him "we are going to need some sound effects ... what sort of sounds do you want in the game?". He made the sounds for the lasers, dynamite explosions and a little jingle for when the player dies. We recorded him making the sounds on my laptop's built-in microphone, and I used Audacity to crop the sounds and perform a bit of basic normalisation and noise filtering, before loading them into the game. "What about music?" I asked. He told me "the music has to go like this: da da da daaa da, da da da daaaa da! ...", so I recorded a snippet and set about making a quick orchestral arrangement around the tune he had hummed in Musescore.

Finally I asked him "So, what are you going to call our game?". He told me "It's called 'Ships and Dynamites' ...". "Shouldn't that be 'Ships and Dynamite'?" I asked. "No, dad ... it's Dynamites" he insisted. "OK fair enough ... Dynamites it is".

This is a brief playthrough of our final game:


It was really fun to do this together, we both had a great time. He has had fun showing his game to friends and cousins, and everyone we have shown so far seems to like the game, and I think he's learnt a bit about logically what has to go into a game, how to get something like this to work etc. If interested, you can download the game here:

ships_and_dynamites.zip (1.2Mb)
Source distribution: requires python and pygame


Monday, May 7, 2018

PyWeek 25: The Desert and the Sea


"The Desert and the Sea" was my solo entry for PyWeek 25 (April 2018), a twice yearly video game development competition that gets competitors to build a complete game from scratch in seven days using the python programming language. This competition's theme was "Two Worlds" and I made a 3D exploration and adventure game set across two parallel worlds connected via a series of portals.

 

The game was inspired (sort of) by early 90s adventure games like Myst; there's a bit of exploration to do and some spatial puzzles built around teleportation and having to move between parallel worlds to by-pass obstacles that exist only in one world or the other. The game uses Pygame and PyOpenGL to produce it's first-person perspective graphics, and I was pretty happy with the final visuals and feel of the game. I spent a lot of time "world building" in this one, trying to use the visuals along with audio and music to create a nice atmosphere.

 

Although it wasn't my best entry in recent times, it still managed to narrowly win both the individual and overall winner for the comp with an overall score of 3.95/5.0, so I was pretty pleased :).

Playthrough Video:


You can currently download the game as either a source release (works with Windows/OSX/Linux, but requires additional installations) or as a standalone Windows application (I'm still in the process of getting the standalone OSX version working):

 

Windows (tested on Windows 7/10):
the_desert_and_the_sea_pyweek25_windows.zip (76.4Mb)

Mac OSX: stay tuned!

Source Distribution (compatible with Windows/Mac OSX/Linux, requires python 2.7, pygame, numpy and PyOpenGL, see installation notes in README):
the_desert_and_the_sea_pyweek25_source.zip (11.9Mb)

If you are having trouble getting the game to run, or have a bug/crash to report, please email: randomprojectlab@gmail.com

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


Monday, January 29, 2018

Global Game Jam January 2018


Global Game Jam is an annual event held at approximately 700 sites simultaneously across the world in which participants join teams to create a video game in 48 hours. I participated this year at the Academy of Interactive Entertainment, Sydney site: was awesome. This year's theme was "Transmission" and I worked in a team with two programmers/developers and two 3D artists to create our game "Sonav" in which you control a boat navigating through a minefield under heavy fog. You need to use your transmitting sonar pulse to clear the fog and see obstacles while trying to move between objectives under a time limit. I worked on music, sound and UI graphics which was good fun (a nice change from programming).


I had chunks of free time during the weekend which I used to work on my own side project game (called "Transmission: defence") using a custom-built alternative bluetooth video game controller (called "Turny") that I had designed and built in the weeks leading up to the jam (see previous post on the development of Turny). You control four defence platforms using transmitted energy pulses to defend against incoming missiles. The frequency and range of the pulses are controlled by the four colour-coded knobs on Turny. The game was written in python and pygame.



Both games are available to download and play at:

https://globalgamejam.org/2018/games/sonav
https://globalgamejam.org/2018/games/transmission-defence

"Transmission: Defence" and "Turny" have also featured on "Shake That Button", a website that curates alternative controllers and games. There are some super cool projects listed there, check them out!


Thursday, January 25, 2018

Turny: an alternative bluetooth video game controller

With Global Game Jam 2018 coming up soon, I had the idea of building an alternative video game controller for which I could design a game for during the jam. I recently got my hands on an Adafruit Bluefruit LE m0 Featherboard, an Arduino-compatible microcontroller with built-in low-energy bluetooth module and I was quite keen to try and find a project to test it out on. I started thinking of types of control mechanisms that you don't really find on modern, conventional game controllers: I didn't really have too much time to try and use something really exotic that I'd have to order in, so I ended up thinking about paddles. Old games controllers dating back to the 1970's commonly used a single paddle, or rotational knob, for example on the Magnavox Odyssey and the Atari 2600. The original arcade version of Pong, one of the first video games used two potentiometer knob controllers for two player controller of in-game "paddles" (hence the origin of the term, in relation to the on-screen object the players control). No modern game controllers seem to use paddles or knobs anymore. I had a bunch of spare potentiometers sitting around, so I decided that I'd base the controller around a group of these rotational inputs.

I started off by testing out the bluefruit featherboard; I soldered on the headers, downloaded the appropriate packages for this board for use with the Arduino IDE. Connected it up and got the blink sketch working. I downloaded the Arduino bluefruit library and uploaded and ran the "controller" sketch from the examples that came with the library. I then installed the Adafruit Bluefruit LE Connect app on my android phone and connected to the featherboard. Messages all appearing normally on the serial console when selecting colours in the app. I then modified this sketch to colour a Neopixel based on the colour received through the colour picker function. I connected a neopixel up to PIN 5 and everything working well. I also downloaded the Adafruit BLE desktop app for OSX and tested the connection was working smoothly between the featherboard and my laptop, all good.

I found this library for interfacing on the desktop end via python. I tested the provided example 'list_uarts.py'; was working correctly to find the featherboard when it was switched on. I used this code as the basis for integrating communications with the bluetooth module in a pygame loop. I had to embed all of the code to connect to the device and continuously poll data into a separate thread which was called from a Scene/Director class and dumps the latest polled controller data into variables that gets read by the game during an event call. Everything seemed to work ok; perhaps a little bit laggy (approx. 100-200 ms of lag), but it's hard to tell.


I started designing a 3D printed case: I wanted to design something that was relatively quick to knock up in OpenSCAD: basically just a box with four pots, one each corner. I added space for a panel mounted momentary button in the middle on top and a hole from which I would mount a neopixel shining up to provide some feedback to the player for when the controller was connected/searching for a connection, or perhaps to use as indicators during a game. I printed a separate thin white circle that would sit on top of this hole (superglued on) to help diffuse the light coming from the neopixel. I also added holes on the sides for both a power on/off switch and the usb port for charging the battery via the featherboard. I designed a little logo to go on the top of the controller: I placed an imprint of this into the case model and separately printed (in a different colour) a solid version of the logo text that I could superglue on top of the imprint, to make it readable.


I connected up all of the electronics on a breadboard circuit to test everything was working ok. I connected the four potentiometers through to four analog input pins on the featherboard, a momentary button to a pull-up enabled GPIO input pin, the neopixel to one of the GPIO output pins, and a slide switch connecting the ground and enable pins on the featherboard. For the final electronics, I ended up designing everything around a small solderless breadboard which housed the featherboard; I wanted to be able to easily salvage out this board for future projects, and it meant a little less time soldering too.


Once I had all the parts printed and electronics wired up, I glued it all together. I wrote a little demo python script using pygame to connect to the controller and display a series of coloured panels corresponding to each of the rotational values of each potentiometer, just to test everything was working OK.

So far, my plan is to perhaps use this as a controller to design a game around for the upcoming Global Game Jam in a few days: I've thought of a couple of little "mini-game" ideas like a physics-based game where the knobs control the position of little trapdoors, or perhaps a tower defence game where the knobs control the viewing direction of little defence towers ... will have to see what the theme is when it is announced! If I do end up making a game for it (I'm sure I will), I'll post about it.

Update (30/01/2018): I did make a game, see: https://globalgamejam.org/2018/games/transmission-defence



Downloads:

3D model files and OpenSCAD source for the controller case can be found at:
https://www.thingiverse.com/thing:2769138

Code for running the controller can be found at:
https://github.com/mit-mit-randomprojectlab/turny-controller

Code for running a pygame demo on a desktop/laptop that connects to the controller: to be uploaded.