audio/music
Notes, scales, chords and tunings, Persian dastgah among them.
import audio.music
This package is the arithmetic of music rather than of sound: what a note is, which notes belong together, and what frequency each one wants. It makes no sound itself, which audio/synth does.
Notes are MIDI numbers, so 60 is middle C and 69 is the A tuned to 440. NoteToFreq turns one into a frequency in equal temperament, and JustFreq and PythagoreanRatio are there when equal temperament is not what you want.
Things to know
- Scales and chords come back as vectors of semitone steps, which the caller frees.
NoteNamereturns a string the caller frees.ParseNotereads one back and accepts flats and either case, so it round-trips its own output.- Persian music does not fit twelve semitones. A dastgah is therefore given in cents, not semitone steps: the third of Shur sits at 350 cents, between a minor and a major third, where no piano key is.
NoteToFreqCentsis how you ask for it, andKoronCentsandSoriCentsare the accidentals that get you there. - The seven dastgah here are the frequencies of their tonic rows. A real performance moves between gusheh within a dastgah, which is a matter of melody rather than of tuning.
Constants and variables
A4Note
const A4Note: i32 = 69import audio.music
import math
import mem
func main:
println music.A4Note, music.A4Freq
println music.NoteToFreq(69), music.NoteToFreq(81), music.NoteToFreq(57)
println math.Abs(music.NoteToFreq(60) - 261.6255653005986) < 0.0001
println music.FreqToNote(440.0), music.FreqToNote(261.63), music.FreqToNote(0.0)
println music.Octave(60), music.PitchClass(61), music.PitchClass(-1)
println music.Transpose(60, 7), music.Interval(60, 67)
println music.Cents(440.0, 880.0), music.FreqToCents(440.0, 69)
println music.NoteToFreqCents(69, 1200.0)
each n in [60, 61, 69, 127]:
name := music.NoteName(n)
println name, music.ParseNote(name) == n
mem.Free(name as void*)
end
println music.ParseNote("c4"), music.ParseNote("Db4")
println music.ParseNote("x9"), music.ParseNote(""), music.ParseNote("C")
println music.BeatSeconds(120.0), music.BeatSeconds(0.0)
endA4Freq
const A4Freq: f64 = 440The example for this item is shown with the ones above: music-Note.salam
Scale numbers Scale…
| Name | Value |
|---|---|
ScaleMajor | 0 |
ScaleMinor | 1 |
ScaleHarmonicMinor | 2 |
ScaleMelodicMinor | 3 |
ScalePentatonic | 4 |
ScalePentatonicMinor | 5 |
ScaleBlues | 6 |
ScaleChromatic | 7 |
ScaleDorian | 8 |
ScalePhrygian | 9 |
ScaleLydian | 10 |
ScaleMixolydian | 11 |
ScaleLocrian | 12 |
ScaleWholeTone | 13 |
import audio.music
func main:
mut maj := music.Scale(music.ScaleMajor)
println maj.len(), maj.get(0), maj.get(6)
maj.free()
mut minor := music.Scale(music.ScaleMinor)
println minor.get(2), minor.get(5)
minor.free()
mut chrom := music.Scale(music.ScaleChromatic)
println chrom.len()
chrom.free()
mut pent := music.Scale(music.ScalePentatonic)
println pent.len()
pent.free()
mut blues := music.Scale(music.ScaleBlues)
println blues.len(), blues.get(3)
blues.free()
mut dor := music.Scale(music.ScaleDorian)
println dor.get(2), dor.get(6)
dor.free()
mut run := music.ScaleNotes(60, music.ScaleMajor, 8)
println run.len(), run.get(0), run.get(7)
run.free()
mut tri := music.ChordNotes(60, music.ChordMajor)
println tri.len(), tri.get(1), tri.get(2)
tri.free()
mut m7 := music.ChordNotes(60, music.ChordMinor7)
println m7.len(), m7.get(3)
m7.free()
mut dim := music.Chord(music.ChordDiminished)
println dim.get(2)
dim.free()
mut sus := music.Chord(music.ChordSus4)
println sus.get(1)
sus.free()
mut aug := music.Chord(music.ChordAugmented)
println aug.get(2)
aug.free()
mut dom := music.Chord(music.ChordDominant7)
println dom.get(3)
dom.free()
endChord numbers Chord…
| Name | Value |
|---|---|
ChordMajor | 0 |
ChordMinor | 1 |
ChordDiminished | 2 |
ChordAugmented | 3 |
ChordSus2 | 4 |
ChordSus4 | 5 |
ChordMajor7 | 6 |
ChordMinor7 | 7 |
ChordDominant7 | 8 |
ChordDiminished7 | 9 |
The example for this item is shown with the ones above: music-Scale.salam
Dastgah numbers Dastgah…
| Name | Value |
|---|---|
DastgahShur | 0 |
DastgahMahur | 1 |
DastgahHomayoun | 2 |
DastgahSegah | 3 |
DastgahChahargah | 4 |
DastgahNava | 5 |
DastgahRastPanjgah | 6 |
import audio.music
func main:
mut shur := music.Dastgah(music.DastgahShur)
println shur.len(), shur.get(0), shur.get(2), shur.get(6)
shur.free()
mut mahur := music.Dastgah(music.DastgahMahur)
println mahur.get(2)
mahur.free()
mut homayoun := music.Dastgah(music.DastgahHomayoun)
println homayoun.get(1)
homayoun.free()
mut segah := music.Dastgah(music.DastgahSegah)
println segah.get(2)
segah.free()
println music.KoronCents, music.SoriCents
mut freqs := music.DastgahFreqs(60, music.DastgahShur)
println freqs.len()
println freqs.get(0) == music.NoteToFreq(60)
println freqs.get(2) > music.NoteToFreq(63), freqs.get(2) < music.NoteToFreq(64)
freqs.free()
println music.JustRatio(0), music.JustRatio(7), music.JustRatio(4)
println music.PythagoreanRatio(0), music.PythagoreanRatio(7), music.PythagoreanRatio(2)
println music.JustFreq(69, 7)
endKoronCents
const KoronCents: f64 = -50The example for this item is shown with the ones above: music-Dastgah.salam
SoriCents
const SoriCents: f64 = 50The example for this item is shown with the ones above: music-Dastgah.salam
Functions
NoteToFreq
func NoteToFreq(note: int): f64The example for this item is shown with the ones above: music-Note.salam
NoteToFreqCents
func NoteToFreqCents(note: int, cents: f64): f64The example for this item is shown with the ones above: music-Note.salam
FreqToNote
func FreqToNote(freq: f64): intThe example for this item is shown with the ones above: music-Note.salam
FreqToCents
func FreqToCents(freq: f64, note: int): f64The example for this item is shown with the ones above: music-Note.salam
Octave
func Octave(note: int): intThe example for this item is shown with the ones above: music-Note.salam
PitchClass
func PitchClass(note: int): intThe example for this item is shown with the ones above: music-Note.salam
Transpose
func Transpose(note: int, semitones: int): intThe example for this item is shown with the ones above: music-Note.salam
Interval
func Interval(low: int, high: int): intThe example for this item is shown with the ones above: music-Note.salam
NoteName
func NoteName(note: int): strThe example for this item is shown with the ones above: music-Note.salam
ParseNote
func ParseNote(name: str): intThe example for this item is shown with the ones above: music-Note.salam
Scale
func Scale(kind: int): Vector<int>The example for this item is shown with the ones above: music-Scale.salam
ScaleNotes
func ScaleNotes(root: int, kind: int, count: int): Vector<int>The example for this item is shown with the ones above: music-Scale.salam
Chord
func Chord(kind: int): Vector<int>The example for this item is shown with the ones above: music-Scale.salam
ChordNotes
func ChordNotes(root: int, kind: int): Vector<int>The example for this item is shown with the ones above: music-Scale.salam
Dastgah
func Dastgah(kind: int): Vector<f64>The example for this item is shown with the ones above: music-Dastgah.salam
DastgahFreqs
func DastgahFreqs(root: int, kind: int): Vector<f64>The example for this item is shown with the ones above: music-Dastgah.salam
JustRatio
func JustRatio(degree: int): f64The example for this item is shown with the ones above: music-Dastgah.salam
JustFreq
func JustFreq(root: int, degree: int): f64The example for this item is shown with the ones above: music-Dastgah.salam
PythagoreanRatio
func PythagoreanRatio(degree: int): f64The example for this item is shown with the ones above: music-Dastgah.salam
Cents
func Cents(a: f64, b: f64): f64The example for this item is shown with the ones above: music-Note.salam
BeatSeconds
func BeatSeconds(bpm: f64): f64The example for this item is shown with the ones above: music-Note.salam