### Quick Start: Create a MIDI Track Source: https://github.com/grimmdude/midiwriterjs/blob/master/llms.txt Basic example demonstrating how to create a track, add a note event, and build a MIDI file using MidiWriterJS. ```javascript import MidiWriter from 'midi-writer-js'; const track = new MidiWriter.Track(); track.addEvent(new MidiWriter.NoteEvent({pitch: ['C4', 'D4', 'E4'], duration: '4', sequential: true})); const writer = new MidiWriter.Writer(track); writer.buildFile(); // Uint8Array writer.base64(); // base64 string writer.dataUri(); // data URI for playback/download ``` -------------------------------- ### Quick Start: CommonJS Usage Source: https://github.com/grimmdude/midiwriterjs/blob/master/README.md Example demonstrating track creation and adding a note event using CommonJS syntax. Outputs a data URI. ```javascript const MidiWriter = require('midi-writer-js'); const track = new MidiWriter.Track(); track.addEvent(new MidiWriter.NoteEvent({pitch: ['C4', 'E4', 'G4'], duration: '2'})); const writer = new MidiWriter.Writer(track); console.log(writer.dataUri()); ``` -------------------------------- ### Quick Start: TypeScript Usage Source: https://github.com/grimmdude/midiwriterjs/blob/master/README.md Example demonstrating track creation and adding a note event using TypeScript syntax. Builds the MIDI file as a Uint8Array. ```typescript import MidiWriter from 'midi-writer-js'; const track = new MidiWriter.Track(); track.addEvent(new MidiWriter.NoteEvent({pitch: ['C4', 'E4', 'G4'], duration: '2'})); const writer = new MidiWriter.Writer(track); const data: Uint8Array = writer.buildFile(); ``` -------------------------------- ### Quick Start: ESM Usage Source: https://github.com/grimmdude/midiwriterjs/blob/master/README.md Example demonstrating basic track creation, adding a program change event for instrument selection, and a sequential note event using ESM syntax. Outputs a data URI. ```javascript import MidiWriter from 'midi-writer-js'; const track = new MidiWriter.Track(); track.addEvent(new MidiWriter.ProgramChangeEvent({instrument: 1})); track.addEvent(new MidiWriter.NoteEvent({pitch: ['C4', 'D4', 'E4'], duration: '4', sequential: true})); const writer = new MidiWriter.Writer(track); console.log(writer.dataUri()); ``` -------------------------------- ### Install MidiWriterJS Source: https://github.com/grimmdude/midiwriterjs/blob/master/llms.txt Install the MidiWriterJS library using npm. ```bash npm install midi-writer-js ``` -------------------------------- ### Track Constructor Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/api-reference/track.md Initializes a new, empty MIDI track with default settings. This is the starting point for building a track. ```APIDOC ## Constructor Track() ### Description Creates a new, empty track with default properties. ### Example ```javascript import MidiWriter from 'midi-writer-js'; const track = new MidiWriter.Track(); track.addEvent(new MidiWriter.NoteEvent({pitch: 'C4', duration: '4'})); ``` ``` -------------------------------- ### Initialize MidiWriter Writer with Options Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/INDEX.md Example of initializing a MidiWriter.Writer instance with custom configuration options for ticksPerBeat and middleC. This allows for fine-tuning the MIDI output precision and tuning. ```javascript const writer = new MidiWriter.Writer(track, { ticksPerBeat: 480, // High precision middleC: 'C4' // Standard tuning }); ``` -------------------------------- ### NoteEvent Usage Examples Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/api-reference/note-event.md Illustrates various ways to use the NoteEvent class, from single notes and chords to arpeggios, rests, dynamics, and multi-channel configurations. ```APIDOC ## NoteEvent Usage Examples This section provides practical examples of how to use the `NoteEvent` class to create different musical elements. ### Single Note Adds a single quarter note 'C4' to the track. ```javascript // Assuming 'track' is an instance of MidiWriter.Track track.addEvent(new MidiWriter.NoteEvent({pitch: 'C4', duration: '4'})); ``` ### Chord (Multiple Pitches, Simultaneous) Adds a C Major chord (C4, E4, G4) as a half note. ```javascript track.addEvent(new MidiWriter.NoteEvent({ pitch: ['C4', 'E4', 'G4'], duration: '2' })); ``` ### Arpeggio (Multiple Pitches, Sequential) Adds a C Major arpeggio (C4, E4, G4) where notes play sequentially as eighth notes. ```javascript track.addEvent(new MidiWriter.NoteEvent({ pitch: ['C4', 'E4', 'G4'], duration: '8', sequential: true })); ``` ### Note with Grace Note Adds a quarter note 'C5' with a grace note 'B4'. ```javascript track.addEvent(new MidiWriter.NoteEvent({ pitch: 'C5', duration: '4', grace: 'B4' })); ``` ### Rest (using wait) Adds a quarter rest followed by a quarter note 'C4'. ```javascript track.addEvent(new MidiWriter.NoteEvent({ pitch: 'C4', duration: '4', wait: '4' })); ``` Adds a half rest followed by a whole note 'E4'. ```javascript track.addEvent(new MidiWriter.NoteEvent({ pitch: 'E4', duration: '1', wait: '2' })); ``` ### Multiple Octaves Adds a sequence of notes across different octaves. ```javascript track.addEvent(new MidiWriter.NoteEvent({pitch: 'C3', duration: '4'})); track.addEvent(new MidiWriter.NoteEvent({pitch: 'C4', duration: '4'})); track.addEvent(new MidiWriter.NoteEvent({pitch: 'C5', duration: '4'})); ``` ### Using MIDI Numbers Adds a quarter note using MIDI number 60 (Middle C). ```javascript track.addEvent(new MidiWriter.NoteEvent({ pitch: 60, duration: '4' })); ``` Adds a chord using an array of MIDI numbers. ```javascript track.addEvent(new MidiWriter.NoteEvent({ pitch: [60, 64, 67], // C4, E4, G4 duration: '4' })); ``` ### Dynamics (Velocity) Adds a soft note with velocity 30. ```javascript track.addEvent(new MidiWriter.NoteEvent({ pitch: 'C4', duration: '4', velocity: 30 })); ``` Adds a loud note with velocity 100. ```javascript track.addEvent(new MidiWriter.NoteEvent({ pitch: 'E4', duration: '4', velocity: 100 })); ``` ### Repeat Plays the note 'C4' three times in succession with an eighth note duration. ```javascript track.addEvent(new MidiWriter.NoteEvent({ pitch: 'C4', duration: '8', repeat: 3 })); ``` ### Different Channels Adds a note to MIDI channel 1 (default). ```javascript track.addEvent(new MidiWriter.NoteEvent({ pitch: 'C4', duration: '4', channel: 1 })); ``` Adds a note to MIDI channel 10 (often used for drums). ```javascript track.addEvent(new MidiWriter.NoteEvent({ pitch: 'C2', // Kick drum duration: '4', channel: 10 })); ``` ### Explicit Tick Position Adds a note starting at tick 512, ignoring any 'wait' property. ```javascript track.addEvent(new MidiWriter.NoteEvent({ pitch: 'C4', duration: '4', tick: 512 })); ``` ### Combining Multiple Events with Map Function Adds multiple `NoteEvent` objects to the track, applying a velocity function to each. ```javascript track.addEvent([ new MidiWriter.NoteEvent({pitch: ['C4', 'E4', 'G4'], duration: '4'}), new MidiWriter.NoteEvent({pitch: ['D4', 'F4', 'A4'], duration: '4'}), new MidiWriter.NoteEvent({pitch: ['E4', 'G4', 'B4'], duration: '4'}) ], function(index, event) { return {velocity: 50 + (index * 15)}; }); ``` ``` -------------------------------- ### Set Tempo using Track Helper or Directly Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/api-reference/meta-events.md Demonstrates setting the MIDI tempo using the Track helper method or by directly adding a TempoEvent. Includes an example of changing tempo mid-track. ```javascript track.setTempo(120); // 120 BPM (via Track helper) // or directly: track.addEvent(new MidiWriter.TempoEvent({bpm: 120})); // Change tempo mid-track track.addEvent(new MidiWriter.TempoEvent({bpm: 80, tick: 512})); ``` -------------------------------- ### MidiWriterJS Error Handling Example Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/errors.md Illustrates robust error handling for MIDI generation, including validating note velocity and duration, and catching potential errors during track and writer setup. Requires importing MidiWriter. ```javascript import MidiWriter from 'midi-writer-js'; try { // Create track const track = new MidiWriter.Track(); track.setTempo(120); // Validate and add notes const noteData = {pitch: 'C4', duration: '4', velocity: 50}; // Check velocity if (noteData.velocity < 1 || noteData.velocity > 100) { throw new Error(`Invalid velocity: ${noteData.velocity}`); } // Check duration try { MidiWriter.Utils.getTickDuration(noteData.duration); } catch (e) { throw new Error(`Invalid duration: ${noteData.duration}`); } track.addEvent(new MidiWriter.NoteEvent(noteData)); // Create writer const writer = new MidiWriter.Writer(track, {ticksPerBeat: 128}); const midiBytes = writer.buildFile(); } catch (error) { console.error('MIDI generation error:', error.message); } ``` -------------------------------- ### Default Writer Configuration Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/configuration.md Example of creating a MidiWriter with default configuration (ticksPerBeat: 128, middleC: 'C4'). ```javascript import MidiWriter from 'midi-writer-js'; const track = new MidiWriter.Track(); track.addEvent(new MidiWriter.NoteEvent({pitch: 'C4', duration: '4'})); const writer = new MidiWriter.Writer(track); // Uses: ticksPerBeat=128, middleC='C4' const midiBytes = writer.buildFile(); ``` -------------------------------- ### Melody Example (Hot Cross Buns) Source: https://github.com/grimmdude/midiwriterjs/blob/master/README.md Generates a MIDI track for the 'Hot Cross Buns' melody. Ensure MidiWriterJS is imported before use. ```javascript 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 writer = new MidiWriter.Writer(track); console.log(writer.dataUri()); ``` -------------------------------- ### Initialize VexFlow Integration Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/api-reference/vexflow.md Create a new VexFlow instance for converting VexFlow notation to MidiWriterJS tracks. This is the starting point for using the VexFlow integration. ```javascript import MidiWriter from 'midi-writer-js'; const vexWriter = new MidiWriter.VexFlow(); ``` -------------------------------- ### Markdown Table Example Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/README.md Illustrates the structure of parameter tables used in the documentation. These tables define arguments, types, requirements, defaults, and descriptions for various functions and options. ```markdown | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | pitch | string \| number \| array | Yes | — | Note pitch (C4, 60, ['C4', 'E4']) | | duration | string \| array | No | '4' | Note length (4=quarter, d4=dotted) | | velocity | number | No | 50 | Loudness (1-100) | ``` -------------------------------- ### Complete MIDI File Creation and Saving Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/INDEX.md This snippet shows how to create a MIDI track, add notes and metadata, and then generate a MIDI file. It includes examples for saving the file in both Node.js and browser environments. ```javascript import MidiWriter from 'midi-writer-js'; // Create a track const track = new MidiWriter.Track(); // Add metadata track.addTrackName('My Song'); track.setTempo(120); // Add notes track.addEvent([ new MidiWriter.NoteEvent({pitch: 'C4', duration: '4'}) new MidiWriter.NoteEvent({pitch: 'D4', duration: '4'}) new MidiWriter.NoteEvent({pitch: 'E4', duration: '4'}) new MidiWriter.NoteEvent({pitch: 'F4', duration: '4'}) ]); // Generate MIDI file const writer = new MidiWriter.Writer(track); const midiBytes = writer.buildFile(); // In Node.js: save to file import fs from 'fs'; fs.writeFileSync('output.mid', midiBytes); // In browser: create download link const uri = writer.dataUri(); const link = document.createElement('a'); link.href = uri; link.download = 'output.mid'; link.click(); ``` -------------------------------- ### version() Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/api-reference/utils.md Gets the MidiWriterJS version number. ```APIDOC ## version() ### Description Gets the MidiWriterJS version number. ### Method static version() ### Returns `string` — Version string (e.g., "3.2.0") ### Example ```javascript import MidiWriter from 'midi-writer-js'; console.log(MidiWriter.Utils.version()); // "3.2.0" ``` ``` -------------------------------- ### Create a new Track Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/api-reference/track.md Instantiate a new Track object to begin building a MIDI track. This is the starting point for adding events and configuring track properties. ```typescript constructor() ``` -------------------------------- ### Build MIDI with Empty Track Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/errors.md When building a MIDI file with a track that has no events added, the library will create a valid but silent MIDI file. This example shows the code structure for such a scenario. ```javascript const track = new MidiWriter.Track(); // No events added const writer = new MidiWriter.Writer(track); const bytes = writer.buildFile(); // Valid MIDI file with no notes ``` -------------------------------- ### Create and Save MIDI File (Node.js) Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/INDEX.md Use this snippet to create a simple MIDI file with a single track and save it to disk using Node.js's file system module. Ensure you have the 'midi-writer-js' package installed. ```javascript import MidiWriter from 'midi-writer-js'; import fs from 'fs'; const track = new MidiWriter.Track(); track.addEvent(new MidiWriter.NoteEvent({pitch: 'C4', duration: '4'})); const writer = new MidiWriter.Writer(track); fs.writeFileSync('output.mid', writer.buildFile()); ``` -------------------------------- ### Create a Drum Track (Channel 10) Source: https://github.com/grimmdude/midiwriterjs/blob/master/README.md MIDI channel 10 is reserved for percussion. Map pitch values to specific drum sounds. This example adds a kick, snare, and hi-hat. ```javascript const drums = new MidiWriter.Track(); drums.addTrackName('Drums'); drums.addEvent(new MidiWriter.NoteEvent({pitch: ['C2'], duration: '4', channel: 10, velocity: 80})); drums.addEvent(new MidiWriter.NoteEvent({pitch: ['D2'], duration: '4', channel: 10, velocity: 80})); drums.addEvent(new MidiWriter.NoteEvent({pitch: ['F#2'], duration: '8', channel: 10, repeat: 4})); ``` -------------------------------- ### Combine Multiple Events with a Map Function Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/api-reference/note-event.md Add multiple NoteEvents at once and modify them using a callback function. This example applies varying velocities to a sequence of chords. ```javascript track.addEvent([ new MidiWriter.NoteEvent({pitch: ['C4', 'E4', 'G4'], duration: '4'}), new MidiWriter.NoteEvent({pitch: ['D4', 'F4', 'A4'], duration: '4'}), new MidiWriter.NoteEvent({pitch: ['E4', 'G4', 'B4'], duration: '4'}) ], function(index, event) { return {velocity: 50 + (index * 15)}; }); ``` -------------------------------- ### NoteEvent Constructor Parameters Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/api-reference/note-event.md Defines the parameters available for the NoteEvent constructor, including pitch, duration, wait, velocity, channel, repeat, grace, sequential playback, and start tick. ```typescript constructor(fields: { pitch: string | number | (string | number)[], duration?: string | string[] | number, wait?: string | number | (string | number)[], velocity?: number, channel?: number, repeat?: number, grace?: string | string[], sequential?: boolean, startTick?: number, tick?: number }) ``` -------------------------------- ### Demonstrate Invalid Pitch String Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/errors.md Shows an example of an invalid pitch string that cannot be parsed by the library's pitch validation, resulting in an undefined return value. This underscores the importance of using standard musical notation for pitches. ```javascript // Invalid: 'H' is not a valid note name (not in English notation) MidiWriter.Utils.getPitch('H4'); // Returns undefined or error ``` -------------------------------- ### Get MidiWriterJS Version Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/api-reference/utils.md Retrieves the current version of the MidiWriterJS library. ```javascript import MidiWriter from 'midi-writer-js'; console.log(MidiWriter.Utils.version()); // "3.2.0" ``` -------------------------------- ### Create an Arpeggio (Sequential Pitches) Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/api-reference/note-event.md Create an arpeggio by setting the 'sequential' property to true. Notes will play one after another. ```javascript // C Major arpeggio (notes play one after another) track.addEvent(new MidiWriter.NoteEvent({ pitch: ['C4', 'E4', 'G4'], duration: '8', sequential: true })); ``` -------------------------------- ### Importing midi-writer-js Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/INDEX.md Demonstrates how to import the midi-writer-js library in different module systems (ESM, CommonJS) and for browser environments. ```APIDOC ## Importing midi-writer-js ### Description Shows how to import the library using ESM, CommonJS, or a browser script tag. ### Method ```typescript // ESM (recommended) import MidiWriter from 'midi-writer-js'; // CommonJS const MidiWriter = require('midi-writer-js'); // Browser (UMD) ``` ### Main Export Object The default export is an object containing all public classes and utilities: ```typescript { // Core classes Track, Writer, NoteEvent, // MIDI events NoteOnEvent, NoteOffEvent, ProgramChangeEvent, ControllerChangeEvent, PitchBendEvent, // Meta events TempoEvent, TimeSignatureEvent, KeySignatureEvent, TextEvent, TrackNameEvent, CopyrightEvent, InstrumentNameEvent, MarkerEvent, CuePointEvent, LyricEvent, EndTrackEvent, // Utilities Utils, VexFlow, Constants } ``` ``` -------------------------------- ### Chords vs. Sequential Notes Source: https://github.com/grimmdude/midiwriterjs/blob/master/README.md Demonstrates how to play notes simultaneously as a chord or sequentially as an arpeggio. The `sequential: true` option is key for arpeggios. ```javascript // Chord (notes play simultaneously) track.addEvent(new MidiWriter.NoteEvent({pitch: ['C4', 'E4', 'G4'], duration: '1'})); // Arpeggio (notes play sequentially) track.addEvent(new MidiWriter.NoteEvent({pitch: ['C4', 'E4', 'G4'], duration: '8', sequential: true})); ``` -------------------------------- ### Get Duration Multiplier Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/api-reference/utils.md Retrieves the fractional multiplier of a duration relative to a quarter note. Useful for internal duration calculations. ```javascript Utils.getDurationMultiplier('4'); // 1 (quarter = baseline) Utils.getDurationMultiplier('2'); // 2 (half = 2 quarters) Utils.getDurationMultiplier('8'); // 0.5 (eighth = 0.5 quarters) Utils.getDurationMultiplier('d4'); // 1.5 (dotted quarter) Utils.getDurationMultiplier('4t'); // 0.667 (triplet quarter) ``` -------------------------------- ### Create an Arpeggio (Sequential Playback) Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/INDEX.md This snippet shows how to create an arpeggio by setting the 'sequential' option to true. Each note in the pitch array will play one after another. ```javascript track.addEvent(new MidiWriter.NoteEvent({ pitch: ['C4', 'E4', 'G4'], duration: '8', sequential: true // Play one at a time })); ``` -------------------------------- ### Configure Writer with Standard Middle C Reference Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/configuration.md Initialize the writer with the default middle C reference ('C4'), ensuring standard MIDI pitch calculations. ```javascript // Standard tuning (note names interpreted as 4-based octaves) const writer = new MidiWriter.Writer(track, { middleC: 'C4' }); track.addEvent(new MidiWriter.NoteEvent({pitch: 'C4', duration: '4'})); // MIDI 60 ``` -------------------------------- ### Add NoteOnEvent to Track Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/api-reference/midi-events.md Example of adding a NoteOnEvent to a MIDI track using MidiWriterJS. This demonstrates setting the pitch, velocity, and channel for the event. ```javascript track.addEvent(new MidiWriter.NoteOnEvent({ pitch: 'C4', velocity: 64, channel: 1 })); ``` -------------------------------- ### Set Explicit Tick Position Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/api-reference/note-event.md Control the exact start time of a note by setting the 'tick' property. The 'wait' property is ignored when 'tick' is specified. ```javascript // Note starts at tick 512, wait is ignored track.addEvent(new MidiWriter.NoteEvent({ pitch: 'C4', duration: '4', tick: 512 })); ``` -------------------------------- ### Initialize Writer with Options Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/configuration.md Configure writer behavior by passing options to the constructor. Options can control timing resolution and pitch references. ```typescript const writer = new MidiWriter.Writer(tracks, { ticksPerBeat: 128, middleC: 'C4' }); ``` -------------------------------- ### buildFile() Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/api-reference/writer.md Builds the complete MIDI file and returns it as a Uint8Array. This is the primary method for obtaining the raw binary data of the MIDI file, suitable for saving to a file or further processing. ```APIDOC ## buildFile() ### Description Builds the complete MIDI file as a byte array. This method is used to get the raw binary data of the MIDI file, which can then be saved to a file or used in other applications. ### Method ``` buildFile(): Uint8Array ``` ### Returns `Uint8Array` — Binary MIDI file data ### Example ```javascript import MidiWriter from 'midi-writer-js'; const track = new MidiWriter.Track(); track.addEvent(new MidiWriter.NoteEvent({pitch: 'C4', duration: '4'})); const writer = new MidiWriter.Writer(track); const midiBytes = writer.buildFile(); // In Node.js, save to file import fs from 'fs'; fs.writeFileSync('output.mid', midiBytes); ``` ``` -------------------------------- ### WriterOptions Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/types.md Options for configuring the MIDI writer instance. ```APIDOC ## WriterOptions Constructor options for `Writer`. | Property | Type | Default | Description | |----------|------|---------|-------------| | ticksPerBeat | number | 128 | Ticks per quarter note (PPQN) | | middleC | string | 'C4' | Reference pitch for note conversion | ``` -------------------------------- ### Add ProgramChangeEvent to Track Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/api-reference/midi-events.md Add a ProgramChangeEvent to a MIDI track to change the instrument. Examples show changing to piano, violin, and setting drums on a specific channel. ```javascript // Change to piano (instrument 0) track.addEvent(new MidiWriter.ProgramChangeEvent({instrument: 0, channel: 1})); ``` ```javascript // Change to violin (instrument 40) track.addEvent(new MidiWriter.ProgramChangeEvent({instrument: 40})); ``` ```javascript // Drums on channel 10 track.addEvent(new MidiWriter.ProgramChangeEvent({instrument: 0, channel: 10})); ``` -------------------------------- ### Constructor Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/api-reference/writer.md Initializes a new Writer instance with one or more tracks and optional configuration. The `tracks` parameter can be a single Track object or an array of Track objects. The `options` object allows customization of `ticksPerBeat` for timing precision and `middleC` for pitch reference. ```APIDOC ## Constructor ### Description Initializes a new Writer instance with one or more tracks and optional configuration. The `tracks` parameter can be a single Track object or an array of Track objects. The `options` object allows customization of `ticksPerBeat` for timing precision and `middleC` for pitch reference. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table | Parameter | Type | Required | Default | Description | |---|---|---|---|---| | tracks | Track | Track[] | Yes | A single Track or array of Track objects to include in the MIDI file | | options | object | No | {} | Configuration object | | options.ticksPerBeat | number | No | 128 | Ticks per quarter note (PPQN). Controls timing precision. Common values: 24, 96, 128, 480 | | options.middleC | string | No | 'C4' | Reference pitch for note conversion. Allows shifting MIDI pitch references | ``` -------------------------------- ### Build MIDI File from Track Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/INDEX.md Create a Writer instance with one or more tracks and then build the MIDI file. The Writer can output raw bytes, a Base64 string, or a data URI. ```typescript const writer = new MidiWriter.Writer(track); const midiBytes = writer.buildFile(); ``` -------------------------------- ### VexFlow Constructor Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/api-reference/vexflow.md Initializes a new VexFlow instance for converting VexFlow notation to MIDI tracks. ```APIDOC ## Constructor ```typescript constructor() ``` Creates a new VexFlow instance. **Example:** ```javascript import MidiWriter from 'midi-writer-js'; const vexWriter = new MidiWriter.VexFlow(); ``` ``` -------------------------------- ### Export MIDI from VexFlow Voice Source: https://github.com/grimmdude/midiwriterjs/blob/master/README.md This snippet shows how to convert a VexFlow voice into a MidiWriterJS track and generate a MIDI data URI. This feature is experimental and requires VexFlow setup. ```javascript // ...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()); ``` -------------------------------- ### Import MidiWriter Library Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/INDEX.md Shows how to import the midi-writer-js library in different module systems (ESM, CommonJS) and for browser environments. ```typescript // ESM (recommended) import MidiWriter from 'midi-writer-js'; // CommonJS const MidiWriter = require('midi-writer-js'); // Browser (UMD) ``` -------------------------------- ### Instantiate Writer with a Single Track Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/api-reference/writer.md Create a new Writer instance with a single Track object. This is the primary way to begin building a MIDI file. ```typescript import MidiWriter from 'midi-writer-js'; const track = new MidiWriter.Track(); track.addEvent(new MidiWriter.NoteEvent({pitch: 'C4', duration: '4'})); const writer = new MidiWriter.Writer(track); ``` -------------------------------- ### Custom Tuning Reference Configuration Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/configuration.md Set a custom middleC reference point to alter pitch mapping. For example, setting middleC to 'C3' shifts all pitches down an octave relative to standard. ```javascript const track = new MidiWriter.Track(); // Pitches will be shifted down one octave from standard track.addEvent(new MidiWriter.NoteEvent({pitch: 'C5', duration: '4'})); const writer = new MidiWriter.Writer(track, { middleC: 'C3' // C5 now maps to standard middle C }); const midiBytes = writer.buildFile(); ``` -------------------------------- ### Save MIDI File to Disk (Node.js) Source: https://github.com/grimmdude/midiwriterjs/blob/master/llms.txt Use Node.js 'fs' module to write the generated MIDI file to disk. ```javascript fs.writeFileSync('output.mid', writer.buildFile()) ``` -------------------------------- ### Controller Changes and Pitch Bend Source: https://github.com/grimmdude/midiwriterjs/blob/master/README.md Illustrates how to set volume using a Controller Change event and apply pitch bending. Ensure MidiWriterJS is imported. ```javascript import MidiWriter from 'midi-writer-js'; const track = new MidiWriter.Track(); // Set volume via CC #7 track.addEvent(new MidiWriter.ControllerChangeEvent({controllerNumber: 7, controllerValue: 100})); // Pitch bend ranging from -1.0 to 1.0 (0 = no bend) track.addEvent(new MidiWriter.PitchBendEvent({bend: 0.5})); track.addEvent(new MidiWriter.NoteEvent({pitch: ['E4'], duration: '2'})); const writer = new MidiWriter.Writer(track); console.log(writer.dataUri()); ``` -------------------------------- ### Demonstrate Invalid Duration Strings Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/errors.md Illustrates various ways an invalid duration string can be provided to MidiWriter.NoteEvent, leading to specific error messages. These examples highlight the need for correct duration formatting. ```javascript // Invalid: 'x' is not a valid note value new MidiWriter.NoteEvent({pitch: 'C4', duration: 'x'}); // Error: "x is not a valid duration." // Invalid: 7 is not a power of 2 new MidiWriter.NoteEvent({pitch: 'C4', duration: '7'}); // Error: "7 is not a valid duration." // Invalid: negative explicit ticks new MidiWriter.NoteEvent({pitch: 'C4', duration: 'T-10'}); // Error: "T-10 is not a valid duration." ``` -------------------------------- ### Create a Single Note Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/api-reference/note-event.md Instantiate a NoteEvent for a single musical note. Requires importing MidiWriter and creating a Track instance. ```javascript import MidiWriter from 'midi-writer-js'; const track = new MidiWriter.Track(); track.addEvent(new MidiWriter.NoteEvent({pitch: 'C4', duration: '4'})); const writer = new MidiWriter.Writer(track); console.log(writer.dataUri()); ``` -------------------------------- ### Create Multi-Track MIDI Files Source: https://github.com/grimmdude/midiwriterjs/blob/master/llms.txt Pass an array of Track objects to the Writer constructor to create multi-track MIDI files. ```javascript new MidiWriter.Writer([track1, track2]) ``` -------------------------------- ### ProgramChangeEventOptions Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/types.md Options for creating a Program Change MIDI event. ```APIDOC ## ProgramChangeEventOptions Constructor options for `ProgramChangeEvent`. | Property | Type | Default | Description | |----------|------|---------|-------------| | instrument | number | — | Instrument number (0-127) | | channel | number | 0 | MIDI channel (0-15) | | delta | number | 0 | Tick offset | ``` -------------------------------- ### Validate Pitch Format Before Creating NoteEvent Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/errors.md Check if a pitch string conforms to valid musical notation before creating a NoteEvent. This example uses a regular expression and a utility function to ensure the pitch is correctly formatted, preventing undefined return values or errors from the underlying pitch parsing. ```javascript const pitch = 'C4'; if (MidiWriter.Utils.isNumeric(pitch) || /^[A-G][#b]?\d$/.test(pitch)) { // Valid pitch format track.addEvent(new MidiWriter.NoteEvent({pitch, duration: '4'})); } else { console.error('Invalid pitch:', pitch); } ``` -------------------------------- ### Writer Methods Source: https://github.com/grimmdude/midiwriterjs/blob/master/README.md Methods for building and exporting the MIDI file from a Writer instance. ```APIDOC ## Writer Methods ### `buildFile()` - **Returns**: `Uint8Array` - **Description**: Constructs the MIDI file as a byte array. ### `base64()` - **Returns**: `string` - **Description**: Returns the MIDI file as a base64-encoded string. ### `dataUri()` - **Returns**: `string` - **Description**: Generates a Data URI string for the MIDI file, suitable for playback or download links. ### `stdout()` - **Description**: Writes the MIDI file to standard output. Primarily used for Node.js CLI operations. ### `setOption(key, value)` - **Returns**: `Writer` - **Description**: Sets a specific option on the Writer instance. Supports method chaining. ``` -------------------------------- ### ControllerChangeEventOptions Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/types.md Options for creating a Controller Change MIDI event. ```APIDOC ## ControllerChangeEventOptions Constructor options for `ControllerChangeEvent`. | Property | Type | Default | Description | |----------|------|---------|-------------| | controllerNumber | number | — | CC number (0-119) | | controllerValue | number | — | CC value (0-127) | | channel | number | 0 | MIDI channel (0-15) | | delta | number | 0 | Tick offset | ``` -------------------------------- ### WriterOptions Interface Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/types.md Options for configuring the MIDI writer. Use `ticksPerBeat` to set the PPQN and `middleC` for note conversion reference. ```typescript interface WriterOptions { ticksPerBeat?: number; middleC?: string; } ``` -------------------------------- ### Configure Writer Options with Chaining Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/api-reference/writer.md Set writer options such as 'ticksPerBeat' and 'middleC' using the `setOption` method, which supports method chaining for concise configuration. ```javascript const writer = new MidiWriter.Writer(track); writer .setOption('ticksPerBeat', 96) .setOption('middleC', 'C4'); ``` -------------------------------- ### Multi-Track Configuration Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/configuration.md Configure a Writer with options that apply to multiple tracks simultaneously. This is useful for setting global parameters like ticksPerBeat and middleC for all tracks in a composition. ```javascript const melody = new MidiWriter.Track(); melody.addTrackName('Melody'); melody.addEvent(new MidiWriter.NoteEvent({pitch: 'C5', duration: '4'})); const bass = new MidiWriter.Track(); bass.addTrackName('Bass'); bass.addEvent(new MidiWriter.NoteEvent({pitch: 'C2', duration: '4'})); const writer = new MidiWriter.Writer([melody, bass], { ticksPerBeat: 96, middleC: 'C4' }); // Both tracks use the same options const midiBytes = writer.buildFile(); ``` -------------------------------- ### Add Notes Across Multiple Octaves Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/api-reference/note-event.md Demonstrates adding sequential notes at different octave levels. ```javascript // Melody across octaves track.addEvent(new MidiWriter.NoteEvent({pitch: 'C3', duration: '4'})); track.addEvent(new MidiWriter.NoteEvent({pitch: 'C4', duration: '4'})); track.addEvent(new MidiWriter.NoteEvent({pitch: 'C5', duration: '4'})); ``` -------------------------------- ### Utils Class Methods Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/MANIFEST.txt Utility functions for various MIDI data manipulations and conversions. ```APIDOC ## Utils ### `version()` **Description**: Returns the current version of the MIDIWriterJS library. **Method**: `Utils.version()` **Returns**: `string` ### `getPitch(pitch, middleC?)` **Description**: Converts various pitch representations to MIDI note numbers. **Method**: `Utils.getPitch(pitch, middleC?) **Parameters**: #### Path Parameters - **pitch** (string | number | Array) - Required - The pitch to convert. - **middleC** (number) - Optional - The MIDI note number for middle C. **Returns**: `number | Array` ### `stringToBytes(string)` **Description**: Converts a string to an array of bytes. **Method**: `Utils.stringToBytes(string) **Parameters**: #### Path Parameters - **string** (string) - Required - The string to convert. **Returns**: `number[]` ### `numberToVariableLength(ticks)` **Description**: Converts a number (ticks) into a variable-length MIDI byte sequence. **Method**: `Utils.numberToVariableLength(ticks) **Parameters**: #### Path Parameters - **ticks** (number) - Required - The number of ticks. **Returns**: `number[]` ### `numberToBytes(number, bytesNeeded)` **Description**: Converts a number into a fixed-size byte array. **Method**: `Utils.numberToBytes(number, bytesNeeded) **Parameters**: #### Path Parameters - **number** (number) - Required - The number to convert. - **bytesNeeded** (number) - Required - The number of bytes to produce. **Returns**: `number[]` ### `numberFromBytes(bytes)` **Description**: Converts a byte array back into a number. **Method**: `Utils.numberFromBytes(bytes) **Parameters**: #### Path Parameters - **bytes** (number[]) - Required - The byte array. **Returns**: `number` ### `toArray(value)` **Description**: Ensures a value is an array. **Method**: `Utils.toArray(value) **Parameters**: #### Path Parameters - **value** (any) - Required - The value to convert. **Returns**: `Array` ### `convertVelocity(velocity)` **Description**: Converts a velocity value to the standard MIDI range (0-127). **Method**: `Utils.convertVelocity(velocity) **Parameters**: #### Path Parameters - **velocity** (number) - Required - The velocity value. **Returns**: `number` ### `getTickDuration(duration, ticksPerBeat?)` **Description**: Calculates the tick duration for a given note duration string. **Method**: `Utils.getTickDuration(duration, ticksPerBeat?) **Parameters**: #### Path Parameters - **duration** (string) - Required - The note duration (e.g., '4', '8d'). - **ticksPerBeat** (number) - Optional - The number of ticks per beat. **Returns**: `number` ### `getDurationMultiplier(duration)` **Description**: Gets the multiplier for dotted note durations. **Method**: `Utils.getDurationMultiplier(duration) **Parameters**: #### Path Parameters - **duration** (string) - Required - The note duration string. **Returns**: `number` ### `isNumeric(n)` **Description**: Checks if a value is numeric. **Method**: `Utils.isNumeric(n) **Parameters**: #### Path Parameters - **n** (any) - Required - The value to check. **Returns**: `boolean` ### `stringByteCount(s)` **Description**: Calculates the byte count of a string, assuming UTF-8 encoding. **Method**: `Utils.stringByteCount(s) **Parameters**: #### Path Parameters - **s** (string) - Required - The string. **Returns**: `number` ### `getRoundedIfClose(tick)` **Description**: Rounds a tick value if it's very close to an integer. **Method**: `Utils.getRoundedIfClose(tick) **Parameters**: #### Path Parameters - **tick** (number) - Required - The tick value. **Returns**: `number` ### `getPrecisionLoss(tick)` **Description**: Calculates the precision loss for a given tick value. **Method**: `Utils.getPrecisionLoss(tick) **Parameters**: #### Path Parameters - **tick** (number) - Required - The tick value. **Returns**: `number` ``` -------------------------------- ### NoteEvent Constructor Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/api-reference/note-event.md Initializes a new NoteEvent instance. This is the primary way to add musical notes to a track, automatically generating MIDI Note On and Note Off events. ```APIDOC ## Constructor NoteEvent ### Description Initializes a new NoteEvent instance. This is the primary way to add musical notes to a track, automatically generating MIDI Note On and Note Off events. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **pitch** (string | number | array) - Required - Note pitch as string (e.g., 'C4') or MIDI number (0-127). Array creates chord or arpeggio. - **duration** (string | array) - Optional - Note length (see [Duration Values](#duration-values)). Can be single value or array (sum is used). Defaults to '4'. - **wait** (string | number | array) - Optional - Rest before note sounds (same format as duration). Defaults to 0. - **velocity** (number) - Optional - Loudness (1-100). Defaults to 50. - **channel** (number) - Optional - MIDI channel (1-16). Defaults to 1. - **repeat** (number) - Optional - How many times to repeat this note event. Defaults to 1. - **grace** (string | array) - Optional - Grace note(s) before main note (same pitch format as pitch). - **sequential** (boolean) - Optional - If true, array pitches play sequentially; if false, they play as chord. Defaults to false. - **startTick** | **tick** (number) - Optional - Explicit tick position. If provided, wait is ignored. ### Request Example ```json { "pitch": "C4", "duration": "8", "velocity": 70 } ``` ### Response This method does not return a value directly, but configures the NoteEvent object for subsequent use. #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### Create a Chord (Simultaneous Pitches) Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/api-reference/note-event.md Add a chord to the track by providing an array of pitches. All pitches in the array will play at the same time. ```javascript // C Major chord track.addEvent(new MidiWriter.NoteEvent({ pitch: ['C4', 'E4', 'G4'], duration: '2' // Half note })); ``` -------------------------------- ### PitchBendEventOptions Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/types.md Options for creating a Pitch Bend MIDI event. ```APIDOC ## PitchBendEventOptions Constructor options for `PitchBendEvent`. | Property | Type | Default | Description | |----------|------|---------|-------------| | bend | number | — | Bend amount (-1.0 to 1.0) | | channel | number | 0 | MIDI channel (0-15) | | delta | number | 0 | Tick offset | ``` -------------------------------- ### ProgramChangeEvent Constructor Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/api-reference/midi-events.md Initializes a ProgramChangeEvent to change the MIDI instrument on a specified channel. MIDI supports 128 standard instruments. ```APIDOC ## ProgramChangeEvent ### Description Changes the MIDI instrument (patch) on a channel. MIDI has 128 standard instruments (GM patch set). ### Parameters #### Path Parameters - **instrument** (number) - Required - Instrument number (0-127) - **channel** (number) - Optional - MIDI channel (0-15, note: 0-indexed). Defaults to 0. - **delta** (number) - Optional - Tick offset. Defaults to 0. ### Request Example ```javascript // Change to piano (instrument 0) track.addEvent(new MidiWriter.ProgramChangeEvent({instrument: 0, channel: 1})); // Change to violin (instrument 40) track.addEvent(new MidiWriter.ProgramChangeEvent({instrument: 40})); // Drums on channel 10 track.addEvent(new MidiWriter.ProgramChangeEvent({instrument: 0, channel: 10})); ``` ### Properties - **name**: 'ProgramChangeEvent' (string) - **status**: 0xC0 (number) - **instrument**: number - **channel**: number - **data**: number[] - **delta**: number ``` -------------------------------- ### setOption() Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/api-reference/writer.md Allows modification of Writer instance options after initialization. This method supports method chaining, enabling multiple options to be set sequentially. ```APIDOC ## setOption() ### Description Sets an option on the Writer instance. This method supports method chaining, allowing multiple options to be set in a single statement. ### Method ``` setOption(key: string, value: number | string): Writer ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table | Parameter | Type | Required | Description | |---|---|---|---| | key | string | Yes | Option key name | | value | number | string | Yes | Option value | ### Returns `Writer` — This instance for chaining ### Example ```javascript const writer = new MidiWriter.Writer(track); writer .setOption('ticksPerBeat', 96) .setOption('middleC', 'C4'); ``` ``` -------------------------------- ### Core Classes Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/INDEX.md Overview of the main classes available in MIDIWriterJS for building MIDI files. ```APIDOC ## Core Classes ### Track **Purpose:** Container for MIDI events. ### Writer **Purpose:** MIDI file builder and output generator. ### NoteEvent **Purpose:** High-level note wrapper (most common). ``` -------------------------------- ### Writer Options Configuration Source: https://github.com/grimmdude/midiwriterjs/blob/master/_autodocs/INDEX.md Defines the available options for the Writer constructor, including ticksPerBeat for precision and middleC for tuning. Default values are provided. ```typescript { ticksPerBeat?: number; // Default: 128 (24, 96, 480 common) middleC?: string; // Default: 'C4' } ```