Scales

Tap the buttons to define the scale. Move your mouse/finger to control the note.

The focus behind this sketch was pitch quantisation. That is, how can we map the continuous spectrum of pitch onto a discrete musical scale? This will become important if we want to use the final program to come up with harmonious melodies.

To make this work, I first came up with a way to index notes. By convention we start with A4 (440hz) to which we assign index 0. Then the semitone up has index 1, the next index 2 and so on. In the same way, the semitone below has index -1 etc. So each musical note is given an integer.

The second part of the puzzle is a continuous bijection between frequencies and notes (including the real numbers between note indices). There are many ways to do this, but the one I chose is based on 12-tone equal temperament (12-TET). You can spend hours in the music theory rabbit hole of why this works, but here's the function ff which maps note index nn to its frequency:

f(n)=4402n/12f(n)=440\cdot2^{n / 12}

Altogether, to quantise a frequency \(x\) to the chromatic scale, apply the inverse of the above f1(x)f^{-1}(x) to get the real-valued unquantised note index. Round it to the nearest note index, then apply f again to get the quantised frequency.

quantise(x)=f(round(f1(x)))quantise(x) = f(round(f^{-1}(x)))

Finally, in order to quantise to a scale I created a Scale class. It takes a tonic (root note of the scale) and a set of notes in one octave relative to that tonic and generates an array of all the notes in the scale across all octaves in the audible range. We can then use binary search to get the nearest note in the scale to a given note!