$30
Programming Project: The Frequencies of Musical Notes
CPSC-298-6 Programming in C++
Introduction
Audio programming, a key subfield in computer game development, relies on C++
for performance and for the language's facilities for low-level interaction with
hardware. Signal processing applications, such as those for acoustic signal
processing and radio frequency, or R/F, signal processing, often depend on C++ for
the same reasons.
In this assignment, you'll investigate the frequencies of musical notes and their
mathematical relation.
In particular, you'll implement the formula for computing the frequencies of musical
notes given a reference frequency.
fk,ν = fR × 2(ν)+ k/12
where
fR is the Reference Frequency, in this case 16.35 Hz (cycles per second), the frequency of the note C
in octave 0 (denoted by C0).
ν is the octave number (which ranges from 0 to 9 for our purposes)
k is the half-step (or semitone number) within the octave, it has values between 0 and 11 inclusive.
fk,ν is the frequency of the note in octave ν whose half-step within the octave is k. 1
The reference frequency typically used is 440Hz, corresponding to note A4, which is
the A note in (piano) octave 4. The equation when this value is used for fR is a bit
more complex and less intuitive; we'll stick with C0 and use 16.35 Hz as our
reference frequency.
The next section provides you with some background on the assignment. You can
skip this section and go directly to the Assignment section if you'd like. However,
you might find the background information helpful and possibly even interesting.
Background
You may be more familiar with music than signal processing; however, both have
their foundations in mathematics.
1 More technically, it is frequency of equal-tempered interval k in octave ν. The octaves are named in
the order of their appearance on a standard 88-key piano keyboard, beginning with octave 0 (or the
"zero'th octave").
2
The musical notes you're familiar with have very specific frequencies that are
mathematically related to each other. (Incidentally, we perceive frequency as pitch;
the higher the frequency the higher the pitch.)
For a piano or other string instrument, frequency is the rate of oscillation (or. more
accurately, vibration) of the strings used to produce the sound. Frequency is
measured in cycles per second, or cycles/second. The unit of frequency is called the
Hertz, and is abbreviated Hz. Its dimensions are inverse seconds because cycles (as
in cycles per second) is just a count - we call it a "pure" number; it has no
dimensions, so we're left with seconds in the denominator or s-1 (inverse seconds)
for Hz.
The notes whose familiar syllables are "do", "re", "me", "fa", "so", "la", and "ti" have
letter designations, C, D, E, F G, A, and B, respectively, as show in the diatonic scale
below. (You don't need to know this to do the assignment, but you may find it
interesting.)
The Diatonic Scale
You may recognize these notes on the piano keyboard as shown in the figure below.
3
A Portion of the Piano Keyboard
But piano keyboards have a lot more keys that just what is shown above; what's
going on?
The notes sort of repeat themselves. They're arranged in octaves where the notes in
the next higher octave have twice the frequency.
Let's look at an example, C0, the note with the lowest frequency, a meager 16.35
cycles per second (16.35 Hz). C0 is in the zero'th octave. The next octave is 1 and the
C note in that octave, denoted as C1, has a frequency of 32.70 Hz, twice as much. The
C in octave 2, C2, has a frequency twice that of C1, or 65.41 (there's a little rounding
error). Each time you go up an octave, the frequency doubles.
C0 16.35 Hz (Too low for the piano)
C1 32.70 Hz
C2 65.41 Hz
C3 130.81 Hz
C4 261.626 Hz ("Middle C")
C5 523.251 Hz
C6 1046.502 Hz
C7 2093.005 Hz
C8 4186.009 Hz (highest note of piano)
C9 8372.018 Hz
The same holds true for the other notes too; take A for example.
A in octave 0, or A0, has a frequency of 27.5 Hz; it's the lowest note on the piano.
4
A0 27.5 Hz (Lowest note of piano)
A1 55 Hz
A2 110 Hz
A3 220 Hz
A4 440 Hz (Tuning Reference Note)
A5 880 Hz
A6 1760 Hz
A7 3520 Hz
A8 7040 Hz
A9 14080 Hz
So, for any note with a frequency, f, its equivalent in the next higher octave has a
frequency of 2*f. And the frequency of its equivalent two octaves up is 2*2*f. Three
octaves up, it's 2*2*2*f. The frequency of its equivalent one octave down is f/2. Two
octaves down, it's f/(2*2) or f/4.
But what about the other notes, the ones on the black keys, C# (C Sharp) and D♭ (D
Flat, sometime written Db). The sharp symbol in C# means the note "is a little higher
in pitch (or frequency)" than C and the flat symbol in D♭ means "a little power in
pitch (or frequency) than D." C# (C Sharp) and D♭ (D Flat) have the same frequency -
they're just different perspectives of the same thing.
The frequency of C# in the zero'th octave, C#0, is 17.32 Hz, just a little higher than C0
at 16.35. (And this is the frequency of D♭
0 , too.)
Let's take a look at the frequencies of all the notes in the zero'th octave.
5
Frequencies of Notes in the Zero'th Octave in Hertz
You learned earlier that to go from C0 (C in the zero'th octave) to C1 (C in the first
octave), you just double the frequency. (C0 has a frequency of 16.35 Hz and C1 has a
frequency of 32.70 Hz - exactly double.) But what about going from C0 to C#0, the
next note right after C0?
That's a little harder. Each transition (from C0 to C#0 , for instance) is called a half
step. (Transitioning from one row to the next row in the table above is one half step;
to go from the top to the bottom is 11 half steps.) It turns out the formula is:
fn = fR * (a)n
where
* indicates multiplication, as in a C++ program.
fR = the frequency of one fixed note, the reference frequency, which must be defined.
n = the number of half steps away from the fixed note you are. If you are at a higher
note, n is positive. If you are on a lower note, n is negative.
fn = the frequency of the note n half steps away.
a = (2)1/12 = the twelfth root of 2 = the number which when multiplied by itself 12
times equals 2 = 1.059463094359...
So, let's see if this works for single half step from C0 to C#0.
In this case:
6
fR is the frequency of C0, which is 16.35 Hz
n is the number of half steps from C0 to C#0, which is 1.
a is approximately 1.059463094359
fn is just f1 (one step from 0), the frequency of C#0, the value we want to compute,
which from our table should be 17.32 Hz.
fn = fR * (a)n
f1 = 16.35 Hz * (1.059463094359)1
f1 = 16.35 Hz * 1.059463094359
f1 = 17.32 Hz (approximately)
17.32 Hz is exactly what we were looking for.
Now, let's see if this works if we go up a full octave. Recall that there are 11 half
steps on the zero'th octave (count them if you'd like to double check this). So, to get
to the next octave we just need to go one more, or 12 half steps. The table below
shows the frequencies of the notes in octave 0 and the frequency of the first note in
octave 1, C0 , which is what we're looking for.
Frequencies of Notes in the Zero'th Octave in Hertz as well as C1, the C of the 1st
Octave
7
For this case:
fR is the frequency of C0, which is 16.35 Hz
n is the number of half steps from C0 to C1, which is 12.
a is approximately 1.059463094359
fn is just f12 (twelve step from 0), the frequency of C#0, the value we want to
compute, which from our table should be 17.32 Hz.
f12 = fR * (a)12
But a is (2)1/12 = the twelfth root of 2, and ((2)1/12)12 is (2)12/12, which is (2)1 or 2.
f12 = f0 * 2
f12 = (16.35 Hz) * 2
f12 = 32.70 Hz
The frequency of C1 is 32.70, exactly double that of C0, exactly what it should be.
Let's simplify our formula to make "jumping to the next octave easier. We'll
introduce a new variable, nu, , which is the octave number. Instead of n for the
number of half steps in total, we'll use k, which is the number of half steps within an
octave, and so has values from 0 to 11, inclusive.
fk,ν = fR × 2(ν)+ k/12
fR is the Reference Frequency, in this case 16.35 Hz (cycles per second), the Frequency of the note C
in octave 0, the "zero'th octave, (denoted by C0).
ν is the octave number (which ranges from 0 to 9 for our purposes)
k is the half-step (or semitone number) within the octave, it has values between 0 and 11 inclusive.
fk,ν is the frequency of the note in octave ν whose half-step within the octave is k. 2
Our original formula,
fk,ν = fR × 2(ν)+ k/12
can be rewritten as (we converted exponent addition to multiplication)
fk,ν = fR × 2(ν) × 2k/12
Let's compute the frequency of D3, the D note in octave 3, whose frequency is
146.83. In this case ν is 3 (D3 is in octave 3), k is 2 (D3 is two half tones from the start
of the octave).
2 More technically, it is frequency of equal-tempered interval k in octave ν. The octaves are named in
the order of their appearance on a standard 88-key piano keyboard, beginning with octave 0 (or the
"zero'th octave").
8
Annotated Excerpt of Table of Notes and Frequencies
fk,ν = fR × 2(ν) × 2k/12
fk,ν = fR × 2(3) × 22/12
fk,ν = (16.35 Hz) × 2(3) × 22/12
fk,ν = (16.35 Hz) × 2*2*2 × 22/12
fk,ν = (16.35 Hz) × 8 × 22/12
Remember that 21/12 is the twelfth root of 2 which is approximately
1.059463094359.
fk,ν = (16.35 Hz) × 8 × (1.059463094359)2
fk,ν = (16.35 Hz) × 8 × (1.059463094359) × (1.059463094359)
fk,ν = 146.818 Hz which is very close to 146.83 Hz.
Rather than doing this by hand, let's write a C++ program to compute fk,ν.
You haven't studied loops or functions in C++ yet, so writing the program isn't
straightforward.
Assignment
Use the formula below to compute the frequencies of the following notes: , C#0, D0,
D3 , C4, D#7, and C8.
fk,ν = fR × 2(ν)+ k/12
fR is the Reference Frequency, in this case 16.35 Hz (cycles per second), the Frequency of the note C
in octave 0, the "zero'th octave, (denoted by C0).
ν is the octave number (which ranges from 0 to 9 for our purposes)
k is the half-step (or semitone number) within the octave, it has values between 0 and 11 inclusive.
fk,ν is the frequency of the note in octave ν whose half-step within the octave is k. 3
3 More technically, it is the frequency of the equal-tempered interval k in octave ν. The octaves are
named in the order of their appearance on a standard 88-key piano keyboard, beginning with octave
0 (or the "zero'th octave").
9
It's easier to code the formula if you place it in this form:
fk,ν = fR × 2(ν) × 2k/12
Or, even better, if you put it in this form:
fk,ν = fR × 2(ν) × (21/12)k
Assume that the twelfth root of 2 (21/12)is 1.059463094359.
Also assume the reference frequency, fR , is that of note C0 and is exactly 16.35 Hz.
For each calculation, display the name of the note (e.g. "C#0", "D0", "C4", "D#7" and
"C8"), the value of nu (ν, the octave number), and the value of k (the half-tone or
interval relative to the start of the octave) and the computed frequency, fk,ν.
At the start of your program, display the reference frequency, fR, 16.35 Hz.
Use a double data type to hold the value of the twelfth root of 2, 1.059463094359
(e.g. double dTwelfthRootOfTwo).
Remember if you need to square 1.059463094359, you can just multiply it by itself:
(1.059463094359 * 1.059463094359). Cubing it is just as easy:
(1.059463094359 * 1.059463094359 * 1.059463094359)
Use an integer data type to store values such as 2, 22, 23 (e.g. long
iTwoRaisedToPowerNu); of course, these values are just 2, 4, and 8.
The table below lists the notes, their octave number and the half-tone offset number
from the start of the octave. It also lists their frequency (and wavelength) for you to
check your answers.
Musical Note ν
Octave Number
k
Half-tone offset
Frequency (Hz) Wavelength (cm)
C0
Reference
0 0 16.35 Hz 2109.89 cm
C#0 0 1 17.32 Hz 1991.47 cm
D0 0 2 18.35 Hz 1879.69 cm
C4
(Middle C)
4 0 261.63 Hz 131.87 cm
D#7 7 3 2489.02 Hz 13.86 cm
C8
(highest piano
note)
8 0 4186.01 Hz 8.24 cm
Incidentally, what is 2 raised to the zero'th power (20)? 1 of course.
For each frequency you compute, fk,ν, you'll also compute and display the
wavelength using the following equation.
10
Wk,v = c/ fk,ν
where
Wk,v is the wavelength, c is the speed of sound in air (at room temperature), and
fk,ν is the frequency.
The speed of sound in air at room temperature is (roughly) 345 meters per second
(345 m/s). Near the start of your program, display the value of the speed of sound.
Also, you'll display the value for the wavelength in centimeters per second (cm/s).
Remember that there are 100 centimeters in a meter, so use a conversion factor
(100 cm/1 m).
The output of your program will appear similar to that shown in the following
screen capture.
Notice that the computed frequency and wavelength values don't match the
expected values exactly (they're very close though). Why is that?
The next section provides a few references in case you like to explore further. After
this, you'll find a full table of the notes with their frequencies and wavelengths.
References
Loy, Gareth. Musimathics, Volume 1 (p. 41). MIT Press, 2011.
Frequencies of Musical Notes, A4 = 440 Hz (mtu.edu)
https://pages.mtu.edu/~suits/notefreqs.html
Formula for frequency table (mtu.edu)
https://pages.mtu.edu/~suits/NoteFreqCalcs.html
Table of Musical Notes and Their Frequencies and Wavelengths
(liutaiomottola.com)
11
https://www.liutaiomottola.com/formulae/freqtab.htm
Appendix: Table of Musical Notes and their Frequencies
12
13
14
15