Code
from pydub.generators import Sine
import simpleaudio as sa
Alex Chisholm
May 18, 2025
A major scale is foundational to Western music and is one of the first concepts taught to music students. Let’s start this blog by having Python play a C scale using Pydub and Simpleaudio.
A musical note can be represented in several ways. On sheet music, it appears on a staff, which uses a specific clef such as the treble clef to indicate pitch. The same note can also be written using a letter name (like C, D, or E) combined with a number to indicate its octave, with lower numbers representing deeper, lower-pitched sounds. Additionally, each note corresponds to a specific frequency, commonly measured in Hertz (Hz).
We can overlay these visually.
Listen to these eight notes that range from C1 (32.70 Hz) to C8 (4186.01 Hz):
An 88-key piano ranges from A0 to C8 with the following frequencies. Notice that higher octaves have higher frequencies and that each octave jump doubles the frequency.
Note | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|---|
C | - | 32.70 | 65.41 | 130.81 | 261.63 | 523.25 | 1046.50 | 2093.00 | 4186.01 |
C#/Db | - | 34.65 | 69.30 | 138.59 | 277.18 | 554.37 | 1108.73 | 2217.46 | - |
D | - | 36.71 | 73.42 | 146.83 | 293.66 | 587.33 | 1174.66 | 2349.32 | - |
D#/Eb | - | 38.89 | 77.78 | 155.56 | 311.13 | 622.25 | 1244.51 | 2489.02 | - |
E | - | 41.20 | 82.41 | 164.81 | 329.63 | 659.25 | 1318.51 | 2637.02 | - |
F | - | 43.65 | 87.31 | 174.61 | 349.23 | 698.46 | 1396.91 | 2793.83 | - |
F#/Gb | - | 46.25 | 92.50 | 185.00 | 369.99 | 739.99 | 1479.98 | 2959.96 | - |
G | - | 49.00 | 98.00 | 196.00 | 392.00 | 783.99 | 1567.98 | 3135.96 | - |
G#/Ab | - | 51.91 | 103.83 | 207.65 | 415.30 | 830.61 | 1661.22 | 3322.44 | - |
A | 27.50 | 55.00 | 110.00 | 220.00 | 440.00 | 880.00 | 1760.00 | 3520.00 | - |
A#/Bb | 29.14 | 58.27 | 116.54 | 233.08 | 466.16 | 932.33 | 1864.66 | 3729.31 | - |
B | 30.87 | 61.74 | 123.47 | 246.94 | 493.88 | 987.77 | 1975.53 | 3951.07 | - |
The note C4 (261.63 Hz) is known as Middle C. The note A4 (440 Hz) is often the Tuning A used by orchestras before rehearsals and concerts to have musicians play in tune together.
Now let’s see how Python can take the role of musician. We’ll begin by importing our helper packages.
Next we’ll create a dictionary with the notes of a c scale beginning with middle C.
Next we’ll define in milliseconds how quickly we want the notes in the scale to be played by setting note_duration
. Then we’ll loop through each of the values in our dictionary to build the scale, appending the tones to an empty list named scale
. Finally, we’ll convert into a continuous audio clip by merging all the tones into a single Audio Segment with sum()
.
The final c_scale
PyDub Audio Segment contains a bunch of useful information.
print("Duration (ms):", len(c_scale)) # Total duration in milliseconds
print("Frame rate (Hz):", c_scale.frame_rate) # Sample rate
print("Channels:", c_scale.channels) # Mono (1) or stereo (2)
print("Sample width (bytes):", c_scale.sample_width) # Usually 2 (16-bit)
print("Frame width (bytes):", c_scale.frame_width) # channels * sample_width
print("Number of frames:", c_scale.frame_count()) # Total number of frames
print("Max amplitude:", c_scale.max) # Maximum absolute amplitude value
print("dBFS (volume level):", c_scale.dBFS) # Average decibels relative to full scale
Duration (ms): 3200
Frame rate (Hz): 44100
Channels: 1
Sample width (bytes): 2
Frame width (bytes): 2
Number of frames: 141120.0
Max amplitude: 32767
dBFS (volume level): -3.0108529080336788
Using Simpleaudio
we can play the scale.
Finally, if we want, we can save the Audio Segment.
Not bad for a few lines of code!