@perry-rylance/midi
v1.2.2
Published
TypeScript library for parsing, building, serializing and debugging MIDI.
Downloads
712
Maintainers
Readme
@perry-rylance/midi
TypeScript library for parsing, building, serializing and debugging MIDI.
There are many JS / TS MIDI parsers online, this library is unique in that not only parses MIDI, it also allows you to construct MIDI from scratch, or alter existing MIDI, in a type-safe and strict fashion. This library will let you programatically build MIDI files and guide you along the way without allowing you to write invalid data. Almost no knowledge of the MIDI spec is required, simply install and start using the library.
Examples
- The Microtonal cyclic polyrhythm generator demonstrates generating MIDI and extending this libraries modules.
Usage
Reading MIDI data
- Get your data into an
ArrayBuffer - Instantiate a
new ReadStreamwith yourArrayBuffer - Instantiate a
new File - Call
readBytespassing in yourReadStream
Creating MIDI data
- Instantiate a
new File - Instantiate a
new Trackand push it to your filestracks - Instantiate any subclasses of
Eventyou need, egNoteOnEvent - Push your events to the tracks
events
For more advanced usage, see the fluent documentation below.
Writing MIDI data
- You'll need a
Fileeither read in or created from scratch as described above - Instantiate a
new WriteStream - Call
writeByteson yourFilepassing in yourWriteStream - You can use
toArrayBufferfrom theWriteStreamthen do whatever you need toDataUrlis also provided for convenience
Automatic end of track handling
Most MIDI players and parsers expect each track to end with an "end of track" event.
By default, when writing, File will call fixEndOfTrack on each track before writing. This strips out any existing EndOfTrackEvents and adds one on the end, preserving delta.
If you need to disable this behaviour, you can pass { autoEndOfTrackEvents: false } to writeBytes.
Version overview
1.2.*
A new fluent API has been added to allow easier composition with less boilerplate. Full compatibility with earlier versions is maintained.
new File()
.tracks([
new Track()
.events([
new TrackNameEvent()
.text("Bass"),
new ProgramChangeEvent()
.program(ProgramType.SLAP_BASS_1),
new NoteOnEvent()
.key(48),
new NoteOffEvent()
.delta(960)
.key(48)
])
])
.toArrayBuffer();If you need to inspect an item using your stepping debugger you can use probe():
new File()
.tracks([
new Track()
.events([
new TrackNameEvent().text("Inspect me")
])
.probe()
]);You can also call probe() conditionally:
new File()
.tracks([
"Lead",
"Bass",
"Percussion"
].map(name => new Track()
.events([
new TrackNameEvent().text(name)
])
.probe(name == "Lead")
));See Fluent.test.ts for very basic examples.
1.1.*
This library was originally conceived to work purely with files and not with real-time streams. 1.1.0 introduces some changes that make working with real-time streams easier. MIDI delta time is a concept that relates strictly to files with tracks, as opposed to real-time streams do not use delta time on events at all - we simply need to send events down the stream and timing is left entirely up to the device sending.
With that in mind, 1.1.0 introduces some changes to the internal implementation of how streams read and write events. Delta time is now read and written by the track, during read operations this is then passed down to the event factory. This means that we can now work with pure events in the context of a stream without having to worry about workarounds to remove delta time.
This should not break any projects that use this library, but may break projects that extend our classes or depend on the implementation handling delta time at an event level.
1.0.*
Initial release.
Development
Clone this repository and run npm install.
Run npm run dev during development to see TypeScript errors.
Testing
Run npm run test to run the entire test suite.
To run individual tests, run npm run test -- -i ./tests/FileLibrary.test.ts -t "Reads tests\\files\\test-illegal-message-fe.mid" replacing the argument for -t with the name of the test you wish to run.
Credits
- With thanks to Recording Blogs, Teragon Audio and Mido for insight into the MIDI spec.
- With thanks to jazz-soft for the test files.
