Class MidiIo
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
bufferNoteBufferstreamStreamoptionsMidiExportOptions
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
bufferNoteBufferpathstringoptionsMidiExportOptions
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
bufferorpathis 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
streamStreamoptionsMidiImportOptions
Returns
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
pathstringoptionsMidiImportOptions