Skip to content

← Creating

How Does a Computer Play a Tune?

Topic 32 · Grades 6–8 · Notes as numbers

Blocks with variables, from Grade 7 (and sound as samples, Grade 7); the Python parts from Grade 8 (lists and functions).

What this builds on from class
In this unit 8 sections
  1. Try it
  2. How it works
  3. Program it
  4. What your program shows
  5. Going further still
  6. Challenges
  7. Questions
  8. Where to go next

A phone rings with a little tune. A toy keyboard plays “Happy Birthday” when you press a button. A computer has no strings to pluck and no drum to hit, only numbers. So how does it play a tune?

The answer is short. A note is a number: how many times a second something vibrates. A tune is a list of those numbers. And the most surprising part: to play the same tune higher or lower, the computer multiplies every number by the same amount.

Try it now. Each key is a note of the sargam, Sa Re Ga Ma Pa Dha Ni and the next Sa, with its number under it. Tap a key to hear it.

Try it

Play the notes

Tap the keys. The picture above them shows the note’s vibration, drawn over Sa’s. Change Sa, then press Play the tune again.

Sa: 6 waves · Pa: 9 waves025 thousandths of a secondSaसा240HzReरे270HzGaग300HzMaम320HzPaप360HzDhaध400HzNiनि450HzSa′सां480Hz
Sa:
Note
Pa
Vibrations a second
360
Fraction of Sa
3/2 = 1.5

Pa: 360 vibrations a second, 3/2 of Sa’s 240. Every 2 waves of Sa, Pa has made exactly 3, and the two waves start together again (the dashed lines). Notes whose waves line up often sound smooth together.

Sa vibrates 240 times a second. The next Sa up, Sa′, sounds like the same note, only higher. How many times a second do you think Sa′ vibrates?

Pick an answer to see why.

You need: for the blocks, variables from Grade 7 (and how sound is stored as samples, Grade 7). For the Python, lists and functions, from Grade 8.

Try it

Use the keys above, with Sa at 240.

  • a.Read the number on each key. Which keys have numbers that are exactly half or twice another key’s?
  • b.Tap Pa. In the picture, count Sa’s waves (gray) and Pa’s waves (blue) between two dashed lines. What do you notice?
  • c.Now tap Ga, Ma, Dha, Re and Ni in turn. For which notes do the dashed lines come close together, and for which are there none at all?
  • d.Press Play the tune with Sa at 240, then with Sa at 360 and 200. Is it the same tune?

How it works

A note is a number

Pluck a string of a guitar or a sarangi, and it moves back and forth, very fast. Each time it moves, it pushes the air, and the pushes reach your ear. How many times it moves back and forth each second is the note’s pitch. Few vibrations a second make a low note; many make a high one. Vibrations a second are counted in hertz (Hz): a note of 240 Hz vibrates 240 times every second.

Two numbers matter most:

  • Twice the number sounds like the same note, higher. Sa at 240 Hz and Sa′ at 480 Hz sound so alike that they share a name. The step from a note to the one with twice its number is an octave.
  • Pa is 3/2 of Sa. Whatever number a singer picks for Sa, Pa is one and a half times it.

A flute plays Sa at 300 Hz. What is its Pa?

Pick an answer to see why.

The scale’s fractions

The other notes are fractions of Sa too. In one common way of tuning, they are these:

Note Sa Re Ga Ma Pa Dha Ni Sa′
Fraction of Sa 1 9/8 5/4 4/3 3/2 5/3 15/8 2
With Sa at 240 Hz 240 270 300 320 360 400 450 480

Musicians don’t all tune Re, Ga, Dha and Ni exactly alike, and a raag may raise or lower some of them. But Sa and Pa never move: in Hindustani music they are called the achal notes, the ones that don’t move. Once Sa is chosen, Pa is fixed at 3/2 of it, and Sa′ at twice it.

The dashed lines in the widget show why these fractions are special. When Pa is 3/2 of Sa, every 2 waves of Sa take exactly as long as 3 waves of Pa, so the two waves keep lining up. Notes whose waves line up often, like Sa and Pa, sound smooth when they are played together.

From numbers to sound

You know from Grade 7 Grade 7: Sound as samples that a computer keeps a sound as a list of samples: how far the speaker should be pushed out or pulled in, thousands of times a second. To play a note of 240 Hz, the computer works out samples that rise and fall 240 times a second, and sends them to the speaker. The speaker moves the air back and forth 240 times a second, and you hear Sa.

So a tune is numbers all the way down: a list of notes, each a number of hertz, each turned into thousands of samples.

The computer plays a tune with Sa at 240 Hz. You want the same tune, an octave higher. What does it do to every note’s number?

Pick an answer to see why.

Program it

With blocks

Here is the start of a well-known tune, Twinkle, Twinkle, Little Star, as a block program. Each play block plays one note: its hertz and how many seconds it lasts. The pairs of notes are repeats.

Try it

Twinkle as numbers

Press Run and listen (turn your sound on). Each note appears on the lines of Sa, Re, Ga as it plays, as high as its pitch. Then change one number and Run again: change the first 240 to 250, say. Does the tune still sound right?

SaReGaMaPaDhaNiSa′Re′Ga′Ma′Pa′NiDha
Notes played
0
Last note
–
Its name (Sa = 240 Hz)
–

What the program says and asks appears here.

Press Run to start the program, or Step to do one block at a time.

Loading the blocks…

Every number in that program was worked out from Sa = 240. So the next program doesn’t write the numbers at all. It keeps Sa in a variable, sa, and works out each note from it: Pa is sa × 3 ÷ 2, Dha is sa × 5 ÷ 3, and so on.

Try it

The same tune in any key

Press Run. Then change set sa to 240 to 360, and Run again. Try 200 and 300. Watch the bars: the tune keeps its shape, and the whole thing moves up or down.

SaReGaMaPaDhaNiSa′Re′Ga′Ma′Pa′NiDha
Notes played
0
Last note
–
Its name (Sa = 240 Hz)
–

What the program says and asks appears here.

sa – no value

Press Run to start the program, or Step to do one block at a time.

Loading the blocks…

In Python (from Grade 8)

Now the samples themselves. from sound import play gives you play(samples, rate): a list of numbers from −1 to 1, rate of them a second, played by the page. (sound is this page’s own module; on your own computer you would need a sound library instead.) Press Run, then Play under the output. Nothing plays until you press it.

Step 1: one note

A smooth vibration that goes up and down evenly is a sine wave. math.sin gives it: as its number grows by 2π (about 6.28), it goes up, down and back to the middle once. So math.sin(2 * math.pi * hz * t) goes round hz times every second of t. The program makes one sample every 1/8,000 of a second, and lets each note fade away, like a plucked string.

import mathfrom sound import play RATE = 8000                    # samples a second def note(hz, seconds):    samples = []    n = int(RATE * seconds)    for i in range(n):        t = i / RATE                           # this sample's time, in seconds        fade = 1 - i / n                       # dies away, like a plucked string        samples.append(0.5 * fade * math.sin(2 * math.pi * hz * t))    return samples def waves(samples):    # count how often the wave crosses the middle going up    count = 0    for i in range(1, len(samples)):        if samples[i - 1] <= 0 and samples[i] > 0:            count = count + 1    return count sa = note(240, 1)print(len(sa), 'samples')print([round(x, 2) for x in sa[:12]])print(waves(sa), 'waves in one second')print(waves(note(480, 1)), 'waves in one second, for Sa an octave up')play(sa, RATE)play(note(480, 1), RATE)

Output

8000 samples[0.0, 0.09, 0.18, 0.27, 0.34, 0.4, 0.45, 0.48, 0.5, 0.5, 0.47, 0.44]240 waves in one second480 waves in one second, for Sa an octave up

One second of Sa is 8,000 numbers, and the wave in them goes up and down exactly 240 times. Play both sounds: the same note, the second one higher. (On a phone’s small speaker low notes are quiet; headphones help.)

Step 2: a tune is a list

Now the tune from the blocks, as two lists: each note’s hertz, and how many beats it lasts. A beat here is 0.3 seconds.

import mathfrom sound import play RATE = 8000 def note(hz, seconds):    samples = []    n = int(RATE * seconds)    for i in range(n):        t = i / RATE        fade = 1 - i / n        samples.append(0.5 * fade * math.sin(2 * math.pi * hz * t))    return samples # Twinkle, Twinkle, Little Star: Sa Sa Pa Pa Dha Dha Pa, Ma Ma Ga Ga Re Re Satune = [240, 240, 360, 360, 400, 400, 360, 320, 320, 300, 300, 270, 270, 240]beats = [1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2] def song(tune, beats):    samples = []    for k in range(len(tune)):        samples = samples + note(tune[k], 0.3 * beats[k])    return samples twinkle = song(tune, beats)print(len(twinkle), 'samples:', len(twinkle) / RATE, 'seconds')play(twinkle, RATE)

Output

38400 samples: 4.8 seconds

samples + note(...) joins two lists into one, so the notes come one after another. A tune of 14 numbers became 38,400.

Step 3: a new key, two ways

What happens if you change every number in the tune the same way? The program makes the tune again in two ways: every number times 1.5, and every number plus 120. Both start on 360. Then it looks at each step of the tune: each note as a fraction of the note before it.

import mathfrom sound import play RATE = 8000 def note(hz, seconds):    samples = []    n = int(RATE * seconds)    for i in range(n):        t = i / RATE        fade = 1 - i / n        samples.append(0.5 * fade * math.sin(2 * math.pi * hz * t))    return samples def song(tune, beats):    samples = []    for k in range(len(tune)):        samples = samples + note(tune[k], 0.3 * beats[k])    return samples def steps(tune):    # each note as a fraction of the note before it    out = []    for k in range(1, len(tune)):        out.append(round(tune[k] / tune[k - 1], 2))    return out tune = [240, 240, 360, 360, 400, 400, 360, 320, 320, 300, 300, 270, 270, 240]beats = [1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2] times = []                       # every number times 1.5plus = []                        # every number plus 120for hz in tune:    times.append(hz * 1.5)    plus.append(hz + 120) print('tune: ', tune[:7])print('× 1.5:', times[:7])print('+ 120:', plus[:7])print()print('steps of the tune: ', steps(tune)[:6])print('steps of × 1.5:    ', steps(times)[:6])print('steps of + 120:    ', steps(plus)[:6]) play(song(tune, beats), RATE)play(song(times, beats), RATE)play(song(plus, beats), RATE)

Output

tune:  [240, 240, 360, 360, 400, 400, 360]× 1.5: [360.0, 360.0, 540.0, 540.0, 600.0, 600.0, 540.0]+ 120: [360, 360, 480, 480, 520, 520, 480] steps of the tune:  [1.0, 1.5, 1.0, 1.11, 1.0, 0.9]steps of × 1.5:     [1.0, 1.5, 1.0, 1.11, 1.0, 0.9]steps of + 120:     [1.0, 1.33, 1.0, 1.08, 1.0, 0.92]

Play all three. The first two are the same tune; the third sounds wrong from its third note.

What your program shows

  • A tune is a list of numbers. Your program turned 14 numbers into 38,400 samples, and the speaker played Twinkle, Twinkle.
  • A note is a number of vibrations a second. The wave your program made for Sa went up and down exactly 240 times in a second, and the one for Sa′ 480 times.
  • Multiplying keeps the tune; adding breaks it. Times 1.5, every step of the tune stayed the same fraction (1.5, 1.11, 0.9…), and it sounded like the same tune in a new key. Plus 120, the big first jump, Sa up to Pa (× 1.5), shrank to × 1.33, which is Sa up to Ma: the tune’s shape changed.

Your ear doesn’t hear the numbers themselves. It hears how each note compares with the others: the fractions. Keep the fractions, and any Sa gives the same tune. That is why a singer can choose a Sa that suits their voice and the harmonium player can follow, and why one line of a program, set sa to 360, moves a whole song.

Two men sitting on a mat by a brick wall in Kathmandu, one playing a pair of tabla drums, the other a harmonium, with a songbook open in front of them
Figure 32.1 Musicians in Kathmandu with tabla and a harmonium, their songbook open on the mat. Before a song starts, a Sa is chosen to suit the voice, the harmonium player takes that key as Sa, and every other note follows from it. Photo: Sigismund von Dobschütz, CC BY-SA 3.0

Going further still

The harmonium’s twelve equal steps

A harmonium can’t follow the fractions exactly. Its keys play twelve equal steps to the octave: each key’s number is the one before it multiplied by the same amount, 2 to the power 1/12 (about 1.0595), so twelve steps make exactly 2. That way it can play in any key, but most of its notes are slightly off the fractions. How far off?

SA = 240STEP = 2 ** (1 / 12)             # one step of the harmonium: 12 of them make 2 # each note: its name, its fraction, and how many harmonium steps above SaNOTES = [['Re', 9 / 8, 2], ['Ga', 5 / 4, 4], ['Ma', 4 / 3, 5],         ['Pa', 3 / 2, 7], ['Dha', 5 / 3, 9], ['Ni', 15 / 8, 11], ["Sa'", 2 / 1, 12]] for note in NOTES:    tuned = SA * note[1]    harmonium = SA * STEP ** note[2]    print(note[0], ': fraction', round(tuned, 1), 'Hz, harmonium', round(harmonium, 1), 'Hz, off by', round(harmonium - tuned, 1))

Output

Re : fraction 270.0 Hz, harmonium 269.4 Hz, off by -0.6Ga : fraction 300.0 Hz, harmonium 302.4 Hz, off by 2.4Ma : fraction 320.0 Hz, harmonium 320.4 Hz, off by 0.4Pa : fraction 360.0 Hz, harmonium 359.6 Hz, off by -0.4Dha : fraction 400.0 Hz, harmonium 403.6 Hz, off by 3.6Ni : fraction 450.0 Hz, harmonium 453.1 Hz, off by 3.1Sa' : fraction 480.0 Hz, harmonium 480.0 Hz, off by 0.0

Pa is less than half a hertz off, but Ga, Dha and Ni are 2 to 4 hertz sharp. Its notes are fixed, and it can’t play the fine shades between them that Indian classical music uses. Partly for that reason, All India Radio kept the harmonium off the air from 1940 to 1971.

Things to try

  • Make note sound richer: add a quieter wave at twice the note’s hertz, 0.25 * math.sin(2 * math.pi * 2 * hz * t). The pitch stays the same (the whole pattern still repeats hz times a second), but the note sounds more like a real instrument.
  • Write octave_up(tune) that gives back a new list with every number doubled, and play the tune an octave up.

Challenges

★ Find Pa (blocks)

Finish the program so that, after it asks for Sa’s hertz, it says Pa’s, and nothing else (for 240 it says 360). Then press Test.

Try it

★ Find Pa

What the program says and asks appears here.

sa – no value
TestShould sayIt said
Sa = 240360
Sa = 200300
Sa = 300450
Sa = 261.6392.4
Sa = 135202.5

Press Run to start the program, or Step to do one block at a time.

Loading the blocks…

Hint
Answer

★★ A new key (Python, from Grade 8)

Write new_key(tune, old_sa, new_sa): it gives back a new list, the tune moved from a Sa of old_sa to a Sa of new_sa, each number rounded to 1 decimal place with round(x, 1).

def new_key(tune, old_sa, new_sa):    # every note moved so that old_sa becomes new_sa    return tune print(new_key([240, 240, 360, 360, 400], 240, 300))

Try it

★★ A new key

  1. Sa 240 to 300 new_key([240, 240, 360, 360, 400], 240, 300) Should give [300, 300, 450, 450, 500] Yours —
  2. Sa 240 to 261.6 new_key([240, 270, 300], 240, 261.6) Should give [261.6, 294.3, 327] Yours —
Tests passed
— / 8
Challenge
★★ solved

Write your new_key in the program above (Edit), then check it.

A test your function gets wrong, anything it prints, and any error appear here.

Hint
Answer

★★★ Name the notes (Python, from Grade 8)

A program listens to someone sing and measures the hertz of each note, a little off, as singing is. Write sargam(tune, sa): for each number, the name of the nearest note of the scale for that Sa, from the table above. Notes in the octave above get a ' after the name, one for each octave up ("Sa'", "Pa''"), and notes below Sa get a . in front, one for each octave down ('.Pa').

def sargam(tune, sa):    # the name of the nearest note for each number    return [] print(sargam([240, 360, 400, 480], 240))

Try it

★★★ Name the notes

  1. Sa 240, in tune sargam([240, 360, 400, 480], 240) Should give ['Sa', 'Pa', 'Dha', 'Sa\''] Yours —
  2. Across three octaves, a little off sargam([121, 179, 240, 476, 721], 240) Should give ['.Sa', '.Pa', 'Sa', 'Sa\'', 'Pa\''] Yours —
Tests passed
— / 8
Challenge
★★★ solved

Write your sargam in the program above (Edit), then check it.

A test your function gets wrong, anything it prints, and any error appear here.

Hint
Another hint
Answer

Questions

What does “a note of 360 Hz” mean?

Pick an answer to see why.

With Sa at 200 Hz, which of these is Sa′, the Sa an octave higher?

Pick an answer to see why.

a.

A tune starts 300, 300, 450, 450. Write the same four notes in the key with Sa at 240 (the tune’s Sa is 300).

Answer
b.

Rina wants her tune higher, so she adds 100 to every note. Explain why it no longer sounds like the same tune, and what she should do instead.

Answer
c.

How many samples does a computer need for a 2-second note, at 8,000 samples a second? And how many times does the wave of a 300 Hz note go up and down in those 2 seconds?

Answer
d.

Why are Sa and Pa called achal, “not moving”, while other notes may be tuned a little differently?

Answer

Where to go next

  • Grade 7, Sound as samples: how a sound becomes a list of numbers, and how many bytes it takes.
  • Grade 8, Photos, Sound and Video: recording clean sound, and music you may use in your own videos.
  • Grade 8, Lists: the lists a tune is kept in.
  • How Does a Computer Make a Sitar-like Note out of Noise? A note that sounds like a plucked string, made from random numbers, and Raag Bhupali on it.
  • How Does a Tuner Hear Which Note You Play? Finding a note’s hertz from a recording, by comparing the sound with itself (Grades 9–12). (Coming soon.)

Found a mistake? Please tell us.