@pioug/MidiConvert

3.0.0-beta.9 • Public • Published

MidiConvert Build Status Coverage Status

This is a fork of Tonejs/MidiConvert. The fork has diverged since by including directly the parser of NHQ/midi-file-parser and adding the following features:

  • Generate MIDI file by including functions from dingram/jsmidgen
  • Output sustain pedal events
  • Output instruments used in tracks
  • Splitting tracks by MIDI Channel of MIDI Type 0 file

The toolchain is also different:

  • Bundling with Rollup
  • Minification with Clojure compiler
  • Code linting with ESLint
  • Continuous integration with Travis CI

Read more about the changes in the CHANGELOG.md.

Usage

This library can be installed via NPM:

npm i --save @pioug/MidiConvert

In HTML:

<script src="build/MidiConvert.js"></script>

Or in JavaScript:

var MidiConvert = require('@pioug/MidiConvert');

API

MidiConvert.parse(BinaryString midiBlob, [Object options]) => Object

This function returns an object with two properties:

  • transport: the bpm and time signature values of the midi file as a Javascript Object (formerly parseTransport)
  • parts: an array of the tracks. Each track is an array of notes (formerly parseParts)
var midiObject = MidiConvert.parse(midiBlob, options);
{
  transport: {
    bpm: 120,
    instruments: [1, 25, 0],
    timeSignature: [4, 4],
    trackNames: ["Solo piano", "Guitar riff", "Kick-ass drums"]
  },
  parts: [
    [
      {
        time: "0i",
        midiNote: 67,
        noteName: "G4",
        velocity: 0.7086614173228346,
        duration: "12i"
      },
      ... rest of events
    ],
    ... rest of tracks
  ]
}

Which can then be used in Tone.Part:

var pianoPart = new Tone.Part(callback, midiObject.parts[0]).start();

Options

The options object defines how the MIDI file is parsed:

MidiConvert.parse(midiBlob, {
  /*
   *  the pulses per quarter note at which
   *  the midi file is parsed.
   */
  PPQ : 192,
  /*
   *  if the notes scientific pitch notation
   *  should be included in the output.
   */
  noteName : true,
  /*
   *  if the normalized velocity should be included
   *  in the output
   */
  velocity : true,
  /*
   *  if the time between the noteOn and noteOff event
   *  should be included in the output. Otherwise
   *  each event represents a noteOn.
   */
  duration : true,
  /*
   *  execute an additional sorting function
   *  useful for testing
   */
   deterministic: true
});

MidiConvert.generate(midiJson) => Buffer

Generate a file buffer from an object respecting the structure of the parse output.

var sourceFile = fs.readFileSync('./midi/bwv-846.mid', 'binary'),
  sourceData = MidiConvert.parse(sourceFile, midiConvertOpts),
  destinationData = MidiConvert.parse(MidiConvert.generate(sourceData), midiConvertOpts);
t.deepEqual(sourceData, destinationData) // TRUE;

Class MidiConvert.File

  • addTrack() - Add a new Track object to the file and return the new track
  • addTrack(track) - Add the given Track object to the file and return the file
  • toBytes() - Convert to buffer

Class MidiConvert.Track

Time and duration are specified in "ticks", and there is a hardcoded value of 128 ticks per beat. This means that a quarter note has a duration of 128.

Pitch can be specified by note name with octave (a#4) or by note number (60). Middle C is represented as c4 or 60.

  • addNote(channel, pitch, duration[, time[, velocity]])

    • Add a new note with the given channel, pitch, and duration
    • If time is given, delay that many ticks before starting the note
    • If velocity is given, strike the note with that velocity
  • addNoteOn(channel, pitch[, time[, velocity]]) -Start a new note with the given channel and pitch

    • If time is given, delay that many ticks before starting the note
    • If velocity is given, strike the note with that velocity
  • addNoteOff(channel, pitch[, time[, velocity]])

    • End a note with the given channel and pitch
    • If time is given, delay that many ticks before ending the note
    • If velocity is given, strike the note with that velocity
  • addChord(channel, chord[, velocity])

    • Add a chord with the given channel and pitches
    • Accepts an array of pitches to play as a chord
    • If velocity is given, strike the chord with that velocity
  • setInstrument(channel, instrument[, time])

    • Change the given channel to the given instrument
    • If time is given, delay that many ticks before making the change
  • setTempo(bpm[, time])

    • Set the tempo to bpm beats per minute
    • If time is given, delay that many ticks before making the change
  • setTimeSignature(numerator, denominator[, time])

    • Set the time signature with the given numerator and denominator
    • If time is given, delay that many ticks before making the change
  • setTrackName(name[, time])

    • Set the track name with the given string
    • If time is given, delay that many ticks before making the change
var fs = require('fs');
var MidiConvert = require('@pioug/MidiConvert');

var file = new MidiConvert.MidiGen.File();
var track = new MidiConvert.MidiGen.Track();
file.addTrack(track);

track.addNote(0, 'C4', 64);
track.addNote(0, 'D4', 64);
track.addNote(0, 'E4', 64);
track.addNote(0, 'F4', 64);
track.addNote(0, 'G4', 64);
track.addNote(0, 'A4', 64);
track.addNote(0, 'B4', 64);
track.addNote(0, 'B5', 64);

fs.writeFileSync('test.mid', file.toBytes(), 'binary');

MIDI Blob

In Node.js, pass to MidiConvert the output from fs.readFile:

fs.readFile('./test.mid', 'binary', function(err, buffer) {
  if (err) return;
  var midiObject = MidiConvert.parse(buffer);
});

In the browser, the MIDI blob as a string can be obtained using the FileReader API.

var reader = new FileReader();
reader.onload = function(e) {
  var midiObject = MidiConvert.parse(e.target.result);
}
reader.readAsBinaryString(file);

Development

If you want to contribute to this project:

git clone git@github.com:pioug/MidiConvert.git
npm i
npm run build
npm test

Readme

Keywords

none

Package Sidebar

Install

npm i @pioug/MidiConvert

Weekly Downloads

2

Version

3.0.0-beta.9

License

MIT

Last publish

Collaborators

  • pioug