jsmidgen

repository·main·Indexed 42 days ago

https://github.com/dingram/jsmidgen

A pure-JavaScript MIDI file generator (v0.1.8) that allows developers to programmatically construct MIDI tracks, notes, chords, and musical settings. It features a fluid API for chained generation and provides classes for managing MIDI files and tracks, including serialization to bytes, Uint8Array, or Blob.

Tokens
2.8K
Snippets
9
Records
11
Agent score
4%

What's inside jsmidgen

  1. Generate a MIDI file with jsmidgen

    main

    To generate a MIDI file, create a Midi.File instance, add one or more Midi.Track objects to it, and populate the tracks with musical events (notes, instrument changes, tempo, etc.). Finally, use toBytes() or toUint8Array() to serialize the file for saving or transmission.

    Note that time and duration are measured in "ticks". The library uses a hardcoded value of 128 ticks per beat (e.g., a quarter note has a duration of 128).

    var fs = require('fs');
    var Midi = require('jsmidgen');
    
    var file = new Midi.File();
    var track = new Midi.Track();
    file.addTrack(track);
    
    track.addNote(0, 'c4', 64);
    
    fs.writeFileSync('test.mid', file.toBytes(), 'binary');
  2. Use the fluid API for chained MIDI generation

    main

    The library supports a fluid (chained) API, allowing you to build tracks and sequences in a single continuous statement. This is useful for concise musical definitions.

    Key aliases available in the fluid API:

    • note() is an alias for addNote()
    • instrument() is an alias for setInstrument()
    • noteOn() is an alias for addNoteOn()
    • noteOff() is an alias for addNoteOff()
    var fs = require('fs');
    var Midi = require('jsmidgen');
    
    var file = new Midi.File();
    file
      .addTrack()
        .note(0, 'c4', 32)
        .note(0, 'd4', 32)
        .instrument(0, 19)
        .addChord(0, ['c4', 'e4', 'g4'], 64)
        .noteOn(0, 'c4', 1)
        .noteOff(0, 'c4', 384);
    
    fs.writeFileSync('test2.mid', file.toBytes(), 'binary');
  3. Midi.Track API Reference

    main

    The Midi.Track class contains the musical events. Pitch can be specified by note name with octave (e.g., a#4, c4) or by note number (e.g., 60). Middle C is c4 or 60.

    Note Events

    • addNote(channel, pitch, duration[, time[, velocity]]): Adds a note. If time is provided, it acts as a delay (rest). If velocity is provided, it sets the strike strength.
    • addNoteOn(channel, pitch[, time[, velocity]]): Starts a note. Alias: noteOn().
    • addNoteOff(channel, pitch[, time[, velocity]]): Ends a note. Alias: noteOff().
    • addChord(channel, chord[, velocity]): Plays an array of pitches as a chord.

    Musical Settings

    • setInstrument(channel, instrument[, time]): Changes the instrument for a channel (0-indexed). Alias: instrument().
    • setTempo(bpm[, time]): Sets the tempo in beats per minute.
    • setTimeSignature(numerator, denominator[, time]): Sets the time signature. The denominator must be a power of 2 (1, 2, 4, 8, 16, 32).
    • setKeySignature(accidentals[, minor[, time]]): Sets the key signature. accidentals is positive for sharps and negative for flats. minor is a boolean.
  4. Midi.File API Reference

    main

    The Midi.File class manages the overall MIDI file structure and serialization.

    MethodDescription
    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()Serialize the file to an array of bytes.
    toUint8Array()Serialize the file to a Uint8Array.
    toBlob([genericType])Serialize the file to a Blob. If genericType is true, uses application/octet-stream; otherwise uses audio/x-midi.
  5. Create a MIDI file with Midi.File

    main

    Use the Midi.File class to represent a complete MIDI file. You can specify the ticks (ticks per beat, default 128) and provide an array of Midi.Track objects. The class provides methods to serialize the file into various formats like a byte array, Uint8Array, or a Blob for browser use.

    const midiFile = new Midi.File({ ticks: 480 });
    const track = new Midi.Track();
    
    // Add content to track...
    
    midiFile.addTrack(track);
    
    // Export to different formats
    const bytes = midiFile.toBytes();
    const uint8 = midiFile.toUint8Array();
    const blob = midiFile.toBlob(); // Returns audio/x-midi
  6. Manage MIDI tracks with Midi.Track

    main

    The Midi.Track class is used to compose sequences of MIDI events. It supports a fluid API for adding notes, chords, and meta-events (like tempo or time signature).

    const track = new Midi.Track();
    
    // Add a single note (channel, pitch, duration, time, velocity)
    // Pitch can be a number (60) or a string ("c4")
    track.addNote(0, "c4", 128, 0, 90);
    
    // Add a chord (channel, array of pitches, duration, velocity)
    track.addChord(0, ["e4", "g4", "c5"], 256, 100);
    
    // Set track metadata
    track.setTempo(120, 0);
    track.setInstrument(0, 1, 0); // Set instrument on channel 0
    
    // Add manual events
    track.addEvent(new Midi.MidiEvent({ type: Midi.MidiEvent.NOTE_ON, channel: 0, param1: 60, time: 0 }));
  7. Add notes and chords to a track

    main

    The Midi.Track class provides high-level methods to add musical data:

    • addNote(channel, pitch, dur, time, velocity): Adds a NOTE_ON followed by a NOTE_OFF event. pitch can be a numeric MIDI pitch or a symbolic string (e.g., "c4").
    • addNoteOn(channel, pitch, time, velocity): Adds only a NOTE_ON event.
    • addNoteOff(channel, pitch, time, velocity): Adds only a NOTE_OFF event.
    • addChord(channel, chord, dur, velocity): Adds a sequence of NOTE_ON events for each pitch in the chord array, followed by NOTE_OFF events. The first note in the chord is held for the specified dur, while subsequent notes are released immediately to ensure the chord starts together.
    const track = new Midi.Track();
    
    // Using symbolic note names
    track.addNote(0, 'a4', 128, 0, 90);
    
    // Using numeric MIDI pitches
    track.addNote(0, 60, 128, 0, 90);
    
    // Adding a chord
    track.addChord(0, ['c4', 'e4', 'g4'], 256, 100);
  8. Set track metadata and time signatures

    main

    Use these methods on a Midi.Track instance to add MetaEvents that control the playback environment:

    • setTempo(bpm, time): Sets the beats per minute.
    • setTimeSignature(numerator, denominator, time): Sets the time signature. The denominator must be an exact power of 2.
    • setKeySignature(accidentals, minor, time): Sets the key signature. accidentals is the number of sharps (positive) or flats (negative). minor is a boolean.
    • setInstrument(channel, instrument, time): Sets the program change (instrument) for a specific channel.
    const track = new Midi.Track();
    
    track.setTempo(140, 0);
    track.setTimeSignature(4, 4, 0);
    track.setKeySignature(1, true, 0); // 1 sharp, minor key
    track.setInstrument(0, 1, 0);    // Channel 0, Instrument 1
  9. Convert between note names and MIDI pitches

    main

    The Midi.Util object provides helper functions for musical notation conversion:

    • midiPitchFromNote(n): Converts a symbolic note name (e.g., "c4", "f#3") to a numeric MIDI pitch.
    • noteFromMidiPitch(n, [returnFlattened]): Converts a numeric MIDI pitch to a symbolic note name. If returnFlattened is true, it prefers flats (e.g., "gb") over sharps (e.g., "f#").
    • ensureMidiPitch(p): A convenience function that accepts either a number or a note name string and always returns a numeric MIDI pitch.
    const Util = Midi.Util;
    
    // Note name to pitch
    const pitch = Util.midiPitchFromNote("c4"); // 60
    
    // Pitch to note name
    const note = Util.noteFromMidiPitch(60); // "c4"
    const flatNote = Util.noteFromMidiPitch(61, true); // "db4"
    
    // Flexible conversion
    const p1 = Util.ensureMidiPitch("a#4"); // 73
    const p2 = Util.ensureMidiPitch(73);      // 73
  10. Reference: MetaEvent type codes

    main

    These constants define the types of meta-events used in MetaEvent objects.

    MetaEvent.SEQUENCE        = 0x00;
    MetaEvent.TEXT            = 0x01;
    MetaEvent.COPYRIGHT       = 0x02;
    MetaEvent.TRACK_NAME      = 0x03;
    MetaEvent.INSTRUMENT      = 0x04;
    MetaEvent.LYRIC           = 0x05;
    MetaEvent.MARKER          = 0x06;
    MetaEvent.CUE_POINT       = 0x07;
    MetaEvent.CHANNEL_PREFIX   = 0x20;
    MetaEvent.END_OF_TRACK    = 0x2f;
    MetaEvent.TEMPO           = 0x51;
    MetaEvent.SMPTE           = 0x54;
    MetaEvent.TIME_SIG        = 0x58;
    MetaEvent.KEY_SIG         = 0x59;
    MetaEvent.SEQ_EVENT       = 0x7f;
  11. Reference: MidiEvent event codes

    main

    These constants define the type of MIDI channel messages used in MidiEvent objects.

    MidiEvent.NOTE_OFF           = 0x80;
    MidiEvent.NOTE_ON            = 0x90;
    MidiEvent.AFTER_TOUCH        = 0xA0;
    MidiEvent.CONTROLLER         = 0xB0;
    MidiEvent.PROGRAM_CHANGE     = 0xC0;
    MidiEvent.CHANNEL_AFTERTOUCH = 0xD0;
    MidiEvent.PITCH_BEND         = 0xE0;