-
Notifications
You must be signed in to change notification settings - Fork 12
MIDI Class
This is the module responsible for parsing MIDI files into objects readable by Sequencer
class.
Tip
If you encounter any errors in this documentation, please open an issue!
// normal install
import {MIDI} from "./spessasynth_lib/midi_parser/midi_loader.js";
// npm package
import {MIDI} from "spessasynth_lib";
Tip
Using the npm package? Make sure you've read this
const parsedMIDI = new MIDI(arrayBuffer);
- arrayBuffer - an
arrayBuffer
anstance of the midi file.
The amount of tracks in the file.
console.log(`this file has ${parsedMIDI.tracksAmount}`);
The time division of the midi file. Used by the Sequencer
class
console.log(`this sequence's time division is ${parsedMIDI.timeDivision}`);
The sequence's name. The first track's Track Name
's event text.
console.log(`This sequence is named "${parsedMIDI.midiName}"`);
Tip
This property uses basic decoding. If the name is encoded in a different encoding, like shift_jis, it might be better to use rawMidiName.
The name of the MIDI file if provided during the initialization.
A boolean
indicating if the MIDI name is the same as file name, therefore there's no need to decode it.
The sequence's name, as a raw Uint8Array
. Useful for handling unusual encodings.
console.log(new TextDecoder("shift-jis").decode(parsedMIDI.rawMidiName)); // ダメなりんご!!
The decoded copyright and description of the file. Also includes the Sound Canvas display messages.
console.log(`Midi file description: ${parsedMIDI.copyright}`);
Ordered from last to first, all the tempo changes in the file. Will always contain at least 1 tempo (the default 120BPM).
[
{
tempo: 140 /* tempo in BPM */,
ticks: 5437 /* absolute amount of MIDI Ticks from the start */
},
/*...*/
{
tempo: 120,
ticks: 0
}
];
The points of the loop detected in the MIDI file in ticks. If there's nothing detected, the loop will start from the first note on event and end will be the last note off. Current looping detection is: CC 2/4, 116/117 and "start", "loopStart" and "loopEnd" markers.
console.log(parsedMIDI.loop); // {start: 1294, end: 49573}
The MIDI file format. Usually 0 or 1, rarely 2.
console.log(parsedMIDI.format); // 1
The tick number of the first noteOn event in the sequence. Can be used to skip the initial silence.
console.log(parsedMIDI.firstNoteOn); // 1294
The sequence's duration in seconds.
console.log(parsedMIDI.duration); // 125.64;
The detected midi ports for each track. Each port represents a batch of 16 channels.
console.log(parsedMIDI.midiPorts); // [0, 0, 0, 1, 1, 2, ...]
The channel offsets for each MIDI port, using the SpessaSynth method
console.log(parsedMIDI.midiPortChannelOffsets); // [16, 0, 48, 32, ...]
All the channels that each track refers to. An array of Set
s.
console.log(parsedMIDI.usedChannelsOnTrack) // [ Set[0, 1, 2, 3, 4] ] - this sequence has 1 track which plays on channels 0, 1, 2, 3 and 4
The key range of the sequence. The lowest pressed key and highest.
console.log(parsedMIDI.keyRange); // {min: 0, max: 127}
The detected lyrics, stored as binary text data, as MIDIs can use different encodings.
Stored as an array of Uint8Array
s, each is a single lyrics event.
Tip
See Official SF2 RMIDI Specification for more info.
An ArrayBuffer
representation of the embedded soundfont in an RMID file. If no soundfont or not RMID, undefined.
This can be either SoundFont binary or DLS binary.
Warning
If the embedded soundfont is defined, Sequencer
will automatically pass it to the synthesizer.
If you want to avoid this behavior, make sure you set it to undefined before passing the rmid file.
A number
representing the bank offset of the file. Only applies to RMID, for normal MIDIs it's set to 0.
An Object
representing the INFO chunk of an RMID file. See this for more information.
The actual MIDI sequence data. Described below.
Calculates time in seconds given the MIDI ticks.
MIDIticksToSeconds(ticks, midi);
- ticks -
number
- the time in MIDI ticks. - midi -
MIDI
- the MIDI sequence to calculate the time with.
The returned value is the time in seconds from the start of the MIDI to the given tick.
Renders the sequence as a .mid file. More info
writeMIDIFile(midi);
- midi - the
MIDI
instance to export.
The returned value is an Uint8Array
- a binary representation of the .mid file.
The file is stored as an array of tracks, accesible via parsedMIDI.tracks
.
Each track is an array of events.
Each event is a MidiMessage
class, which is defined as follows;
class MidiMessage
{
/**
* absolute amount of MIDI Ticks from the start of the track
* @type {number}
*/
ticks;
/**
* the status byte of the message as a number from 0 to 255
* @type {number}
*/
messageStatusByte;
/**
* @type {IndexedByteArray}
*/
messageData;
}
- ticks - absolute amount of MIDI Ticks from the start of the track.
- messageStatusByte - the status byte of the message as a number from 0 to 255. Learn more here and here.
Important
Note that for Meta Events, the status byte is the SECOND status byte, not the 0xFF!
- messageData - a
IndexedByteArray
(Pretty much exactly the same asUint8Array
) instance of the event's binary data.
For a real word use-case, see how renderer calculates note times from the MIDI file.
Tip
If you encounter any errors in this documentation, please open an issue!
Warning
Make sure you always update worklet_processor.min.js
along with the npm package!