Web Audio API - The Oscillator

After a big confession bear on my last post, it's time to make some pretty funny shit on a computer. I attempted to take on a serious and creative approach to this project, but it ended up just sounding so silly I decided to roll with it.

Without further a do, I present to you . . . Shitty Imperial March

So I recently saw Star Wars - Rogue One, on my holiday. How fucking good is that movie! It got me thinking about simulating the Imperial March music with code. I ended up playing around with the concept of using an oscillator to generate the sound using the Web Audio API.

An oscillator is a repeating waveform with a fundamental frequency and peak amplitude and it forms the basis of most popular synthesis techniques today.

Here is the basic setup for the Web Audio Oscillator.

// Setting up the Audio Context and Oscillator
var context = new (window.AudioContext || window.webkitAudioContext)();  
var osc = context.createOscillator();

// The oscillator sound type (sine, square, sawtooth, triangle, custom)
osc.type = 'sine';

// The frequency value, the higher this value the higher the pitch
osc.frequency.value = 0;

// We connect our oscillator to our audio context.
osc.connect(context.destination);

// To hear the sound, we have to start the oscillator
osc.start();  

One of the challenges was how to describe the song to the oscillator. It turns out that each musical note can be defined by a frequency value. I found a great article describing the frequencies of music.

With a bit of googling I found a notated version of Imperial March. I made a simple hash that converted notes to frequencies that could be used for the oscillator.

// Hash table describing notes and frequency
var noteToFrequency = {};  
noteToFrequency['A'] = 220.0;  
noteToFrequency['A#'] = 233.08;  
noteToFrequency['B'] = 246.94;  
noteToFrequency['C'] = 261.63;  
noteToFrequency['C#'] = 277.18;  
noteToFrequency['D'] = 293.66;  
noteToFrequency['D#'] = 311.13;  
noteToFrequency['E'] = 329.63;  
noteToFrequency['F'] = 349.23;  
noteToFrequency['F#'] = 369.99;  
noteToFrequency['G'] = 392.0;  
noteToFrequency['G#'] = 415.30;  
noteToFrequency['NONE'] = 0;  

All that was needed now was a song format that could use a series of timeouts and a recursive function that could run through the instructions. A song was composed of many note objects. Each note object had the following:

{ note: 'G', time: 1, strength: 0.5, giphy: 'url' },

The note would get passed through a function and converted to a frequency. The time would define how long the interval would wait before jumping into the next note object. strength would be called within the time timeout and would allow the note to cut to silence between its time value. giphy was something I added to change the background image at any given note index within the song.

This is what the first part of the Imperial March looks like. Any value with a -x would push the note an octave to its value. A#-5 would be A# five times higher then the base value provided in the notes hash.

{ note: 'G', time: 1, strength: 0.5 },
{ note: 'G', time: 1, strength: 0.5 },
{ note: 'G', time: 1, strength: 0.5 },
{ note: 'D#', time: 1 },
{ note: 'A#-2', time: 0.75 },
{ note: 'G', time: 0.5, strength: 0.5 },
{ note: 'D#', time: 1 },
{ note: 'A#-2', time: 0.75 },
{ note: 'G', time: 0.5, strength: 0.5 },
{ note: 'NONE', time: 1 },

This method actually proved to be a pretty shitty implementation of timing and made it really hard to define the length of each note. If I were to do it differently I would probably set a BPM and some timing rhythm notation. Here is the recursive function that played the song array.

If you missed it above, here is the link to the shitty imperial march

Have you made shitty tracks in the past? What other cool stuff have you done with the Web Audio API?