Adding support for music melody arrays (#358)
* Adding support for music melody arrays in Typescript
This commit is contained in:
		@@ -166,6 +166,9 @@
 | 
			
		||||
  "led.unplot|param|y": "TODO",
 | 
			
		||||
  "music": "Generation of music tones through pin ``P0``.",
 | 
			
		||||
  "music.beat": "Returns the duration of a beat in milli-seconds",
 | 
			
		||||
  "music.beginMelody": "Starts playing a melody through pin ``P0``. \nNotes are expressed as a string of characters with this format: NOTE[octave][:duration]",
 | 
			
		||||
  "music.beginMelody|param|options": "melody options, once / forever, in the foreground / background",
 | 
			
		||||
  "music.builtInMelody": "Gets the melody array of a built-in melody.",
 | 
			
		||||
  "music.changeTempoBy": "Change the tempo by the specified amount",
 | 
			
		||||
  "music.changeTempoBy|param|bpm": "The change in beats per minute to the tempo, eg: 20",
 | 
			
		||||
  "music.noteFrequency": "Gets the frequency of a note.",
 | 
			
		||||
 
 | 
			
		||||
@@ -115,6 +115,30 @@
 | 
			
		||||
  "LedSpriteProperty.Y|block": "y",
 | 
			
		||||
  "Math.randomBoolean|block": "pick random true or false",
 | 
			
		||||
  "Math|block": "Math",
 | 
			
		||||
  "Melodies.BaDing|block": "ba ding",
 | 
			
		||||
  "Melodies.Baddy|block": "baddy",
 | 
			
		||||
  "Melodies.Birthday|block": "birthday",
 | 
			
		||||
  "Melodies.Blues|block": "blues",
 | 
			
		||||
  "Melodies.Chase|block": "chase",
 | 
			
		||||
  "Melodies.Dadadadum|block": "dadadum",
 | 
			
		||||
  "Melodies.Entertainer|block": "entertainer",
 | 
			
		||||
  "Melodies.Funeral|block": "funereal",
 | 
			
		||||
  "Melodies.Funk|block": "funk",
 | 
			
		||||
  "Melodies.JumpDown|block": "jump down",
 | 
			
		||||
  "Melodies.JumpUp|block": "jump up",
 | 
			
		||||
  "Melodies.Nyan|block": "nyan",
 | 
			
		||||
  "Melodies.Ode|block": "ode",
 | 
			
		||||
  "Melodies.PowerDown|block": "power down",
 | 
			
		||||
  "Melodies.PowerUp|block": "power up",
 | 
			
		||||
  "Melodies.Prelude|block": "prelude",
 | 
			
		||||
  "Melodies.Punchline|block": "punchline",
 | 
			
		||||
  "Melodies.Ringtone|block": "ringtone",
 | 
			
		||||
  "Melodies.Wawawawaa|block": "wawawawaa",
 | 
			
		||||
  "Melodies.Wedding|block": "wedding",
 | 
			
		||||
  "MelodyOptions.ForeverInBackground|block": "forever in background",
 | 
			
		||||
  "MelodyOptions.Forever|block": "forever",
 | 
			
		||||
  "MelodyOptions.OnceInBackground|block": "once in background",
 | 
			
		||||
  "MelodyOptions.Once|block": "once",
 | 
			
		||||
  "Note.CSharp3|block": "C#3",
 | 
			
		||||
  "Note.CSharp4|block": "C#4",
 | 
			
		||||
  "Note.CSharp5|block": "C#5",
 | 
			
		||||
@@ -200,6 +224,8 @@
 | 
			
		||||
  "led.unplot|block": "unplot|x %x|y %y",
 | 
			
		||||
  "led|block": "led",
 | 
			
		||||
  "music.beat|block": "%fraction|beat",
 | 
			
		||||
  "music.beginMelody|block": "start|melody %melody=device_builtin_melody| repeating %options",
 | 
			
		||||
  "music.builtInMelody|block": "%melody",
 | 
			
		||||
  "music.changeTempoBy|block": "change tempo by (bpm)|%value",
 | 
			
		||||
  "music.noteFrequency|block": "%note",
 | 
			
		||||
  "music.playTone|block": "play|tone %note=device_note|for %duration=device_beat",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										119
									
								
								libs/core/melodies.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								libs/core/melodies.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,119 @@
 | 
			
		||||
/*
 | 
			
		||||
The MIT License (MIT)
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2013-2016 The MicroPython-on-micro:bit Developers, as listed
 | 
			
		||||
in the accompanying AUTHORS file
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
in the Software without restriction, including without limitation the rights
 | 
			
		||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
furnished to do so, subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be included in
 | 
			
		||||
all copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
THE SOFTWARE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
// Melodies from file microbitmusictunes.c https://github.com/bbcmicrobit/MicroPython
 | 
			
		||||
 | 
			
		||||
enum Melodies {
 | 
			
		||||
    //% block="dadadum" blockIdentity=music.builtInMelody
 | 
			
		||||
    Dadadadum = 0,
 | 
			
		||||
    //% block="entertainer" blockIdentity=music.builtInMelody
 | 
			
		||||
    Entertainer,
 | 
			
		||||
    //% block="prelude" blockIdentity=music.builtInMelody
 | 
			
		||||
    Prelude,
 | 
			
		||||
    //% block="ode" blockIdentity=music.builtInMelody
 | 
			
		||||
    Ode,
 | 
			
		||||
    //% block="nyan" blockIdentity=music.builtInMelody
 | 
			
		||||
    Nyan,
 | 
			
		||||
    //% block="ringtone" blockIdentity=music.builtInMelody
 | 
			
		||||
    Ringtone,
 | 
			
		||||
    //% block="funk" blockIdentity=music.builtInMelody
 | 
			
		||||
    Funk,
 | 
			
		||||
    //% block="blues" blockIdentity=music.builtInMelody
 | 
			
		||||
    Blues,
 | 
			
		||||
    //% block="birthday" blockIdentity=music.builtInMelody
 | 
			
		||||
    Birthday,
 | 
			
		||||
    //% block="wedding" blockIdentity=music.builtInMelody
 | 
			
		||||
    Wedding,
 | 
			
		||||
    //% block="funereal" blockIdentity=music.builtInMelody
 | 
			
		||||
    Funeral,
 | 
			
		||||
    //% block="punchline" blockIdentity=music.builtInMelody
 | 
			
		||||
    Punchline,
 | 
			
		||||
    //% block="baddy" blockIdentity=music.builtInMelody
 | 
			
		||||
    Baddy,
 | 
			
		||||
    //% block="chase" blockIdentity=music.builtInMelody
 | 
			
		||||
    Chase,
 | 
			
		||||
    //% block="ba ding" blockIdentity=music.builtInMelody
 | 
			
		||||
    BaDing,
 | 
			
		||||
    //% block="wawawawaa" blockIdentity=music.builtInMelody
 | 
			
		||||
    Wawawawaa,
 | 
			
		||||
    //% block="jump up" blockIdentity=music.builtInMelody
 | 
			
		||||
    JumpUp,
 | 
			
		||||
    //% block="jump down" blockIdentity=music.builtInMelody
 | 
			
		||||
    JumpDown,
 | 
			
		||||
    //% block="power up" blockIdentity=music.builtInMelody
 | 
			
		||||
    PowerUp,
 | 
			
		||||
    //% block="power down" blockIdentity=music.builtInMelody
 | 
			
		||||
    PowerDown,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace music {
 | 
			
		||||
 | 
			
		||||
    export function getMelody(melody: Melodies): string[] {
 | 
			
		||||
        switch (melody) {
 | 
			
		||||
            case Melodies.Dadadadum:
 | 
			
		||||
                return ['r4:2', 'g', 'g', 'g', 'eb:8', 'r:2', 'f', 'f', 'f', 'd:8'];
 | 
			
		||||
            case Melodies.Entertainer:
 | 
			
		||||
                return ['d4:1', 'd#', 'e', 'c5:2', 'e4:1', 'c5:2', 'e4:1', 'c5:3', 'c:1', 'd', 'd#', 'e', 'c', 'd', 'e:2', 'b4:1', 'd5:2', 'c:4'];
 | 
			
		||||
            case Melodies.Prelude:
 | 
			
		||||
                return ['c4:1', 'e', 'g', 'c5', 'e', 'g4', 'c5', 'e', 'c4', 'e', 'g', 'c5', 'e', 'g4', 'c5', 'e', 'c4', 'd', 'g', 'd5', 'f', 'g4', 'd5', 'f', 'c4', 'd', 'g', 'd5', 'f', 'g4', 'd5', 'f', 'b3', 'd4', 'g', 'd5', 'f', 'g4', 'd5', 'f', 'b3', 'd4', 'g', 'd5', 'f', 'g4', 'd5', 'f', 'c4', 'e', 'g', 'c5', 'e', 'g4', 'c5', 'e', 'c4', 'e', 'g', 'c5', 'e', 'g4', 'c5', 'e'];
 | 
			
		||||
            case Melodies.Ode:
 | 
			
		||||
                return ['e4', 'e', 'f', 'g', 'g', 'f', 'e', 'd', 'c', 'c', 'd', 'e', 'e:6', 'd:2', 'd:8', 'e:4', 'e', 'f', 'g', 'g', 'f', 'e', 'd', 'c', 'c', 'd', 'e', 'd:6', 'c:2', 'c:8'];
 | 
			
		||||
            case Melodies.Nyan:
 | 
			
		||||
                return ['f#5:2', 'g#', 'c#:1', 'd#:2', 'b4:1', 'd5:1', 'c#', 'b4:2', 'b', 'c#5', 'd', 'd:1', 'c#', 'b4:1', 'c#5:1', 'd#', 'f#', 'g#', 'd#', 'f#', 'c#', 'd', 'b4', 'c#5', 'b4', 'd#5:2', 'f#', 'g#:1', 'd#', 'f#', 'c#', 'd#', 'b4', 'd5', 'd#', 'd', 'c#', 'b4', 'c#5', 'd:2', 'b4:1', 'c#5', 'd#', 'f#', 'c#', 'd', 'c#', 'b4', 'c#5:2', 'b4', 'c#5', 'b4', 'f#:1', 'g#', 'b:2', 'f#:1', 'g#', 'b', 'c#5', 'd#', 'b4', 'e5', 'd#', 'e', 'f#', 'b4:2', 'b', 'f#:1', 'g#', 'b', 'f#', 'e5', 'd#', 'c#', 'b4', 'f#', 'd#', 'e', 'f#', 'b:2', 'f#:1', 'g#', 'b:2', 'f#:1', 'g#', 'b', 'b', 'c#5', 'd#', 'b4', 'f#', 'g#', 'f#', 'b:2', 'b:1', 'a#', 'b', 'f#', 'g#', 'b', 'e5', 'd#', 'e', 'f#', 'b4:2', 'c#5'];
 | 
			
		||||
            case Melodies.Ringtone:
 | 
			
		||||
                return ['c4:1', 'd', 'e:2', 'g', 'd:1', 'e', 'f:2', 'a', 'e:1', 'f', 'g:2', 'b', 'c5:4'];
 | 
			
		||||
            case Melodies.Funk:
 | 
			
		||||
                return ['c2:2', 'c', 'd#', 'c:1', 'f:2', 'c:1', 'f:2', 'f#', 'g', 'c', 'c', 'g', 'c:1', 'f#:2', 'c:1', 'f#:2', 'f', 'd#'];
 | 
			
		||||
            case Melodies.Blues:
 | 
			
		||||
                return ['c2:2', 'e', 'g', 'a', 'a#', 'a', 'g', 'e', 'c2:2', 'e', 'g', 'a', 'a#', 'a', 'g', 'e', 'f', 'a', 'c3', 'd', 'd#', 'd', 'c', 'a2', 'c2:2', 'e', 'g', 'a', 'a#', 'a', 'g', 'e', 'g', 'b', 'd3', 'f', 'f2', 'a', 'c3', 'd#', 'c2:2', 'e', 'g', 'e', 'g', 'f', 'e', 'd'];
 | 
			
		||||
            case Melodies.Birthday:
 | 
			
		||||
                return ['c4:3', 'c:1', 'd:4', 'c:4', 'f', 'e:8', 'c:3', 'c:1', 'd:4', 'c:4', 'g', 'f:8', 'c:3', 'c:1', 'c5:4', 'a4', 'f', 'e', 'd', 'a#:3', 'a#:1', 'a:4', 'f', 'g', 'f:8'];
 | 
			
		||||
            case Melodies.Wedding:
 | 
			
		||||
                return ['c4:4', 'f:3', 'f:1', 'f:8', 'c:4', 'g:3', 'e:1', 'f:8', 'c:4', 'f:3', 'a:1', 'c5:4', 'a4:3', 'f:1', 'f:4', 'e:3', 'f:1', 'g:8'];
 | 
			
		||||
            case Melodies.Funeral:
 | 
			
		||||
                return ['c3:4', 'c:3', 'c:1', 'c:4', 'd#:3', 'd:1', 'd:3', 'c:1', 'c:3', 'b2:1', 'c3:4'];
 | 
			
		||||
            case Melodies.Punchline:
 | 
			
		||||
                return ['c4:3', 'g3:1', 'f#', 'g', 'g#:3', 'g', 'r', 'b', 'c4'];
 | 
			
		||||
            case Melodies.Baddy:
 | 
			
		||||
                return ['c3:3', 'r', 'd:2', 'd#', 'r', 'c', 'r', 'f#:8'];
 | 
			
		||||
            case Melodies.Chase:
 | 
			
		||||
                return ['a4:1', 'b', 'c5', 'b4', 'a:2', 'r', 'a:1', 'b', 'c5', 'b4', 'a:2', 'r', 'a:2', 'e5', 'd#', 'e', 'f', 'e', 'd#', 'e', 'b4:1', 'c5', 'd', 'c', 'b4:2', 'r', 'b:1', 'c5', 'd', 'c', 'b4:2', 'r', 'b:2', 'e5', 'd#', 'e', 'f', 'e', 'd#', 'e'];
 | 
			
		||||
            case Melodies.BaDing:
 | 
			
		||||
                return ['b5:1', 'e6:3'];
 | 
			
		||||
            case Melodies.Wawawawaa:
 | 
			
		||||
                return ['e3:3', 'r:1', 'd#:3', 'r:1', 'd:4', 'r:1', 'c#:8'];
 | 
			
		||||
            case Melodies.JumpUp:
 | 
			
		||||
                return ['c5:1', 'd', 'e', 'f', 'g'];
 | 
			
		||||
            case Melodies.JumpDown:
 | 
			
		||||
                return ['g5:1', 'f', 'e', 'd', 'c'];
 | 
			
		||||
            case Melodies.PowerUp:
 | 
			
		||||
                return ['g4:1', 'c5', 'e', 'g:2', 'e:1', 'g:3'];
 | 
			
		||||
            case Melodies.PowerDown:
 | 
			
		||||
                return ['g5:1', 'd#', 'c', 'g4:2', 'b:1', 'c5:3'];
 | 
			
		||||
            default:
 | 
			
		||||
                return [];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -126,12 +126,24 @@ enum BeatFraction {
 | 
			
		||||
    Breve = 64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum MelodyOptions {
 | 
			
		||||
    //% block="once""
 | 
			
		||||
    Once = 1,
 | 
			
		||||
    //% block="forever"
 | 
			
		||||
    Forever = 2,
 | 
			
		||||
    //% block="once in background"
 | 
			
		||||
    OnceInBackground = 4,
 | 
			
		||||
    //% block="forever in background"
 | 
			
		||||
    ForeverInBackground = 8
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Generation of music tones through pin ``P0``.
 | 
			
		||||
 */
 | 
			
		||||
//% color=#D83B01 weight=98 icon="\uf025"
 | 
			
		||||
namespace music {
 | 
			
		||||
    let beatsPerMinute: number = 120;
 | 
			
		||||
    let freqTable: number[] = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Plays a tone through pin ``P0`` for the given duration.
 | 
			
		||||
@@ -185,6 +197,7 @@ namespace music {
 | 
			
		||||
 | 
			
		||||
    function init() {
 | 
			
		||||
        if (beatsPerMinute <= 0) beatsPerMinute = 120;
 | 
			
		||||
        if (freqTable.length == 0) freqTable = [28, 29, 31, 33, 35, 37, 39, 41, 44, 46, 49, 52, 55, 58, 62, 65, 69, 73, 78, 82, 87, 92, 98, 104, 110, 117, 123, 131, 139, 147, 156, 165, 175, 185, 196, 208, 220, 233, 247, 262, 277, 294, 311, 330, 349, 370, 392, 415, 440, 466, 494, 523, 554, 587, 622, 659, 698, 740, 784, 831, 880, 932, 988, 1047, 1109, 1175, 1245, 1319, 1397, 1480, 1568, 1661, 1760, 1865, 1976, 2093, 2217, 2349, 2489, 2637, 2794, 2960, 3136, 3322, 3520, 3729, 3951, 4186]
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -240,4 +253,127 @@ namespace music {
 | 
			
		||||
            beatsPerMinute = Math.max(1, bpm);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let currentMelody: Melody;
 | 
			
		||||
    let currentBackgroundMelody: Melody;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the melody array of a built-in melody.
 | 
			
		||||
     * @param name the note name, eg: Note.C
 | 
			
		||||
     */
 | 
			
		||||
    //% weight=50 help=music/builtin-melody
 | 
			
		||||
    //% blockId=device_builtin_melody block="%melody"
 | 
			
		||||
    //% blockHidden=true
 | 
			
		||||
    export function builtInMelody(melody: Melodies): string[] {
 | 
			
		||||
        return getMelody(melody);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Starts playing a melody through pin ``P0``.
 | 
			
		||||
     * Notes are expressed as a string of characters with this format: NOTE[octave][:duration]
 | 
			
		||||
     * @param melody the melody array to play, eg: ['g5:1']
 | 
			
		||||
     * @param options melody options, once / forever, in the foreground / background
 | 
			
		||||
     */
 | 
			
		||||
    //% help=music/start-melody weight=60
 | 
			
		||||
    //% blockId=device_start_melody block="start|melody %melody=device_builtin_melody| repeating %options"
 | 
			
		||||
    //% parts="headphone"
 | 
			
		||||
    export function beginMelody(melodyArray: string[], options: MelodyOptions = MelodyOptions.Once) {
 | 
			
		||||
        init();
 | 
			
		||||
        if (currentMelody != undefined) {
 | 
			
		||||
            if (((options & MelodyOptions.OnceInBackground) == 0)
 | 
			
		||||
                && ((options & MelodyOptions.ForeverInBackground) == 0)
 | 
			
		||||
                && currentMelody.background == true) {
 | 
			
		||||
                currentBackgroundMelody = currentMelody;
 | 
			
		||||
            }
 | 
			
		||||
            currentMelody = new Melody(melodyArray, options);
 | 
			
		||||
        } else {
 | 
			
		||||
            currentMelody = new Melody(melodyArray, options);
 | 
			
		||||
            // Only start the fiber once
 | 
			
		||||
            control.inBackground(() => {
 | 
			
		||||
                while (currentMelody.hasNextNote()) {
 | 
			
		||||
                    playNextNote(currentMelody);
 | 
			
		||||
                    if (!currentMelody.hasNextNote() && currentBackgroundMelody) {
 | 
			
		||||
                        // Swap the background melody back
 | 
			
		||||
                        currentMelody = currentBackgroundMelody;
 | 
			
		||||
                        currentBackgroundMelody = null;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                currentMelody = null;
 | 
			
		||||
            })
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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;
 | 
			
		||||
 | 
			
		||||
        for (let pos = 0; pos < currNote.length; pos++) {
 | 
			
		||||
            let noteChar = currNote.charAt(pos);
 | 
			
		||||
            switch (noteChar) {
 | 
			
		||||
                case 'a': case 'A': note = 1; break;
 | 
			
		||||
                case 'b': case 'B': note = 3; break;
 | 
			
		||||
                case 'c': case 'C': note = 4; break;
 | 
			
		||||
                case 'd': case 'D': note = 6; break;
 | 
			
		||||
                case 'e': case 'E': note = 8; break;
 | 
			
		||||
                case 'f': case 'F': note = 9; break;
 | 
			
		||||
                case 'g': case 'G': note = 11; break;
 | 
			
		||||
                case 'r': case 'R': isrest = true; break;
 | 
			
		||||
                case '#': note++; break;
 | 
			
		||||
                case 'b': note--; break;
 | 
			
		||||
                case ':': parsingOctave = false; beatPos = pos; break;
 | 
			
		||||
                default: if (parsingOctave) currentOctave = parseInt(noteChar);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (!parsingOctave) {
 | 
			
		||||
            currentDuration = parseInt(currNote.substr(beatPos + 1, currNote.length - beatPos));
 | 
			
		||||
        }
 | 
			
		||||
        let beat = (60000 / beatsPerMinute) / 4;
 | 
			
		||||
        if (isrest) {
 | 
			
		||||
            music.rest(currentDuration * beat)
 | 
			
		||||
        } else {
 | 
			
		||||
            let keyNumber = note + (12 * (currentOctave - 1));
 | 
			
		||||
            let frequency = keyNumber >= 0 && keyNumber < freqTable.length ? freqTable[keyNumber] : 0;
 | 
			
		||||
            music.playTone(frequency, currentDuration * beat);
 | 
			
		||||
        }
 | 
			
		||||
        melody.currentDuration = currentDuration;
 | 
			
		||||
        melody.currentOctave = currentOctave;
 | 
			
		||||
        melody.currentPos = melody.repeating == true && currentPos == melody.melodyArray.length - 1 ? 0 : currentPos + 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class Melody {
 | 
			
		||||
        public melodyArray: string[];
 | 
			
		||||
        public currentDuration: number;
 | 
			
		||||
        public currentOctave: number;
 | 
			
		||||
        public currentPos: number;
 | 
			
		||||
        public repeating: boolean;
 | 
			
		||||
        public background: boolean;
 | 
			
		||||
 | 
			
		||||
        constructor(melodyArray: string[], options: MelodyOptions) {
 | 
			
		||||
            this.melodyArray = melodyArray;
 | 
			
		||||
            this.repeating = ((options & MelodyOptions.Forever) != 0);
 | 
			
		||||
            this.repeating = this.repeating ? true : ((options & MelodyOptions.ForeverInBackground) != 0)
 | 
			
		||||
            this.background = ((options & MelodyOptions.OnceInBackground) != 0);
 | 
			
		||||
            this.background = this.background ? true : ((options & MelodyOptions.ForeverInBackground) != 0);
 | 
			
		||||
            this.currentDuration = 4; //Default duration (Crotchet)
 | 
			
		||||
            this.currentOctave = 4; //Middle octave
 | 
			
		||||
            this.currentPos = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        hasNextNote() {
 | 
			
		||||
            return this.repeating || this.currentPos < this.melodyArray.length;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        nextNote(): string {
 | 
			
		||||
            const currentNote = this.melodyArray[this.currentPos];
 | 
			
		||||
            return currentNote;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,7 @@
 | 
			
		||||
        "led.cpp",
 | 
			
		||||
        "led.ts",
 | 
			
		||||
        "music.ts",
 | 
			
		||||
        "melodies.ts",
 | 
			
		||||
        "pins.cpp",
 | 
			
		||||
        "pins.ts",
 | 
			
		||||
        "serial.cpp",
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user