Table of Contents

Class MidiIo

Namespace
Celeritas.Core.Midi
Assembly
Celeritas.dll

Reads and writes MIDI files, converting between MIDI ticks and whole-note time units.

public static class MidiIo
Inheritance
MidiIo
Inherited Members

Remarks

Two things a MIDI file cannot hold exactly, so that a caller comparing a buffer with the one read back knows where the difference comes from.

Time is a whole number of ticks. A duration or onset that is not one is written to the nearest tick. At the default 480 ticks per quarter note every ordinary value — and every triplet, quintuplet and 32nd — is exact; a septuplet lands within half a tick (1/28 of a whole note is 68.57 ticks, written as 69, so it reads back as 23/640). Raise TicksPerQuarterNote for a finer grid.

A note is a note-on and a note-off. Two notes of the same pitch on the same channel that overlap in time cannot be told apart in the file: the first note-off ends whichever of them is sounding. A note held from 5/8 for 3/2 with a second sounding of the same pitch from 9/8 for 3/8 inside it is written as two notes, and read back as one from 5/8 to 3/2 and one from 9/8 to 17/8 — the same onsets, the ends re-paired. Give such voices different channels, or use MusicXmlIo, which keeps them apart.

Methods

Export(NoteBuffer, Stream, MidiExportOptions?)

Writes buffer as a single-track MIDI file to stream.

public static void Export(NoteBuffer buffer, Stream stream, MidiExportOptions? options = null)

Parameters

buffer NoteBuffer
stream Stream
options MidiExportOptions

Remarks

The file is SMF format 0: one track chunk holding the tempo and every note. It was written as format 1 before, in which the writer moves the tempo into a first track of its own, so the "single-track" file read back with two tracks and a TrackCount of 2 — see Celeritas.Core.Midi.MidiFileExtensions.FormatThatKeepsTheLayout(Melanchall.DryWetMidi.Core.MidiFile).

Exceptions

ArgumentOutOfRangeException

An option (ticks-per-quarter-note, channel, or BPM) is out of range.

ArgumentException

A note has a negative offset, which MIDI cannot represent.

Export(NoteBuffer, string, MidiExportOptions?)

Exports buffer as a single-track MIDI file at path.

public static void Export(NoteBuffer buffer, string path, MidiExportOptions? options = null)

Parameters

buffer NoteBuffer
path string
options MidiExportOptions

Remarks

See MidiIo for the two things the format cannot hold exactly. The file is SMF format 0: one track chunk holding the tempo and every note.

Exceptions

ArgumentNullException

buffer or path is null.

ArgumentOutOfRangeException

An option (ticks-per-quarter-note, channel, or BPM) is out of range.

ArgumentException

A note has a negative offset, or lasts longer than MIDI can express in one note.

Import(Stream, MidiImportOptions?)

Imports notes from a MIDI stream using hardened reading settings.

public static NoteBuffer Import(Stream stream, MidiImportOptions? options = null)

Parameters

stream Stream
options MidiImportOptions

Returns

NoteBuffer

Remarks

The notes come out in the order SortByOffset chooses: every track merged into one time order by default, or track by track as the file lists them. Either way they are the same notes — a note-on is paired with a note-off in its own track, whichever way the tracks are read.

Notes on the General MIDI percussion channel are left out unless IncludePercussion is set or Channel names that channel: a drum hit's note number is an instrument, not a pitch. They used to come in like any other note, and a drum track under a piano track changed the key the piano was heard in.

Exceptions

InvalidDataException

The stream is malformed or corrupt.

NotSupportedException

The file does not use ticks-per-quarter-note time division.

Import(string, MidiImportOptions?)

Imports notes from the MIDI file at path.

public static NoteBuffer Import(string path, MidiImportOptions? options = null)

Parameters

path string
options MidiImportOptions

Returns

NoteBuffer