### 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'
}
```