enum MidiCommand { TuneRequest = 0xf6 , TimingClock = 0xf8 , Start = 0xfa , Continue = 0xfb , Stop = 0xfc , ActiveSensing = 0xfe , Reset = 0xff } enum MidiChannelMode { AllSoundOff = 120 << 8 | 0 , ResetAllControllers = 121 << 8 | 0 , LocalControlOff = 122 << 8 | 0 , LocalControlOn = 122 << 8 | 127 , AllNotesOff = 123 << 8 | 0 , OmniModeOff = 124 << 8 | 0 , OmniModeOn = 125 << 8 | 0 , MonoModeOff = 126 << 8 | 0 , MonoModeOn = 126 << 8 | 1 , PolyModeOn = 127 << 8 | 0 } /**
 * Blocks to simulate MIDI instruments.
 */ namespace midi { /**
     * Transport needs to be set prior to using MIDI APIs
     */ let transport ; param newTransport export function setTransport ( newTransport ) { transport = newTransport ; } param data export function sendMessage ( data ) { if ( ! transport ) return ; const buf = pins . createBuffer ( data . length ) ; for ( let i = 0 ; i < data . length ; ++ i ) buf . setNumber ( NumberFormat . UInt8LE , i , data [ i ] ) ; control . __midiSend ( buf ) ; transport ( buf ) ; } /**
    * Send raw MIDI messages via serial
    */ export function useRawSerial ( ) { function send ( data ) { serial . writeBuffer ( data ) ; } setTransport ( send ) ; } /**
     * Send human readable MIDI messages via serial
     */ export function useSerial ( ) { function send ( data ) { serial . writeString ( "midi:" ) ; for ( let i = 0 ; i < data . length ; ++ i ) { if ( i > 0 ) serial . writeString ( "," ) ; serial . writeNumber ( data [ i ] ) ; } serial . writeLine ( "" ) ; } setTransport ( send ) ; } let channels ; param channel export function channel ( channel ) { channel -= 1 ; channel = Math . max ( 0 , Math . min ( 15 , channel ) ) ; if ( ! channels ) channels = [ ] ; let i = channels [ channel ] ; if ( ! i ) i = channels [ channel ] = new MidiController ( channel ) ; return i ; } /**
     * A Output MIDI controller, typically a keyboard.
     */ export class MidiController { channel : number ; velocity : number ; constructor ( channel ) { this . channel = channel ; this . velocity = 0x7f ; } param key param duration note ( key , duration ) { key = key >> 0 ; if ( duration > 0 ) { this . noteOn ( key ) ; basic . pause ( duration ) ; } this . noteOff ( key ) ; basic . pause ( 6 ) ; } param key noteOn ( key , velocity = 0 ) { key = key >> 0 ; if ( key < 0 || key > 0x7f ) return ; sendMessage ( [ 0x90 | this . channel , key , velocity || this . velocity ] ) ; } param key noteOff ( key , velocity = 0 ) { key = key >> 0 ; if ( key < 0 || key > 0x7f ) return ; sendMessage ( [ 0x80 | this . channel , key , velocity || this . velocity ] ) ; } param instrument setInstrument ( instrument ) { instrument = instrument >> 0 ; instrument -= 1 ; if ( instrument < 0 || instrument > 0x7f ) return ; sendMessage ( [ 0xc0 | this . channel , instrument ] ) ; } param velocity setVelocity ( velocity ) { velocity = velocity >> 0 ; this . velocity = velocity & 0x7f ; } param amount pitchBend ( amount ) { amount = amount >> 0 ; amount = Math . max ( 0 , amount & 0x3fff ) ; sendMessage ( [ 0xe0 | this . channel , amount & 0x7f , ( amount >> 7 ) & 0x7f ] ) ; } param cmd command ( cmd ) { cmd = cmd >> 0 ; sendMessage ( [ cmd | this . channel ] ) ; } param program programChange ( program ) { program = program >> 0 ; sendMessage ( [ 0xc0 | this . channel , program & 0x7f ] ) ; } param pressure aftertouch ( pressure ) { pressure = pressure >> 0 ; sendMessage ( [ 0xd0 | this . channel , pressure & 0x7f ] ) ; } param key param pressure polyphonicAftertouch ( key , pressure ) { key = key >> 0 ; pressure = pressure >> 0 ; sendMessage ( [ 0xa0 | this . channel , key & 0x7f , pressure & 0x7f ] ) ; } param controller param value controlChange ( fn , value ) { fn = fn >> 0 ; value = value >> 0 ; sendMessage ( [ 0xb0 | this . channel , fn & 0x7f , value & 0x7f ] ) ; } param mode channelMode ( mode ) { sendMessage ( [ 0xb0 | this . channel , ( mode >> 8 ) & 0x7f , mode & 0x7f ] ) ; } } param frequency param duration export function playTone ( frequency , duration ) { channel ( 1 ) . note ( frequencyToKey ( frequency ) , duration ) ; } param frequency export function toneOn ( frequency ) { channel ( 1 ) . noteOn ( frequencyToKey ( frequency ) ) ; } param frequency export function toneOff ( frequency ) { channel ( 1 ) . noteOff ( frequencyToKey ( frequency ) ) ; } param bend export function pitchBend ( bend ) { channel ( 1 ) . pitchBend ( bend ) ; } param frequency export function frequencyToKey ( frequency ) { frequency = frequency | 0 ; const log2 = 0.6931471805599453 ; return Math . max ( 0 , Math . min ( 127 , Math . round ( Math . log ( frequency / 440.0 ) / log2 * 12 + 69 ) ) ) ; } param key export function playDrum ( key ) { channel ( 10 ) . noteOn ( key ) ; } param drumSound export function drumSound ( sound ) { return sound ; } /**
     * Selects an instrument
     */ export function instrument ( i ) { return i ; } /**
     * Selects a command
     */ export function command ( c ) { return c ; } }