# The Moon, from DuckTales on the NES: a score for one speaker # https://lab.glossema.dev/play/moon # F sharp major, 140 bpm. The figure climbs F# C# F# G#; the melody enters on A# B C#. :local beat 428ms; :global notes { "F#4"=370; "G#4"=415; "A4"=440; "A#4"=466; "B4"=494; "C#5"=554; "D#5"=622; "E5"=659; "F5"=698; "F#5"=740; "G#5"=831; "A5"=880; "A#5"=932; "B5"=988; "C#6"=1109; "D6"=1175; "F#6"=1480; "G#6"=1661; "A#6"=1865; "B6"=1976 }; :global durs { "e"=($beat / 2); "q"=$beat; "q."=(($beat * 3) / 2); "h"=($beat * 2); "h."=($beat * 3); "w"=($beat * 4) }; # $play "NOTE:dur" sounds one note and waits out its slot; "-" is a rest :global play do={ :global notes; :global durs; :local cut [:find $1 ":"]; :local note [:pick $1 0 $cut]; :local key [:pick $1 ($cut + 1) [:len $1]]; :local len ($durs->$key); :if ($note != "-") do={ :beep frequency=($notes->$note) length=($len - 20ms); } :delay $len; } # 1. Arpeggio: the broken chord as the game plays it, fifteen eighths round and round, # then it settles into four-four with one more C# and the bass walks in :put "Arpeggio"; :local figure { "F#5:e"; "C#6:e"; "F#6:e"; "G#6:e"; "C#6:e"; "F#6:e"; "G#6:e"; "B6:e"; "C#6:e"; "B6:e"; "A#6:e"; "C#6:e"; "A#6:e"; "G#6:e"; "F#6:e" }; :for i from=1 to=3 do={ :foreach n in=$figure do={ $play $n; } } :local steady { "F#5:e"; "C#6:e"; "F#6:e"; "G#6:e"; "C#6:e"; "F#6:e"; "G#6:e"; "C#6:e"; "B6:e"; "C#6:e"; "B6:e"; "A#6:e"; "C#6:e"; "A#6:e"; "G#6:e"; "F#6:e" }; :foreach n in=$steady do={ $play $n; } # 2. Melody: half a figure, then the tune walks in on A# B C#; every long note is cut to ring # and the figure sounds through the gaps, as it does under the game's melody :put "Melody"; :local pickup { "F#5:e"; "C#6:e"; "F#6:e"; "G#6:e"; "A#4:e"; "B4:e"; "C#5:e"; "C#5:q." }; :local theme { "F#5:q"; "F5:q"; "F#5:q"; "G#5:q"; "A#5:e"; "F#5:h"; "C#6:e"; "B6:e"; "C#6:e"; "B6:e"; "A#6:e"; "C#6:e"; "A#6:e"; "F5:e"; "F#5:e"; "C#6:q."; "F#5:e"; "F#5:h"; "B6:e"; "C#6:e"; "B6:e"; "A#6:e"; "C#6:e"; "A#6:e"; "F#5:e"; "F#5:e" }; :local answer { "F#5:h"; "-:e"; "G#5:e"; "F#5:e"; "F5:h"; "A#6:e"; "C#6:e"; "A#6:e"; "G#6:e"; "F#6:e"; "A#4:h"; "-:e"; "G#4:e"; "F#4:e"; "C#5:h"; "-:e"; "F#5:q"; "G#5:q"; "B5:q."; "A#5:e"; "A#5:h"; "B6:e"; "C#6:e"; "B6:e"; "A#6:e"; "C#6:q"; "B5:q"; "A#5:e"; "B5:e"; "A#5:e"; "F#5:q"; "C#5:q."; "-:e"; "G#5:e"; "F#5:e"; "F5:e"; "D#5:e"; "F5:q."; "F#5:q"; "D6:e"; "F#5:q"; "G#6:e"; "F#5:h"; "B5:e"; "A#5:e"; "F#5:e"; "C#5:e"; "B4:e"; "A#4:e" }; :foreach n in=$pickup do={ $play $n; } :foreach n in=$theme do={ $play $n; } :foreach n in=$answer do={ $play $n; } # 3. Climb: the second half, in pairs of repeated notes over new chords, rising twice # and the second time all the way to the high C#, which is left ringing :put "Climb"; :local climb { "F#5:e"; "F#5:e"; "-:q"; "G#5:e"; "G#5:e"; "-:e"; "E5:h"; "C#5:q"; "E5:e"; "C#5:e"; "A4:e"; "B4:q"; "A4:e"; "B4:e"; "-:e"; "A4:e"; "-:e"; "C#5:h."; "-:q."; "F#5:e"; "F#5:e"; "-:q"; "G#5:e"; "G#5:e"; "-:e"; "A5:q"; "E5:q"; "E5:q"; "E5:e"; "A5:e"; "B5:h."; "-:e"; "A5:e"; "C#6:h"; "-:q"; "C#6:e"; "C#6:e"; "C#6:h" }; :foreach n in=$climb do={ $play $n; } # 4. Return: the figure comes back under the ringing C#, the tune enters once more, # then the game's own falling run closes on a low F sharp :put "Return"; :local tail { "G#6:e"; "C#6:e"; "F#6:e"; "G#6:e"; "C#6:e"; "B6:e"; "C#6:e"; "B6:e"; "A#6:e"; "C#6:e"; "A#6:e"; "G#6:e"; "F#6:e" }; :local close { "F#5:h."; "-:q"; "F#6:e"; "C#6:e"; "B5:e"; "A#5:e"; "F#5:e"; "C#5:e"; "B4:e"; "A#4:e"; "F#4:w" }; :foreach n in=$tail do={ $play $n; } :foreach n in=$pickup do={ $play $n; } :foreach n in=$theme do={ $play $n; } :foreach n in=$close do={ $play $n; }