MUSIC FOR TINY AIRPORTS 2/1 πŸ›«

401 words ~ 2-4 mins

Celebrating the 40 years anniversary of Brian Eno's "Ambient 1: Music for Airports" with an homage written in 256 bytes with the Web Audio API.

Source code

Music for Tiny Airports<svg onload="with(new AudioContext)with(createScriptProcessor(k=8192,t=0,1))connect(destination),onaudioprocess=x=>{for(i=0;i<k;t+=2e-5)x.outputBuffer.getChannelData(0)[i++]='%,IW7:A'.charCodeAt(i%7)*t%.1*(1-t/(Math.tan(i%7)+9)%1)}">

An HTML page, generating hours and hours of music for airports in 256 bytes.

There are three parts to this code.

1. The title and script execution

The title is a text node. The script creating the music is executed using the onload event handler of an SVG element. This is the smallest way to run JavaScript.

Music for Tiny Airports<svg onload="/* ... */">

2. The Audio setup

with(new AudioContext)with(createScriptProcessor(k=8192,t=0,1))connect(destination),onaudioprocess=x=>{/* ... */}

This instantiate a new AudioContext, creates a Script Processor node with k=8192 samples, t=0 input channels and 1 output channel. Finally we connect it to the audio destination and initialize its onaudioprocess event handler to generate a new sound buffer when needed. We will reuse the variable t as an approximation of the time.

3. The music generation

Music for Airport consist of 7 "tape" loops that repeat at different interval.

for(i=0;i<k;t+=2e-5)x.outputBuffer.getChannelData(0)[i++]='%,IW7:A'.charCodeAt(i%7)*t%.1*(1-t/(Math.tan(i%7)+9)%1)

This snippet itself consist of two parts.

3.1. The audio buffer update loop

for(i=0;i<k;t+=2e-5)x.outputBuffer.getChannelData(0)[i++]=/* ... */

This will loop through each of the k=8192 audio samples and assign a new value to channel number 0 of the outputBuffer: Our one and only output channel. That way we will get new sound emitted to the audio destination.

At each iteration t, our approximation of the time, is increased by 2-e5. Normally we should increment t by 1 / sampleRate but this takes more characters and we couldn't fit a title in 256 bytes.

Browser engines use a sampleRate of either 44100Hz or 48000Hz. That means that our approximation plays at a different pitch in different browsers.

3.2. The music generation

The following snippet is the core of this project where i%7 refers to each of the 7 "tape" loops composing "Ambient 1: Music for Airports"

// 1---------------------2----3------4--------------3---
'%,IW7:A'.charCodeAt(i%7)*t%.1*(1-t/(Math.tan(i%7)+9)%1)
  1. the frequency of the notes eb', ab', f', c', ab, f, db'.
  2. creates a sawtooth oscillator at this frequency.
  3. sets the envelope of the notes which starts at full volume and decays linearly over the duration of the notes.
  4. gives the duration of the notes.

Hope you enjoyed this project and write up.


Other recent projects

There are many experiments and projects like MUSIC FOR TINY AIRPORTS 2/1 πŸ›« to discover other here.


Let's talk

Don't be shy; get in touch by mail, twitter, github, linkedin or pouet if you have any questions, feedback, speaking, workshop or performance opportunity.