Lore
Unknown location, Yukon, Canada
You're wandering through the forest. You're lost in the dense thicket. There's a clearing. A wooden, cozy-looking cabin sits right in the centre. You can see some sort of faint glow through the window. Huh?
You enter. You find the source of the glow: a strange, alien machine in the corner of the main room. "...Hello? Hello?" No answer from anywhere in the cabin. The machine piques your curiosity, naturally. There are a few buttons. You hesitate for a few seconds. Your eyes are glued to them. "Here goes nothing..."
The machine starts. You hear the whirr of its engine. Its eerie glow gets brighter. Yellow lights blink in some weird, cryptic sequence. Loud, organ-like notes bellow through a set of pipes at the top of the machine.
Technical Details
Version: 1.5.0
This synthesizer's source code can be found here: GitHub
I'm going to give you a quick rundown on how it all works - but the repository above contains all of the specifics.
Technology
This synthesizer was created using TypeScript. It uses the Web Audio API to generate notes in the browser. It uses the aptly named Web MIDI API for receiving MIDI.
Because notes are generated in and via the browser, no audio files (.wav, .mp3, .ogg, etc.) are actually needed. The only file used is the reverb impulse response, which is wrapped around each note. The specific process is called convolution.
Frequency Calculations
Each of the grid's pads are given an ID from 1 to 64, respectively. This is in ascending order, so bottom left is 1 and top right is 64.
I'll use the first pad as an example. When that pad is pressed, its ID of 1 is passed into a note calculator function. Some transposition is needed so that the note is neither too low nor too high. The pad's ID is changed to equal padId - row * 5 - 17. The pad's row is defined as Math.floor((padId - 1) / rowLen) + 1, with rowLen being the square root of the grid size. In this case, row = 1.
After this transposition, the first pad's ID is -19. So, why not just subtract 20 from every ID if they're going to increase in sequential order? This grid is not completely linear - like the grid of the Ableton Push that it was inspired by - so duplicate notes have to be taken into account. Each pad's final frequency is also defined by its row, rather than just its initial ID.
The pad is close to its destination, but a couple of steps still have to be taken. First, it must be ensured that the notes fit into some sort of scale. A chromatic grid might sound fun, but it's largely useless. Some safety nets are required. There are multiple ways of interpreting it, but I chose the Lydian mode - or the notes 1 2 3 ♯4 5 6 7. Without getting too into the weeds, that is accomplished by once again changing the pad's ID - this time using padId = padId + Math.floor(padId / 7 + 2) * 5 + X, with X being some number between 0-5, depending on the initial IDs fit into the Lydian scale (a fancy modulo operation is used to ensure heptatonic compatibility). Don't forget your order of operations!
Finally, that new ID (-26 in this case) is used to calculate the frequency relative to (or, semitones from) A440. The math is frequency = +(440 * Math.pow(Math.pow(2, 1 / 12), padId)). This gives us a frequency of 97.9989 Hz for the first pad - or, the note G2. Here are some notes from Michigan Technological University.
Generation Logging
As Classic Mode is based on the rules of Conway's Game of Life, the grid uses toroidal wrapping: moving patterns that leave one edge continue from the opposite edge. It's still possible to run into still lifes, which are unchanging clusters of notes. As the intention of this mode is to have growing, blooming, and ever-changing chords, the idea of the music devolving into the same notes repeating infinitely is... not ideal, at least for this application.
That's why there is constant Generation Logging happening in the background. With every generation comes a list of every active pad. If the current list is identical to the previous list (i.e. still life is happening), the game will reset itself. Technically this could happen in Random Mode as well. If it does happen, you will have witnessed the greatest statistical improbability of all time.
Reverb
When the synthesizer starts, the impulse response's .wav file is retrieved and turned into an array buffer. If that file is available, notes are routed through a convolver node before reaching the main gain. If it is not available, the synthesizer falls back to a dry signal so the instrument can still play.
You can think of the reverb/gain nodes as guitar pedals. The reverb can be patched in when the impulse response loads, but the signal path still works without it.
Back