|
|
import { IndexedByteArray } from "../utils/indexed_array.js"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export class MIDIMessage |
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ticks; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
messageStatusByte; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
messageData; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
constructor(ticks, byte, data) |
|
|
{ |
|
|
this.ticks = ticks; |
|
|
this.messageStatusByte = byte; |
|
|
this.messageData = data; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function getChannel(statusByte) |
|
|
{ |
|
|
const eventType = statusByte & 0xF0; |
|
|
const channel = statusByte & 0x0F; |
|
|
|
|
|
let resultChannel = channel; |
|
|
|
|
|
switch (eventType) |
|
|
{ |
|
|
|
|
|
case 0x80: |
|
|
case 0x90: |
|
|
case 0xA0: |
|
|
case 0xB0: |
|
|
case 0xC0: |
|
|
case 0xD0: |
|
|
case 0xE0: |
|
|
break; |
|
|
|
|
|
case 0xF0: |
|
|
switch (channel) |
|
|
{ |
|
|
case 0x0: |
|
|
resultChannel = -3; |
|
|
break; |
|
|
|
|
|
case 0x1: |
|
|
case 0x2: |
|
|
case 0x3: |
|
|
case 0x4: |
|
|
case 0x5: |
|
|
case 0x6: |
|
|
case 0x7: |
|
|
case 0x8: |
|
|
case 0x9: |
|
|
case 0xA: |
|
|
case 0xB: |
|
|
case 0xC: |
|
|
case 0xD: |
|
|
case 0xE: |
|
|
resultChannel = -1; |
|
|
break; |
|
|
|
|
|
case 0xF: |
|
|
resultChannel = -2; |
|
|
break; |
|
|
} |
|
|
break; |
|
|
|
|
|
default: |
|
|
resultChannel = -1; |
|
|
} |
|
|
|
|
|
return resultChannel; |
|
|
} |
|
|
|
|
|
|
|
|
export const messageTypes = { |
|
|
noteOff: 0x80, |
|
|
noteOn: 0x90, |
|
|
polyPressure: 0xA0, |
|
|
controllerChange: 0xB0, |
|
|
programChange: 0xC0, |
|
|
channelPressure: 0xD0, |
|
|
pitchBend: 0xE0, |
|
|
systemExclusive: 0xF0, |
|
|
timecode: 0xF1, |
|
|
songPosition: 0xF2, |
|
|
songSelect: 0xF3, |
|
|
tuneRequest: 0xF6, |
|
|
clock: 0xF8, |
|
|
start: 0xFA, |
|
|
continue: 0xFB, |
|
|
stop: 0xFC, |
|
|
activeSensing: 0xFE, |
|
|
reset: 0xFF, |
|
|
sequenceNumber: 0x00, |
|
|
text: 0x01, |
|
|
copyright: 0x02, |
|
|
trackName: 0x03, |
|
|
instrumentName: 0x04, |
|
|
lyric: 0x05, |
|
|
marker: 0x06, |
|
|
cuePoint: 0x07, |
|
|
programName: 0x08, |
|
|
midiChannelPrefix: 0x20, |
|
|
midiPort: 0x21, |
|
|
endOfTrack: 0x2F, |
|
|
setTempo: 0x51, |
|
|
smpteOffset: 0x54, |
|
|
timeSignature: 0x58, |
|
|
keySignature: 0x59, |
|
|
sequenceSpecific: 0x7F |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function getEvent(statusByte) |
|
|
{ |
|
|
const status = statusByte & 0xF0; |
|
|
const channel = statusByte & 0x0F; |
|
|
|
|
|
let eventChannel = -1; |
|
|
let eventStatus = statusByte; |
|
|
|
|
|
if (status >= 0x80 && status <= 0xE0) |
|
|
{ |
|
|
eventChannel = channel; |
|
|
eventStatus = status; |
|
|
} |
|
|
|
|
|
return { |
|
|
status: eventStatus, |
|
|
channel: eventChannel |
|
|
}; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export const midiControllers = { |
|
|
bankSelect: 0, |
|
|
modulationWheel: 1, |
|
|
breathController: 2, |
|
|
footController: 4, |
|
|
portamentoTime: 5, |
|
|
dataEntryMsb: 6, |
|
|
mainVolume: 7, |
|
|
balance: 8, |
|
|
pan: 10, |
|
|
expressionController: 11, |
|
|
effectControl1: 12, |
|
|
effectControl2: 13, |
|
|
generalPurposeController1: 16, |
|
|
generalPurposeController2: 17, |
|
|
generalPurposeController3: 18, |
|
|
generalPurposeController4: 19, |
|
|
lsbForControl0BankSelect: 32, |
|
|
lsbForControl1ModulationWheel: 33, |
|
|
lsbForControl2BreathController: 34, |
|
|
lsbForControl4FootController: 36, |
|
|
lsbForControl5PortamentoTime: 37, |
|
|
lsbForControl6DataEntry: 38, |
|
|
lsbForControl7MainVolume: 39, |
|
|
lsbForControl8Balance: 40, |
|
|
lsbForControl10Pan: 42, |
|
|
lsbForControl11ExpressionController: 43, |
|
|
lsbForControl12EffectControl1: 44, |
|
|
lsbForControl13EffectControl2: 45, |
|
|
sustainPedal: 64, |
|
|
portamentoOnOff: 65, |
|
|
sostenutoPedal: 66, |
|
|
softPedal: 67, |
|
|
legatoFootswitch: 68, |
|
|
hold2Pedal: 69, |
|
|
soundVariation: 70, |
|
|
filterResonance: 71, |
|
|
releaseTime: 72, |
|
|
attackTime: 73, |
|
|
brightness: 74, |
|
|
decayTime: 75, |
|
|
vibratoRate: 76, |
|
|
vibratoDepth: 77, |
|
|
vibratoDelay: 78, |
|
|
soundController10: 79, |
|
|
generalPurposeController5: 80, |
|
|
generalPurposeController6: 81, |
|
|
generalPurposeController7: 82, |
|
|
generalPurposeController8: 83, |
|
|
portamentoControl: 84, |
|
|
reverbDepth: 91, |
|
|
tremoloDepth: 92, |
|
|
chorusDepth: 93, |
|
|
detuneDepth: 94, |
|
|
phaserDepth: 95, |
|
|
dataIncrement: 96, |
|
|
dataDecrement: 97, |
|
|
NRPNLsb: 98, |
|
|
NRPNMsb: 99, |
|
|
RPNLsb: 100, |
|
|
RPNMsb: 101, |
|
|
allSoundOff: 120, |
|
|
resetAllControllers: 121, |
|
|
localControlOnOff: 122, |
|
|
allNotesOff: 123, |
|
|
omniModeOff: 124, |
|
|
omniModeOn: 125, |
|
|
monoModeOn: 126, |
|
|
polyModeOn: 127 |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export const dataBytesAmount = { |
|
|
0x8: 2, |
|
|
0x9: 2, |
|
|
0xA: 2, |
|
|
0xB: 2, |
|
|
0xC: 1, |
|
|
0xD: 1, |
|
|
0xE: 2 |
|
|
}; |