Sound Synthesis Part 3: Pitch

In the previous chapters you learned everything you needed to know about different periodic waveforms.

Now that you know how it sounds, how does it look like? In musical notation it appears like this:
noteA

In scientific pitch notation it’s referred to as A4 because of it’s occurence in the 4th octave. In music an octave is the interval between a pitch and another with half or double it’s frequency.
A4 has a frequency of 440 Hz. If we double the frequency (880), we still hear the note A but one octave up thus called A5. An interval always starts with the note C. According to this, the first note in the 4th octave is C4. In Western countries such an interval is divided into 12 equal parts.
Please note, it’s equal on a logarithmic scale, which means it’s nonlinear. In other words, we can’t simply divide the difference in frequency between 880 and 440 by 12 to get the smallest interval which makes up the semitones.
Instead we use the Twelfth root of two. To get the next semitone after A4, which is A4|B4, we multiply 440 by 2112 and get 466.1637615180899.
In AS3 we can calculate it using the Math.pow() function.

Such a system of tuning is called equal temperament because of the same intervals between adjacent pitches.
Cool! We know that in this system an octave is made up of 12 semitones, what are the notes?

On the 12-tone chromatic scale, it looks like this:
cScaleSharp

# is pronounced ‘sharp’. The 4 refers to the 4th octave in scientific pitch notation.

But wait! The exact same scale could also be written like this:
cScaleFlat

I can’t believe it! Let’s have a closer look by comparing the second semitone in both notations, pretending to be the same tone!
noteComparison

Obviously it isn’t the same note, it’s even on another line! What we see here is a problem caused by the equal temperament. On an equally tempered instrument like a piano or the guitar C and D share the same key/fret! If it’s tuned to another system, these two notes indeed sound slightly different because the pitch of D is a little bit higher.
No problem though since the equal temperament is the base for our tutorial.
We can safely say: C=D, D=E, F=G, G=A, A=B.
For simplicity I’ll refer to those particular notes by it’s ‘sharp’ name only, e.g. C4.

As you just heard again, I was talking about C4 being the first note on the 12-tone chromatic scale in the 4th octave in scientific pitch notation. In this notation the octaves range from -1 to 10, thus C-1 is the lowest while B10 is the highest note.
We can calculate the frequency of both tones using the Twelfth root of two.
A4, which frequency is 440 Hz serves as our base once more. It’s the tenth note on the chromatic scale, which means we’re 3 semitones away from the first note in the fifth octave. Five octaves are missing to reach the tenth octave and a single octave is made up of 12 semitones. 11 semitones are missing to go from C10 to B10.
We’ve enough information to calculate the frequency for B10!

Let’s go into the opposite direction and find out the frequency of C-1.
9 semitones are required to go from A4 to C4 and again 5 octaves to go from C4 to C-1.

If you end up with the following values, everything went well:
C-1=8.175798915643707 Hz
B10=31608.53128039195 Hz

Do you notice anything? Exactly, you’re just remembering something you read in part 1 of this series. The human ear is limited to frequencies up to 20000 Hz, so we won’t ever need a 31609 Hz tone. Likewise 8.18 Hz. It’s actually that deep, that you can hear the individual cycles. I won’t get into detail how this sounds like and let it up to your imagination.
In conclusion, for music we don’t need the full range of notes going  from C-1 to B10.
I’d say we settle with all notes from C1 up to B7!
With the frequencies rounded to 3 decimal places and everything arranged in a nice looking table, we end up with this:

Oct1 Oct2 Oct3 Oct4 Oct5 Oct6 Oct7
 C 32.703 65.406 130.813 261.626 523.251 1046.502 2093.005
C 34.648 69.295 138.591 277.183 554.365 1108.731 2217.461
 D 36.708 73.416 146.832 293.665 587.33 1174.659 2349.318
 D 38.891 77.781 155.563 311.127 622.254 1244.508 2489.016
 E 41.203 82.406 164.814 329.628 659.255 1318.51 2637.02
 F 43.653 87.307 174.614 349.228 698.456 1396.913 2793.826
 F 46.249 92.498 184.997 369.994 739.989 1479.978 2959.955
 G 48.999 97.998 195.998 391.995 783.991 1567.982 3135.963
 G 51.913 103.826 207.652 415.305 830.609 1661.219 3322.438
 A 55.000 110.000 220.000 440.000 880.000 1760.000 3520.000
 A 58.270 116.541 233.082 466.164 932.328 1864.655 3729.31
 B 61.735 123.471 246.942 493.883 987.767 1975.533 3951.066

Now we have a perfect reference to quickly find a particular frequency, e.g. F7 equals 2959.955 Hz. Beautiful! Time to coax some different notes from our tonegenerator!
To do this we could simply copy & paste some frequencies out of the above table but it won’t be very convenient. Actually it would be way more comfortable to refer each indivudual note by it’s name, e.g. A4.
One way to do this would involve manually creating an array, which is merely a table too, and add each individual note and it’s corresponding frequency as an element.

Needless to say that this is a waste of time and a lot of work. Programmers are lazy bums by nature and always seek for better ways to do things. Beside this, if we later decide to expand our range or change the tuning, we would have to redo everything.
Luckily there’s a better way! Let the code do all the dirty work for us!

I’m not kidding, that’s it!
One thing is still missing though – we need a function which will let us search the just generated frequencies table for a particular note and in return gets us the appropriate frequency.
This ain’t magic either

Let’s test if our function works properly.
Try the following code:

and you should see 523.2511306011972 in your debug panel. Bulls-eye!

We’re ready to enhance our tonegenerator.
As usual here’s the complete code first:

If you successfully copy & pasted the code you should hear a melody like this:


It ain’t a random melody though, it’s actually the major pentatonic scale.
In music, a scale is a collection of notes that have been grouped together.
The most well-known among them all is surely the C-major scale.
Written on a staff, it looks like this:
cMajor

As you can see, it’s made up of the notes C – D – E – F – G – A – B. The structure of a scale is always the same and is made up of specific steps between notes. If we were to write down this sequence of steps for the C-major scale, it’s 2 – 2 – 1 – 2 – 2 – 2 – 1.
2 is equal to a Whole, 1 to Half. If we look a the numbers, we can see that it takes 2 steps to go from C to D, so there must be something in-between. Indeed, it’s the note C#!
C – 1 step – C# – 1 step – D | thus 1 step + 1 step = 2 steps
Knowing that a specific scale is always made up of the same steps is important. With this in mind we can easily write down a major scale in another key. Let it be G-major.
Let’s write down all notes ranging from G to G one octave up:
G – 1 step – G# – 1 step – A – 1 step – A# – 1 step – B – 1 step – C – 1 step – C# – 1 step – D – 1 step – D# – 1 step –  E – 1 step – F – 1 step – F# – 1 step – G
Looks like the G-major scale is made up of the notes G – A – B – C – D – E – F#. Awesome!

Reason I’m telling you this, we’re taking advantage of the fact in our code.
Take a closer look at line 26:

Looking familar, huh? There’s just a little difference, it looks like the sequence is written twice. That’s true, we’re playing the major scale over two octaves.
This array is used by the getMeSomeNotes() function. This function initially picks a random root note. If we want the C-major scale, it should pick C-3 for example. According to the sequence in the major array, it then creates a new array containing real note names.
c-3,d-3,e-3,f-3,g-3,a-3,b-3,c-4,d-4,e-4,f-4,g-4,a-4,b-4,c-5,b-4,a-4,g-4,f-4,e-4,d-4,c-4,b-3,a-3,g-3,f-3,e-3,d-3,c-3
The elements in this array can then be used by the findFrequency() function to tell our tonegenerator which frequency it should generate.
To make it sound more interesting, I’ve included sequences for the major, major pentatonic and the harmonic minor scales.
There’s also a new variable called noteLength which, you possibly won’t believe it, determines how long it should play the individual notes. The number is chained to the samplerate.
If you remember, we’re using 44100 samples a second. If we divide noteLength by the samplerate, 11025/44100, we get 0.25, which means a tone lasts for 250ms.

Leave a Reply

Your email address will not be published. Required fields are marked *