in libs/core/music.ts [490:539]
function playNextNote(melody: Melody): void {
// cache elements
let currNote = melody.nextNote();
let currentPos = melody.currentPos;
let currentDuration = melody.currentDuration;
let currentOctave = melody.currentOctave;
let note: number;
let isrest: boolean = false;
let beatPos: number;
let parsingOctave: boolean = true;
let prevNote: boolean = false;
for (let pos = 0; pos < currNote.length; pos++) {
let noteChar = currNote.charAt(pos);
switch (noteChar) {
case 'c': case 'C': note = 1; prevNote = true; break;
case 'd': case 'D': note = 3; prevNote = true; break;
case 'e': case 'E': note = 5; prevNote = true; break;
case 'f': case 'F': note = 6; prevNote = true; break;
case 'g': case 'G': note = 8; prevNote = true; break;
case 'a': case 'A': note = 10; prevNote = true; break;
case 'B': note = 12; prevNote = true; break;
case 'r': case 'R': isrest = true; prevNote = false; break;
case '#': note++; prevNote = false; break;
case 'b': if (prevNote) note--; else { note = 12; prevNote = true; } break;
case ':': parsingOctave = false; beatPos = pos; prevNote = false; break;
default: prevNote = false; if (parsingOctave) currentOctave = parseInt(noteChar);
}
}
if (!parsingOctave) {
currentDuration = parseInt(currNote.substr(beatPos + 1, currNote.length - beatPos));
}
let beat = Math.idiv(60000, beatsPerMinute) >> 2;
if (isrest) {
music.rest(currentDuration * beat)
} else {
let keyNumber = note + (12 * (currentOctave - 1));
let frequency = freqs.getNumber(NumberFormat.UInt16LE, keyNumber * 2) || 0;
music.playTone(frequency, currentDuration * beat);
}
melody.currentDuration = currentDuration;
melody.currentOctave = currentOctave;
const repeating = melody.repeating && currentPos == melody.melodyArray.length - 1;
melody.currentPos = repeating ? 0 : currentPos + 1;
control.raiseEvent(MICROBIT_MELODY_ID, melody.background ? MusicEvent.BackgroundMelodyNotePlayed : MusicEvent.MelodyNotePlayed);
if (repeating)
control.raiseEvent(MICROBIT_MELODY_ID, melody.background ? MusicEvent.BackgroundMelodyRepeated : MusicEvent.MelodyRepeated);
}