Notes, chords and tunes
A note, a chord, and two ways of writing a tune: as a line of text, and as ordinary lines of code.
Notes
playNote("C4") // middle C, for half a second
playNote("C4", 2) // for two seconds
playNote("C4", 2, 0.3) // and quiet: loudness goes from 0 to 1
playNote(["C4", "E4", "G4"]) // three notes at once: a chord
playNote("C4", { length: 2, volume: 0.3, pan: -1, after: 0.5 }) // the same things by nameA note is a letter and a number: "C4" is middle C, "A4" is the A above it, "F#3" is F sharp and "Bb5" is B flat. It can also be a number, where 60 is middle C and each whole number is one key of a piano (61 is C sharp, 72 is the C above). A number with a fraction is between two keys. noteNumber("A4") gives 69 (note_number in Python).
pan is where the note is: -1 is left and 1 is right.
Chords by name
A chord is a note and a kind: "C" and "m7" make "Cm7". Wherever a note is played, a chord's name plays all its notes.
playNote("Cm7") // C minor seventh
playNotes("Am F C G", 0.5) // four chords, half a second eachThe kinds are major (or maj), minor (or m), dim, aug, sus2, sus4, 5, 6, m6, 7, maj7, m7, dim7, m7b5, add9, 9, maj9, m9 and octave. Every sound, synth and setting has the notes of each.
A letter followed by a number is always a note, so "C7" is the note C in octave 7. For the seventh chord write "Cdom7". For a chord in another octave put the octave after the letter: "C3m7".
Lengths
Wherever a length is wanted there are two ways to say it, and they are never mixed up:
- A number is seconds.
playNote("C4", 0.5)lasts half a second, whatever the tempo. - A name is a note length, measured against the tempo:
playNote("C4", "quarter"). At a tempo of 120 a quarter note is half a second; at 60 it is a whole one.
| Name | Also written | How long |
|---|---|---|
"whole" | "1/1", "w" | 4 beats |
"half" | "1/2", "h" | 2 beats |
"quarter" | "1/4", "q" | 1 beat |
"eighth" | "1/8", "e" | half a beat |
"sixteenth" | "1/16", "s" | a quarter of a beat |
A dot makes one half as long again ("quarter.", "q."), and a triplet fits three where two were ("eighth triplet", "e3").
setTempo(140) // beats in a minute. 120 until you say
playNote("C4", "quarter")
playNote("E4", "quarter.", { after: "half" })beats(3) is how many seconds three beats last.
A tune as text
let tune = null
function onMouseDown() {
if (tune) tune.stop()
tune = playNotes("C4 E4 G4 - C5:2 G4+B4+D5 Am", 0.25, { repeat: true })
}playNotes plays a tune a step at a time. The first thing is the notes, as text with spaces between:
| In the text | What it is |
|---|---|
C4 | A note, one step long |
- | A rest |
C5:2 | A note two steps long |
C4:q, C4:h, C4:e, C4:s, C4:w | A note with a length of its own: a quarter, a half, an eighth, a sixteenth, a whole |
G4+B4+D5 | A chord, joined with + |
Am | A chord by name |
The second thing is how long a step is: a number is seconds, a name is a note length (playNotes("C4 E4 G4", "eighth")), and with nothing said it is an eighth.
The notes can also be a list, where a rest is null (None in Python) and a list inside is a chord:
playNotes(["C4", null, ["C4", "E4"]], 0.25)| Option | What it does |
|---|---|
repeat | true plays it round and round; a number, that many times |
volume | How loud, from 0 to 1 |
hold | How much of its step a note sounds for: 0.9 unless you say |
after, at, beat | When it starts |
playNotes hands back the tune, so you can stop it: tune.stop().
A tune whose step is a name, or is left out, is in beats: it changes speed when the tempo changes, even while it repeats. A tune whose step is seconds does not.
The sound engine keeps the time, not your program. A tune stays even when a frame is slow, and several tunes started together stay together.
A tune written as text plays each note plain. A slide into a note, a bend or a vibrato is for one note at a time, in play, start and playNote: see Bending a note.
A tune, one note a line
playNote plays a note now. note plays the next note of a tune: each one begins where the one before it ended, so a tune is written as ordinary lines of code, with loops and ifs, and no arithmetic.
function onMouseDown() {
setTempo(100)
startLines()
note("E4", "quarter")
note("G4", "quarter")
rest("quarter")
note("C5", "half")
chord("Cm", "whole")
for (const name of ["C4", "D4", "E4"]) note(name, "eighth")
}The same tune as text, for comparison: playNotes("E4:q G4:q -:q C5:h Cm:w C4:e D4:e E4:e").
In a line, a length is a name, or a number of beats (note("C4", 2) is a half note). With nothing said it is a quarter. Change a length and everything after it moves along.
Every synth has a line of its own
note, chord and rest write on the synth that playNote uses. Every synth you make has its own line: lead.note("C4", "eighth").
Lines written in the same go begin together, however much code is between them. Write the whole melody, then the whole bass, and they start on the same instant:
const lead = makeSynth("lead")
const bass = makeSynth("bass")
function onMouseDown() {
startLines()
for (const n of ["E4", "G4", "C5", "G4"]) lead.note(n, "quarter")
bass.note("C2", "half")
bass.note("G2", "half")
}A section that goes round
A for loop writes a section several times. loopNotes has it go round for ever, kept in time by the sound engine, and it follows the tempo as it plays. It hands back the loop, which has stop().
const kick = makeSynth("kick")
const snare = makeSynth("snare")
let drums = null
function onMouseDown() {
if (drums) {
drums.stop()
drums = null
return
}
drums = loopNotes(() => {
kick.note("C3", "quarter")
snare.note("A3", "quarter")
})
}In JavaScript the section is a function. In Python it is a with block. To go round four times and then carry on, say how many: loopNotes(4, () => { … }), or with loop_notes(4):.
Starting over
A line carries on from where it ended. If it ended a while ago, the next note begins now. startLines() begins every line again from now, and lead.startLine() begins one (start_lines, start_line). A tune that is played by a click starts with startLines(), so that a second click begins it again and does not add to the end of the first.
startLines({ after: "whole" }) // every line begins a bar from nowWhich way to write a tune
- As text when the tune is a pattern: a drum beat, a bass line, a melody you can see at a glance. It is short, and it repeats with one word.
- As code when the tune is made by the program: a melody from a list, a scale from a loop, a different ending when the player wins.
Both keep exact time, and they can play together.
Related
- Synths and their settings: play a tune on an instrument of your own
- Chip sounds and arpeggios: a chord from one voice
- Sheet music (notation): the same tune written out on a staff, each note lit as it plays
- Function index