.NET library to read, write, process MIDI files and to work with MIDI devices
DryWetMIDI allows now work with MIDI devices on macOS! More than that, a couple of new classes are available for macOS only:
Also HighPrecisionTickGenerator implemented for macOS too so you can now use Playback with default settings on that platform. Its implementation for macOS is not good (in terms of performance) for now but will be optimized for the next release of the library.
This version of the library has following breaking changes:
Melanchall.DryWetMidi.Devices
namespace renamed to Melanchall.DryWetMidi.Multimedia to reflect its content more precisely since not only devices are there.DriverManufacturer
, ProductIdentifier
and DriverVersion
properties were removed from the MidiDevice class and replaced by GetProperty
method for InputDevice and for OutputDevice.Channels
, DeviceType
, NotesNumber
, SupportsLeftRightVolumeControl
, SupportsPatchCaching
, SupportsVolumeControl
, VoicesNumber
and Volume
properties were removed from OutputDevice and replaced by GetProperty method.InvalidSysExEventReceived
and InvalidShortEventReceived
events from InputDevice and replaced them with ErrorOccurred one.GetProperty
method for InputDevice and for OutputDevice.GetSupportedProperties
method for InputDevice and for OutputDevice.ConvertMultiple
methods to BytesToMidiEventConverter (#134).WritingSettings
property of MidiEventToBytesConverter into separate properties.ReadingSettings
property of BytesToMidiEventConverter into separate properties.GetByIndex
method for InputDevice and for OutputDevice.GetObjects
methods of the GetObjectsUtilities sometimes return wrong chords when notes are gathered across different track chunks.EventCallback
property to DevicesConnector
.CutPart
method to MidiFileSplitter
.GetNotes
, ProcessNotes
and RemoveNotes
methods of NotesManagingUtilities
.GetChords
, ProcessChords
and RemoveChords
methods of ChordsManagingUtilities
.DeviceErrorOccurred
event to Playback
(#121).MidiClockSettings
parameter by PlaybackSettings
in all playback creation methods and put MidiClockSettings
inside PlaybackSettings
.Playback
constructors by MidiEvent
s, added GetPlayback
utility methods for MidiEvent
s to (with output device parameter and without it).Playback
when value of TrackControlValue
, TrackPitchValue
or TrackProgram
changed to true
.IMetadata
interface.TryPlayEvent
and GetTimedEvents
protected virtual
method to Playback
(please see Custom playback article).EndOfTrackStoringPolicy
to ReadingSettings
(#17).Metadata
property to MidiEventPlayedEventArgs
(please see Custom playback article).TickGenerator.TickGenerated
event public
.EndOfTrackEvent
class public
(#17).sealed
modifier from Playback
.sealed
modifier from TimedEvent
, Note
and Chord
classes, made their Clone
methods virtual
.Octave
and Note
caches is failed (#116).NoteSearchContext
and ChordSearchContext
are not respected in GetObjects
methods for track chunks collection and for MIDI file.Playback
when we jump to data change event.Methods to get, process and remove timed events and notes now work faster and consume less memory. Full tables with benchmarks results can be found here:
GetObjectsUtilities
class containing methods that allow get objects of different types from the input ones (or MIDI file, for example).ProcessTimedEvents
and RemoveTimedEvents
methods return now count of processed/removed timed events.ProcessNotes
and RemoveNotes
methods return now count of processed/removed notes.ProcessChords
and RemoveChords
methods return now count of processed/removed chords.IsEnabled
property to MidiDevice
.Playback
to move to snap points by data.Playback
return bool
now to indicate whether time changed or not.PlaybackStart
and PlaybackEnd
properties to Playback
.IsEnabled
to PlaybackSnapping
.PlaybackSnapping.Clear
method.TrackProgram
, TrackPitchValue
and TrackControlValue
to Playback
.<
, >
, <=
, >=
operators for Tempo
and TimeSignature
.BeatsPerMinute
property of Tempo
is now of double
type.settings
parameter to SplitByChannel
method.settings
parameter to SplitByNotes
method.GetTimedEvents
, GetNotes
and GetChords
changed from IEnumerable<T>
to ICollection<T>
.NoteDetectionSettings
to GetNotes
, ProcessNotes
and RemoveNotes
.ChordDetectionSettings
to GetChords
, ProcessChords
and RemoveChords
.ChordDetectionSettings
to ChordsQuantizingSettings
and ChordsRandomizingSettings
.NoteDetectionSettings
to NotesQuantizingSettings
and NotesRandomizingSettings
.SilentNoteOnPolicy
property to InputDevice
.SplitByChunks
method to MidiFileSplitter
.GetTimedEventsAndNotesUtilities
(OBS5);GetNotesAndRestsUtilities
(OBS6);TimedEventsManagingUtilities.ToTrackChunk
, NotesManagingUtilities.ToTrackChunk
, ChordsManagingUtilities.ToTrackChunk
(OBS7);TimedEventsManagingUtilities.ToFile
, NotesManagingUtilities.ToFile
, ChordsManagingUtilities.ToFile
(OBS8);TimedEventsManagingUtilities.AddTimedEvents
, NotesManagingUtilities.AddNotes
, ChordsManagingUtilities.AddChords
(OBS9).ICollection<MidiEvent>
on EventsCollection
.ICollection<MidiChunk>
on ChunksCollection
.PatternUtilities.CombineInParallel
last action moves back to previous time (#112).Playback.MoveToNextSnapPoint
works incorrectly for snap point at zero.MetricTimeSpan.Clone
works incorrectly.UnexpectedTrackChunksCountException
constructor.New section has been added to documentation site: Obsolete. This section contains the list of methods and classes that are obsolete and thus will be removed by a next release.
The current list of obsolete API:
interval
parameter from MidiClockSettings.CreateTickGeneratorCallback
.ITickGenerator
to TickGenerator
abstract class.RepeatStarted
event to Playback
.MidiEventReceivedEventArgs
and MidiEventSentEventArgs
public to have ability to fire corresponding events in custom input/output devices.DevicesConnector
now uses IInputDevice
instead of InputDevice
.IDisposable
from DevicesConnector
.AreDevicesConnected
property to DevicesConnector
.Parse
/TryParse
to Octave
.INotifyTimeChanged
interface on TimedEvent
, Note
and Chord
.INotifyLengthChanged
interface on Note
and Chord
.Playback
can cause exceptions.Playback.EventPlayed
not fired for meta events (#82).GetNames
.MidiFile.Read
and MidiFile.Write
methods now work much faster (#64). For MidiFile.Read
new setting ReadingSettings.ReaderSettings.ReadFromMemory
was added:
MidiFile.Read("file.mid", new ReadingSettings
{
ReaderSettings = new ReaderSettings
{
ReadFromMemory = true
}
});
With ReadFromMemory
set to true
entire MIDI file will be put to memory and read from there which gives big speed up.
Added IInputDevice
interface (#54), all methods that accept InputDevice
as an argument accept now IInputDevice
, which implemented by InputDevice
. This interface gives ability to create custom input device implementations.
Added IOutputDevice
interface, all methods that accept OutputDevice
as an argument accept now IOutputDevice
, which implemented by OutputDevice
. This interface gives ability to create custom output device implementations.
Added BytesToMidiEventConverter
class to convert bytes to MIDI events (#55).
Added MidiEventToBytesConverter
class to convert MIDI events to bytes.
Added Interaction.Chord.GetMusicTheoryChord
method.
Added Interaction.Note.GetMusicTheoryNote
method.
Added Interval.GetIntervalDefinitions
method returning collection of IntervalDefinition
which is interval number and quality.
Added Interval.FromDefinition
method to create Interval
from interval number and quality.
Added MusicTheory.Chord.GetNames
method returning names of a chord (for example, A#
or Ddim
) (#58).
Added General MIDI Level 2 percussion API to Melanchall.DryWetMidi.Standards
namespace (#65).
Added ReadingHandlers
property to ReadingSettings
which provides collection of objects that handle MIDI data reading. Also added three handler classes:
TimedEventsReadingHandler
NotesReadingHandler
TempoMapReadingHandler
These classes can speed up getting MIDI data from a MIDI file since information will be gathered during MIDI data reading rather than after data is read which involves additional iteration over MIDI data.
You can create custom reading handler and process MIDI file reading stages.
Added UnknownChannelEventPolicy
property to ReadingSettings
(#69) which specifies how reading engine should react on unknown channel event status byte. Also added UnknownChannelEvent
property which specifies callback that will be called on unknown channel event if UnknownChannelEventPolicy
set to UnknownChannelEventPolicy.UseCallback
.
Added ReaderSettings
property to ReadingSettings
. ReaderSettings
holds I/O settings for MIDI data reader.
Implemented reading MIDI file from non-seekable stream. Settings related to reading from such streams are placed at ReadingSettings.ReaderSettings
. Names of properties corresponding to these settings are start with NonSeekableStream
.
Added Equals
static methods for MidiEvent
, MidiChunk
and MidiFile
classes.
Added PatternUtilities.TransformNotes
accepting NoteSelection
which is predicate to select notes to transform.
Added PatternUtilities.TransformChords
accepting ChordSelection
which is predicate to select chords to transform.
Added PatternUtilities.SetNotesState
method (#74).
Added PatternUtilities.SetChordsState
method.
Pattern.Clone
creates now deep copy instead of shallow one.
Added GetStandardChunkIds
static method to MidiChunk
.
Added GetStandardMetaEventStatusBytes
static method to MetaEvent
.
IComparable
on Interval
.IComparable
on MusicTheory.Note
.Playback
looped on current time change inside EventPlayed
event handler (#56).CsvConverter
closes passed stream after data is read or written (#73).OutputDevice.Volume
get/set fails (#75).ResetEvent
not received by input device.\r
and \n
in texts of meta events.This version of the library has breaking changes:
Melanchall.DryWetMidi.Smf
namespace renamed to Melanchall.DryWetMidi.Core
.Melanchall.DryWetMidi.Smf.Interaction
namespace renamed to Melanchall.DryWetMidi.Interaction
.Melanchall.DryWetMidi.Composing
.BarBeatTimeSpan
renamed to BarBeatTicksTimeSpan
.SetProgram
methods of the PatternBuilder
class to ProgramChange
.SetOctave
method of the PatternBuilder
class from int
to Octave
.From now you can read complete library documentation on https://melanchall.github.io/drywetmidi. Here you can find information about every class and members of the library. API documentation is placed in API Documentation section.
Right now it's not full replacement for the library Wiki so please don't forget to look at Wiki also when you want to get more information on some topic.
Chord
class to Melanchall.DryWetMidi.MusicTheory
namespace.ChordProgression
class to Melanchall.DryWetMidi.MusicTheory
namespace.GetStep
method to ScaleUtilities
that gets NoteName
corresponding to the specified step of a musical scale.GetNotesNames
method to ScaleUtilities
that returns infinite collection of note names that belong to the specified scale.IntervalQuality
enum to Melanchall.DryWetMidi.MusicTheory
namespace.Get
method to Interval
class which accepts interval number and quality.Interval
by number and quality (for example, "P8" which is perfect eight).Transpose
method to NoteUtilities
class which returns the NoteName
transposed by the specified interval.Note
can be parsed now from string with any number of sharps and flats.NoteCallback
property to Playback
class which allows to modify and filter every note to be played.EventCallback
property to Playback
class which allows to modify and filter every MIDI event to be played.EventPlayed
event to Playback
class to track MIDI events playing.PlaybackCurrentTimeWatcher
class which allows to watch current time of specified playbacks and report it in the specified units via corresponding event.BarBeatFractionTimeSpan
which represents a beat as a fraction (for example 0.5
) instead of number of whole beats and number of MIDI ticks (used by BarBeatTicksTimeSpan
).BarBeatUitilities
which contains methods:
GetBarLength
that allows to get length of specified bar in terms of MIDI ticks;GetBeatLength
that allows to get length of a beat of specified bar in terms MIDI ticks.Filter
property to quantizing settings classes to filter out objects that should be quantized.Filter
property to randomizing settings classes to filter out objects that should be randomized.MidiClock
class which allows to report ticks with the specified interval and speed.NoteId
class that repesents a separately sounding note (note number and channel).PatternUtilities
class with methods:
TransformNotes
that transforms notes within the specified Pattern
producing new pattern;TransformChords
that transforms chords within the specified Pattern
producing new pattern;SplitAtAnchor
that splits a pattern into subpatterns in points where the specified anchor inserted;SplitAtAllAnchors
that splits a pattern into subpatterns in points where anchors inserted;SplitAtMarker
that splits a pattern into subpatterns in points where the specified marker inserted;SplitAtAllMarkers
that splits a pattern into subpatterns in points where markers inserted;CombineInSequence
that combines the specified patterns into single one placing them after each other;CombineInParallel
that combines the specified patterns into single one starting all them at the same time (i.e. stacking patterns).PatternBuilder
that holds default values:
PatternBuilder
that return current values:
Velocity
;NoteLength
;Step
;Octave
;RootNote
.ReplayPattern
method to PatternBuilder
class to insert all actions from the specifed pattern.PatternBuilder
constructor that accepts Pattern
to start from the list of actions of the passed pattern.Chord
methods to PatternBuilder
class which accept an instance of the Melanchall.DryWetMidi.MusicTheory.Chord
.Clone
method to Pattern
class to create a copy of the current pattern.GetHashCode
implementation for the library classes.NotesManager
when notes are overlapped.PatternBuilder.MoveToPreviousTime
doesn't work.This is a minor release. Changes are listed below.
DecodeTextCallback
to ReadingSettings
(#27).GetChannels
extension method for TrackChunk
and MidiFile
.DevicesConnector
allows connect one input device to several output devices now.EventType
property to MidiEvent
which allow to check MIDI event type without using as
or is
operators.Playback.OutputDevice
is optional now and can be set to null
.SmfConstants.DefaultEncoding
constant which holds default encoding of text in MIDI file.MidiFile.Read
/MidiFile.Write
.GetTimedEvents
, GetNotes
and GetChords
extension methods for IEnumerable<MidiEvent>
.IsEmpty
extension method for MidiFile
.GetDuration
extension method for MidiFile
.NoteStopPolicy
property from Playback
.InterruptNotesOnStop
property to Playback
.TrackNotes
property to Playback
.NotesPlaybackStarted
/NotesPlaybackFinished
events to Playback
.Playback
constructor with IEnumerable<ITimedObject>
as an argument.SetTime
extension method for TimedEvent
.SetTimeAndLength
extension method for Note
and Chord
.channel
parameter to methods to get program change events by GM programs and to methods to get control change events.GetPlayback
/Play
extension methods for IEnumerable<Note>
and IEnumerable<Chord>
.OutputDevice
property of Playback
.BarBeatTimeSpan
constructor that takes bars number only.Notes
class that holds all available Note
s.SkipPart
and TakePart
extension methods for MidiFile
.Playback
.EndTimeAs
extension method for ILengthedObject
.IConvertible
on FourBitNumber
and SevenBitNumber
.IGrid
along with its implementations from Tools namespace to Smf.Interaction.Pattern
.MidiFile
is lost when splitting file with ArbitraryGrid
.sameTimeEventsComparison
is ignored when managing timed events.Pattern
to TrackChunk
.long
overflow.DryWetMIDI 4.0.0 introduces API for working with MIDI devices. Now it is possible to send MIDI data to and receive it from a MIDI device. Also added methods to play MIDI files and capture incoming events from a device.
Read about working with devices on the library Wiki:
GetTimedEventsAndNotes
and GetNotesAndRests
extension methods for TrackChunk
and MidiFile
.Parse
/TryParse
methods to FourBitNumber
and SevenBitNumber
.ShiftEvents
extension methods for TrackChunk
and MidiFile
which shifts MIDI events inside MidiFile
by the specified distance.Resize
extension method for MidiFile
which resizes MidiFile
to the specified length or by specified ratio (for example, 0.5
means shrinking to the half of the original length).GetChords
extension method for IEnumerable<Note>
which makes chords from notes collection.