3.1.1 • Published 7 months ago

midi-writer-js v3.1.1

Weekly downloads
244
License
MIT
Repository
github
Last release
7 months ago

MidiWriterJS

npm version Tests Lint Try midi-writer-js on RunKit

MidiWriterJS is a JavaScript library providing an API for generating expressive multi-track MIDI files.

Note that the master branch is in active development so if you're looking for a tried and true stable version please use the latest release.

Source Documentation

Install

npm install midi-writer-js

Getting Started

import MidiWriter from 'midi-writer-js';

// Start with a new track
const track = new MidiWriter.Track();

// Define an instrument (optional):
track.addEvent(new MidiWriter.ProgramChangeEvent({instrument: 1}));

// Add some notes:
const note = new MidiWriter.NoteEvent({pitch: ['C4', 'D4', 'E4'], duration: '4'});
track.addEvent(note);

// Generate a data URI
const write = new MidiWriter.Writer(track);
console.log(write.dataUri());

Documentation

MidiWriter.Track()

  • addEvent({event}, mapFunction)
  • setTempo(tempo)
  • addText(text)
  • addCopyright(text)
  • addTrackName(text)
  • addInstrumentName(text)
  • addMarker(text)
  • addCuePoint(text)
  • addLyric(text)
  • setTimeSignature(numerator, denominator)

MidiWriter.NoteEvent({options})

The MIDI spec defines that each note must have a NoteOnEvent and NoteOffEvent (or NoteOnEvent with zero velocity) event, marking the beginning and end of the sounding note. While it's possible to manually add these events to a track with Track.addEvent(), the NoteEvent provides a more intuitive interface for doing this with a single, "pseudo" event. Under the hood, the NoteEvent event generates the relevant NoteOnEvent and NoteOffEvent events.

Each MIDI event has a delta property, which is used to define the number of ticks to wait after the previous event. This can be challenging to calculate if you're not necessarily adding events in a serial fashion. Because of this, you can alternatively use the tick property to define the exact tick where the event should fall.

The NoteEvent supports these options:

MidiWriter.Writer(tracks)

The Writer class provides a few ways to output the file:

  • buildFile() Uint8Array
  • base64() string
  • dataUri() string
  • stdout() file stream (cli)

Hot Cross Buns

Here's an example of how everyone's favorite song "Hot Cross Buns" could be written. Note use of the mapping function passed as the second argument of addEvent(). This can be used to apply specific properties to all events. With some street smarts you could also use it for programmatic crescendos and other property 'animation'.

import MidiWriter from 'midi-writer-js';

const track = new MidiWriter.Track();

track.addEvent([
		new MidiWriter.NoteEvent({pitch: ['E4','D4'], duration: '4'}),
		new MidiWriter.NoteEvent({pitch: ['C4'], duration: '2'}),
		new MidiWriter.NoteEvent({pitch: ['E4','D4'], duration: '4'}),
		new MidiWriter.NoteEvent({pitch: ['C4'], duration: '2'}),
		new MidiWriter.NoteEvent({pitch: ['C4', 'C4', 'C4', 'C4', 'D4', 'D4', 'D4', 'D4'], duration: '8'}),
		new MidiWriter.NoteEvent({pitch: ['E4','D4'], duration: '4'}),
		new MidiWriter.NoteEvent({pitch: ['C4'], duration: '2'})
	], function(event, index) {
    return {sequential: true};
  }
);

const write = new MidiWriter.Writer(track);
console.log(write.dataUri());

VexFlow Integration

MidiWriterJS can export MIDI from VexFlow voices, though this feature is still experimental. Current usage is to use MidiWriter.VexFlow.trackFromVoice(voice) to create a MidiWriterJS Track object:

// ...VexFlow code defining notes
const voice = create_4_4_voice().addTickables(notes);

const vexWriter = new MidiWriter.VexFlow();
const track = vexWriter.trackFromVoice(voice);
const writer = new MidiWriter.Writer([track]);
console.log(writer.dataUri());

Demos

3.1.1

7 months ago

3.0.2

7 months ago

3.1.0

7 months ago

3.0.1

8 months ago

3.0.0

8 months ago

2.1.2

1 year ago

2.1.1

1 year ago

2.1.4

1 year ago

2.1.3

1 year ago

2.0.2

2 years ago

2.1.0

2 years ago

2.0.1

3 years ago

2.0.0

3 years ago

1.7.5

3 years ago

1.7.4

4 years ago

1.7.3

4 years ago

1.7.2

4 years ago

1.7.1

5 years ago

1.7.0

5 years ago

1.6.0

5 years ago

1.5.2

6 years ago

1.5.1

7 years ago

1.5.0

7 years ago

1.4.9

7 years ago

1.4.8

7 years ago

1.4.7

7 years ago

1.4.6

7 years ago

1.4.5

7 years ago

1.4.4

7 years ago

1.4.3

7 years ago

1.4.2

7 years ago

1.4.1

7 years ago

1.4.0

8 years ago

1.3.2

8 years ago

1.3.1

8 years ago

1.2.1

8 years ago

1.2.0

8 years ago

1.1.0

8 years ago

1.0.0

8 years ago