Midi
Description of a scale's pattern as it ascends through an octave.
This class describes the general behavior of a scale as it ascends from a tonic up to
the next tonic. It is described in terms of semitones relative to the tonic; to apply it to
a particular tonic, pass one of these to the constructor of .
Constructs a scale pattern.
The name of the scale pattern.
The ascending pattern of the scale. See the
property for a detailed description and requirements. This parameter is copied.
name or ascent is null.
ascent is invalid.
ToString returns the pattern name.
The pattern's name, such as "Major" or "Melodic Minor (ascending)".
Equality operator does value equality.
Inequality operator does value inequality.
Value equality.
Hash code.
Returns true if ascent is valid.
The name of the scale being described.
The ascent of the scale.
The ascent is expressed as a series of integers, each giving a semitone
distance above the tonic. It must have at least two elements, start at zero (the
tonic), be monotonically increasing, and stay below 12 (the next tonic above).
The number of elements in the ascent tells us how many notes-per-octave in the
scale. For example, a heptatonic scale will always have seven elements in the ascent.
A scale based on a pattern and a tonic note.
For our purposes, a scale is defined by a tonic and then the pattern that it uses to
ascend up to the next tonic. The tonic is described with a because it is
not specific to any one octave. The ascending pattern is provided by the
class.
This class comes with a collection of predefined patterns, such as
and .
Constructs a scale from its tonic and its pattern.
The tonic note.
The scale pattern.
tonic or pattern is null.
Returns true if pitch is in this scale.
The pitch to test.
True if pitch is in this scale.
Returns the scale degree of the given pitch in this scale.
The pitch to test.
The scale degree of pitch in this scale, where 1 is the tonic. Returns -1
if pitch is not in this scale.
Pattern for Major scales.
Pattern for Natural Minor scales.
Pattern for Harmonic Minor scales.
Pattern for Melodic Minor scale as it ascends.
Pattern for Melodic Minor scale as it descends.
Pattern for Chromatic scales.
Array of all the built-in scale patterns.
ToString returns the scale's human-readable name.
The scale's name, such as "G# Major" or "Eb Melodic Minor (ascending)".
Equality operator does value equality because Scale is immutable.
Inequality operator does value inequality because Chord is immutable.
Value equality.
Hash code.
Builds a scale.
The tonic.
The scale pattern.
Must have 12 elements, and is filled with
the 0-indexed scale position (or -1) for each position in the octave.
Must have pattern.Ascent.Length elements, and is filled with
the notes for each scale degree.
Filled with the total number of accidentals in the built
scale.
The tonic of this scale.
The pattern of this scale.
The sequence of notes in this scale.
This sequence begins at the tonic and ascends, stopping before the next tonic.
Base class for all MIDI messages.
Protected constructor.
The timestamp for this message.
Sends this message immediately.
Returns a copy of this message, shifted in time by the specified amount.
Milliseconds since the music started.
Base class for messages relevant to a specific device.
Protected constructor.
The device from which this message originated, or for which it is destined.
Base class for messages relevant to a specific device channel.
Protected constructor.
Channel.
Base class for messages relevant to a specific note.
Protected constructor.
The pitch for this note message.
Velocity, 0..127.
Note On message.
Constructs a Note On message.
The device associated with this message.
Channel, 0..15, 10 reserved for percussion.
The pitch for this note message.
Velocity, 0..127.
The timestamp for this message.
Sends this message immediately.
Returns a copy of this message, shifted in time by the specified amount.
Percussion message.
A percussion message is simply shorthand for sending a Note On message to Channel10 with a
percussion-specific note. This message can be sent to an OutputDevice but will be received
by an InputDevice as a NoteOn message.
Constructs a Percussion message.
The device associated with this message.
Percussion.
Velocity, 0..127.
The timestamp for this message.
Sends this message immediately.
Returns a copy of this message, shifted in time by the specified amount.
Percussion.
Velocity, 0..127.
Note Off message.
Constructs a Note Off message.
The device associated with this message.
Channel, 0..15, 10 reserved for percussion.
The pitch for this note message.
Velocity, 0..127.
The timestamp for this message.
Sends this message immediately.
Returns a copy of this message, shifted in time by the specified amount.
A Note On message which schedules its own Note Off message when played.
Constructs a Note On/Off message.
The device associated with this message.
Channel, 0..15, 10 reserved for percussion.
The pitch for this note message.
Velocity, 0..127.
The timestamp for this message.
The clock that should schedule the off message.
Time delay between on message and off messasge.
Sends this message immediately.
Returns a copy of this message, shifted in time by the specified amount.
The clock used to schedule the follow-up message.
Time delay between the Note On and the Note Off.
Control change message.
Construts a Control Change message.
The device associated with this message.
Channel, 0..15, 10 reserved for percussion.
Control, 0..119
Value, 0..127.
The timestamp for this message.
Sends this message immediately.
Returns a copy of this message, shifted in time by the specified amount.
The control for this message.
Value, 0..127.
Pitch Bend message.
Constructs a Pitch Bend message.
The device associated with this message.
Channel, 0..15, 10 reserved for percussion.
Pitch bend value, 0..16383, 8192 is centered.
The timestamp for this message.
Sends this message immediately.
Returns a copy of this message, shifted in time by the specified amount.
Pitch bend value, 0..16383, 8192 is centered.
Program Change message.
Constructs a Program Change message.
The device associated with this message.
Channel.
Instrument.
The timestamp for this message.
Sends this message immediately.
Returns a copy of this message, shifted in time by the specified amount.
Instrument.
Pseudo-MIDI message used to arrange for a callback at a certain time.
This message can be scheduled with
Clock.Schedule just like any other message. When its time comes and it
gets "sent", it invokes the callback provided in the constructor.
The idea is that you can embed callback points into the music you've
scheduled, so that (if the clock gets to that point in the music) your code has
an opportunity for some additional processing.
The callback is invoked on the MidiOutputDevice's worker thread.
Constructs a Callback message.
The callback to invoke when this message is "sent".
The timestamp for this message.
Sends this message immediately, ignoring the beatTime.
Returns a copy of this message, shifted in time by the specified amount.
The callback to invoke when this message is "sent".
Delegate called when a CallbackMessage is sent.
The time at which this event was scheduled.
Additional messages which should be scheduled as a result of this callback,
or null.
Common base class for input and output devices.
This base class exists mainly so that input and output devices can both go into the same
kinds of MidiMessages.
Protected constructor.
The name of this device.
The name of this device.
Exception thrown when an operation on a MIDI device cannot be satisfied.
Constructs exception with a specific error message.
Description of a chord's pattern starting at the root note.
This class describes the ascending sequence of notes included in a chord, starting with
the root note. It is described in terms of semitones relative to root and letters
relative to the root. To apply it to particular tonic, pass one of these to the
constructor of .
Constructs a chord pattern.
The name of the chord pattern.
The abbreviation for the chord. See the
property for details.
Array encoding the notes in the chord. See the
property for details.
Array encoding the sequence of letters in the chord.
Must be the same length as ascent. See the property for
details.
ascent or letterOffsets is invalid, or they have
different lengths.
an argument is null.
ToString returns the pattern name.
The pattern's name, such as "Major" or "Minor".
Equality operator does value equality.
Inequality operator does value inequality.
Value equality.
Hash code.
Returns true if sequence has at least two elements, starts at zero, and is monotonically
increasing.
The name of the chord pattern.
Abbreviation for this chord pattern.
This is the string used in the abbreviated name for a chord, placed immediately
after the tonic and before the slashed inversion (if there is one). For example,
for minor chords the abbreviation is "m", as in "Am".
The ascending note sequence of the chord, in semitones-above-the-root.
This sequence starts at zero (for the root) and is monotonically
increasing, each element representing a pitch in semitones above the root.
The sequence of letters in the chord.
This array describes what sequence of letters appears in this chord. Each
element is a "letter offset", a positive integer that tell you how many letters to
move up from the root for that note. It must start at zero, representing the
letter for the root note.
A chord.
A chord is defined by its root note, the sequence of semitones, the sequence of
letters, and the inversion. The root note is described with a
because we want to be able to talk about the chord independent of any one octave. The
pattern of semitones and letters is given by the nested class. The
inversion is an integer indicating how many rotations the pattern has undergone.
This class comes with a collection of predefined chord patterns, such as
and .
Constructs a chord from its root note, pattern, and inversion.
The root note of the chord.
The chord pattern.
The inversion, in [0..N-1] where N is the number of notes
in pattern.
pattern is null.
inversion is out of range.
Constructs a chord from a string.
The name to parse. This is the same format as the Name property:
a letter in ['A'..'G'], an optional series of accidentals (#'s or b's), then an
optional inversion specified as a '/' followed by another note name. If the
inversion is present it must be one of the notes in the chord.
name is null.
cannot parse a chord from name.
Returns a list of chords which match the set of input pitches.
Notes being analyzed.
A (possibly empty) list of chords.
Returns true if this chord contains the specified pitch.
The pitch to test.
True if this chord contains the pitch.
Pattern for Major chords.
Pattern for Minor chords.
Pattern for Seventh chords.
Pattern for Augmented chords.
Pattern for Diminished chords.
Array of all the built-in chord patterns.
ToString returns the chord name.
The chord's name.
Equality operator does value equality because Chord is immutable.
Inequality operator does value inequality because Chord is immutable.
Value equality.
Hash code.
Fills dest with a rotated version of source.
The source array.
The dest array, which must have the same length and underlying type
as source.
The number of elements to rotate to the left by.
The name of this chord.
The root note of this chord.
The bass note of this chord.
The pattern of this chord.
The inversion of this chord.
The sequence of notes in this chord.
General MIDI instrument, used in Program Change messages.
The MIDI protocol defines a Program Change message, which can be used to switch a
device among "presets". The General MIDI specification further standardizes those presets
into the specific instruments in this enum. General-MIDI-compliant devices will
have these particular instruments; non-GM devices may have other instruments.
MIDI instruments are one-indexed in the spec, but they're zero-indexed in code, so
we have them zero-indexed here.
This enum has extension methods, such as
and , defined in
.
General MIDI instrument 0 ("Acoustic Grand Piano").
General MIDI instrument 1 ("Bright Acoustic Piano").
General MIDI instrument 2 ("Electric Grand Piano").
General MIDI instrument 3 ("Honky Tonk Piano").
General MIDI instrument 4 ("Electric Piano 1").
General MIDI instrument 5 ("Electric Piano 2").
General MIDI instrument 6 ("Harpsichord").
General MIDI instrument 7 ("Clavinet").
General MIDI instrument 8 ("Celesta").
General MIDI instrument 9 ("Glockenspiel").
General MIDI instrument 10 ("Music Box").
General MIDI instrument 11 ("Vibraphone").
General MIDI instrument 12 ("Marimba").
General MIDI instrument 13 ("Xylophone").
General MIDI instrument 14 ("Tubular Bells").
General MIDI instrument 15 ("Dulcimer").
General MIDI instrument 16 ("Drawbar Organ").
General MIDI instrument 17 ("Percussive Organ").
General MIDI instrument 18 ("Rock Organ").
General MIDI instrument 19 ("Church Organ").
General MIDI instrument 20 ("Reed Organ").
General MIDI instrument 21 ("Accordion").
General MIDI instrument 22 ("Harmonica").
General MIDI instrument 23 ("Tango Accordion").
General MIDI instrument 24 ("Acoustic Guitar (nylon)").
General MIDI instrument 25 ("Acoustic Guitar (steel)").
General MIDI instrument 26 ("Electric Guitar (jazz)").
General MIDI instrument 27 ("Electric Guitar (clean)").
General MIDI instrument 28 ("Electric Guitar (muted)").
General MIDI instrument 29 ("Overdriven Guitar").
General MIDI instrument 30 ("Distortion Guitar").
General MIDI instrument 31 ("Guitar Harmonics").
General MIDI instrument 32 ("Acoustic Bass").
General MIDI instrument 33 ("Electric Bass (finger)").
General MIDI instrument 34 ("Electric Bass (pick)").
General MIDI instrument 35 ("Fretless Bass").
General MIDI instrument 36 ("Slap Bass 1").
General MIDI instrument 37 ("Slap Bass 2").
General MIDI instrument 38 ("Synth Bass 1").
General MIDI instrument 39("Synth Bass 2").
General MIDI instrument 40 ("Violin").
General MIDI instrument 41 ("Viola").
General MIDI instrument 42 ("Cello").
General MIDI instrument 43 ("Contrabass").
General MIDI instrument 44 ("Tremolo Strings").
General MIDI instrument 45 ("Pizzicato Strings").
General MIDI instrument 46 ("Orchestral Harp").
General MIDI instrument 47 ("Timpani").
General MIDI instrument 48 ("String Ensemble 1").
General MIDI instrument 49 ("String Ensemble 2").
General MIDI instrument 50 ("Synth Strings 1").
General MIDI instrument 51 ("Synth Strings 2").
General MIDI instrument 52 ("Choir Aahs").
General MIDI instrument 53 ("Voice oohs").
General MIDI instrument 54 ("Synth Voice").
General MIDI instrument 55 ("Orchestra Hit").
General MIDI instrument 56 ("Trumpet").
General MIDI instrument 57 ("Trombone").
General MIDI instrument 58 ("Tuba").
General MIDI instrument 59 ("Muted Trumpet").
General MIDI instrument 60 ("French Horn").
General MIDI instrument 61 ("Brass Section").
General MIDI instrument 62 ("Synth Brass 1").
General MIDI instrument 63 ("Synth Brass 2").
General MIDI instrument 64 ("Soprano Sax").
General MIDI instrument 65 ("Alto Sax").
General MIDI instrument 66 ("Tenor Sax").
General MIDI instrument 67 ("Baritone Sax").
General MIDI instrument 68 ("Oboe").
General MIDI instrument 69 ("English Horn").
General MIDI instrument 70 ("Bassoon").
General MIDI instrument 71 ("Clarinet").
General MIDI instrument 72 ("Piccolo").
General MIDI instrument 73 ("Flute").
General MIDI instrument 74 ("Recorder").
General MIDI instrument 75 ("PanFlute").
General MIDI instrument 76 ("Blown Bottle").
General MIDI instrument 77 ("Shakuhachi").
General MIDI instrument 78 ("Whistle").
General MIDI instrument 79 ("Ocarina").
General MIDI instrument 80 ("Lead 1 (square)").
General MIDI instrument 81 ("Lead 2 (sawtooth)").
General MIDI instrument 82 ("Lead 3 (calliope)").
General MIDI instrument 83 ("Lead 4 (chiff)").
General MIDI instrument 84 ("Lead 5 (charang)").
General MIDI instrument 85 ("Lead 6 (voice)").
General MIDI instrument 86 ("Lead 7 (fifths)").
General MIDI instrument 87 ("Lead 8 (bass + lead)").
General MIDI instrument 88 ("Pad 1 (new age)").
General MIDI instrument 89 ("Pad 2 (warm)").
General MIDI instrument 90 ("Pad 3 (polysynth)").
General MIDI instrument 91 ("Pad 4 (choir)").
General MIDI instrument 92 ("Pad 5 (bowed)").
General MIDI instrument 93 ("Pad 6 (metallic)").
General MIDI instrument 94 ("Pad 7 (halo)").
General MIDI instrument 95 ("Pad 8 (sweep)").
General MIDI instrument 96 ("FX 1 (rain)").
General MIDI instrument 97 ("FX 2 (soundtrack)").
General MIDI instrument 98 ("FX 3 (crystal)").
General MIDI instrument 99 ("FX 4 (atmosphere)").
General MIDI instrument 100 ("FX 5 (brightness)").
General MIDI instrument 101 ("FX 6 (goblins)").
General MIDI instrument 102 ("FX 7 (echoes)").
General MIDI instrument 103 ("FX 8 (sci-fi)").
General MIDI instrument 104 ("Sitar").
General MIDI instrument 105 ("Banjo").
General MIDI instrument 106 ("Shamisen").
General MIDI instrument 107 ("Koto").
General MIDI instrument 108 ("Kalimba").
General MIDI instrument 109 ("Bagpipe").
General MIDI instrument 110 ("Fiddle").
General MIDI instrument 111 ("Shanai").
General MIDI instrument 112 ("Tinkle Bell").
General MIDI instrument 113 (Agogo"").
General MIDI instrument 114 ("Steel Drums").
General MIDI instrument 115 ("Woodblock").
General MIDI instrument 116 ("Taiko Drum").
General MIDI instrument 117 ("Melodic Tom").
General MIDI instrument 118 ("Synth Drum").
General MIDI instrument 119 ("Reverse Cymbal").
General MIDI instrument 120 ("Guitar Fret Noise").
General MIDI instrument 121 ("Breath Noise").
General MIDI instrument 122 ("Seashore").
General MIDI instrument 123 ("Bird Tweet").
General MIDI instrument 124 ("Telephone Ring").
General MIDI instrument 125 ("Helicopter").
General MIDI instrument 126 ("Applause").
General MIDI instrument 127 ("Gunshot").
Extension methods for the Instrument enum.
Returns true if the specified instrument is valid.
The instrument to test.
Throws an exception if instrument is not valid.
The instrument to validate.
The instrument is out-of-range.
General Midi instrument names, used by GetInstrumentName().
Returns the human-readable name of a MIDI instrument.
The instrument.
The instrument is out-of-range.
Utility functions for encoding and decoding short messages.
Returns true if the given short message describes a Note On message.
The dwParam1 arg passed to MidiInProc.
The dwParam2 arg passed to MidiInProc.
Decodes a Note On short message.
The dwParam1 arg passed to MidiInProc.
The dwParam2 arg passed to MidiInProc.
Filled in with the channel.
Filled in with the pitch.
Filled in with the velocity, 0.127
Filled in with the timestamp in microseconds since
midiInStart().
Encodes a Note On short message.
The channel.
The pitch.
The velocity 0..127.
A value that can be passed to midiOutShortMsg.
pitch is not in MIDI range.
Returns true if the given short message describes a Note Off message.
The dwParam1 arg passed to MidiInProc.
The dwParam2 arg passed to MidiInProc.
Decodes a Note Off short message.
The dwParam1 arg passed to MidiInProc.
The dwParam2 arg passed to MidiInProc.
Filled in with the channel.
Filled in with the pitch.
Filled in with the velocity, 0.127
Filled in with the timestamp in microseconds since
midiInStart().
Encodes a Note Off short message.
The channel.
The pitch.
The velocity 0..127.
A value that can be passed to midiOutShortMsg.
Returns true if the given short message describes a Control Change message.
The dwParam1 arg passed to MidiInProc.
The dwParam2 arg passed to MidiInProc.
Decodes a Control Change short message.
The dwParam1 arg passed to MidiInProc.
The dwParam2 arg passed to MidiInProc.
Filled in with the channel.
Filled in with the control.
Filled in with the value, 0-127.
Filled in with the timestamp in microseconds since
midiInStart().
Encodes a Control Change short message.
The channel.
The control.
The new value 0..127.
A value that can be passed to midiOutShortMsg.
Returns true if the given short message a Program Change message.
The dwParam1 arg passed to MidiInProc.
The dwParam2 arg passed to MidiInProc.
Decodes a Program Change short message.
The dwParam1 arg passed to MidiInProc.
The dwParam2 arg passed to MidiInProc.
Filled in with the channel, 0-15.
Filled in with the instrument, 0-127
Filled in with the timestamp in microseconds since
midiInStart().
Encodes a Program Change short message.
The channel.
The instrument.
A value that can be passed to midiOutShortMsg.
Returns true if the given MidiInProc params describe a Pitch Bend message.
The dwParam1 arg passed to MidiInProc.
The dwParam2 arg passed to MidiInProc.
Decodes a Pitch Bend message based on MidiInProc params.
The dwParam1 arg passed to MidiInProc.
The dwParam2 arg passed to MidiInProc.
Filled in with the channel, 0-15.
Filled in with the pitch bend value, 0..16383, 8192 is centered.
Filled in with the timestamp in microseconds since
midiInStart().
Encodes a Pitch Bend short message.
The channel.
The pitch bend value, 0..16383, 8192 is centered.
A value that can be passed to midiOutShortMsg.
Pitches supported by MIDI.
MIDI defines 127 distinct pitches, in semitone intervals, ranging from C five octaves
below middle C, up to G five octaves above middle C. This covers several octaves above and
below the range of a normal 88-key piano.
These 127 pitches are the only ones directly expressible in MIDI. Precise
variations in frequency can be achieved with Pitch
Bend messages, though Pitch Bend messages apply to the whole channel at once.
In this enum, pitches are given C Major note names (eg "F", "GSharp") followed
by the octave number. Octaves use standard piano terminology: Middle C is in
octave 4. (Note that this is different from "MIDI octaves", which have Middle C in
octave 0.)
This enum has extension methods, such as
and
, defined in
.
C in octave -1.
C# in octave -1.
D in octave -1.
D# in octave -1.
E in octave -1.
F in octave -1.
F# in octave -1.
G in octave -1.
G# in octave -1.
A in octave -1.
A# in octave -1.
B in octave -1.
C in octave 0.
C# in octave 0.
D in octave 0.
D# in octave 0.
E in octave 0.
F in octave 0.
F# in octave 0.
G in octave 0.
G# in octave 0.
A in octave 0.
A# in octave 0, usually the lowest key on an 88-key keyboard.
B in octave 0.
C in octave 1.
C# in octave 1.
D in octave 1.
D# in octave 1.
E in octave 1.
F in octave 1.
F# in octave 1.
G in octave 1.
G# in octave 1.
A in octave 1.
A# in octave 1.
B in octave 1.
C in octave 2.
C# in octave 2.
D in octave 2.
D# in octave 2.
E in octave 2.
F in octave 2.
F# in octave 2.
G in octave 2.
G# in octave 2.
A in octave 2.
A# in octave 2.
B in octave 2.
C in octave 3.
C# in octave 3.
D in octave 3.
D# in octave 3.
E in octave 3.
F in octave 3.
F# in octave 3.
G in octave 3.
G# in octave 3.
A in octave 3.
A# in octave 3.
B in octave 3.
C in octave 4, also known as Middle C.
C# in octave 4.
D in octave 4.
D# in octave 4.
E in octave 4.
F in octave 4.
F# in octave 4.
G in octave 4.
G# in octave 4.
A in octave 4.
A# in octave 4.
B in octave 4.
C in octave 5.
C# in octave 5.
D in octave 5.
D# in octave 5.
E in octave 5.
F in octave 5.
F# in octave 5.
G in octave 5.
G# in octave 5.
A in octave 5.
A# in octave 5.
B in octave 5.
C in octave 6.
C# in octave 6.
D in octave 6.
D# in octave 6.
E in octave 6.
F in octave 6.
F# in octave 6.
G in octave 6.
G# in octave 6.
A in octave 6.
A# in octave 6.
B in octave 6.
C in octave 7.
C# in octave 7.
D in octave 7.
D# in octave 7.
E in octave 7.
F in octave 7.
F# in octave 7.
G in octave 7.
G# in octave 7.
A in octave 7.
A# in octave 7.
B in octave 7.
C in octave 8, usually the highest key on an 88-key keyboard.
C# in octave 8.
D in octave 8.
D# in octave 8.
E in octave 8.
F in octave 8.
F# in octave 8.
G in octave 8.
G# in octave 8.
A in octave 8.
A# in octave 8.
B in octave 8.
C in octave 9.
C# in octave 9.
D in octave 9.
D# in octave 9.
E in octave 9.
F in octave 9.
F# in octave 9.
G in octave 9.
Extension methods for the Pitch enum.
Returns true if pitch is in the MIDI range [1..127].
The pitch to test.
True if the pitch is in [0..127].
Returns the octave containing this pitch.
The pitch.
The octave, where octaves begin at each C, and Middle C is the first pitch in
octave 4.
Returns the position of this pitch in its octave.
The pitch.
The pitch's position in its octave, where octaves start at each C, so C's
position is 0, C#'s position is 1, etc.
Maps PositionInOctave() to a Note preferring sharps.
Maps PositionInOctave() to a Note preferring flats.
Returns the simplest note that resolves to this pitch, preferring sharps where needed.
The pitch.
The simplest note for that pitch. If that pitch is a "white key", the note
is simply a letter with no accidentals (and is the same as
). Otherwise the note has a sharp.
Returns the simplest note that resolves to this pitch, preferring flats where needed.
The pitch.
The simplest note for that pitch. If that pitch is a "white key", the note
is simply a letter with no accidentals (and is the same as
). Otherwise the note has a flat.
Returns the note that would name this pitch if it used the given letter.
The pitch being named.
The letter to use in the name, in ['A'..'G'].
The note for pitch with letter. The result may have a large number of
accidentals if pitch is not easily named by letter.
letter is out of range.
A time-sorted queue of MIDI messages.
Messages can be added in any order, and can be popped off in timestamp order.
Constructs an empty message queue.
Adds a message to the queue.
The message to add to the queue.
The message must have a valid timestamp (not MidiMessage.Now), but other than that
there is no restriction on the timestamp. For example, it is legal to add a message with
a timestamp earlier than some other message which was previously removed from the queue.
Such a message would become the new "earliest" message, and so would be be the first message
returned by PopEarliest().
Discards all messages in the queue.
Removes and returns the message(s) in the queue that have the earliest timestamp.
True if the queue is empty.
The timestamp of the earliest messsage(s) in the queue.
Throws an exception if the queue is empty.
General MIDI percussion note.
In General MIDI, notes played on make the following
percussion sounds, regardless of any Program
Change messages on that channel.
This enum is used with OutputDevice.SendPercussion
and . Equivalently, when cast to
it can be used with OutputDevice.SendNoteOn and
on .
This enum has extension methods, such as
and , defined in
.
General MIDI percussion 35 ("Bass Drum 2").
General MIDI percussion 36 ("Bass Drum 1").
General MIDI percussion 37 ("Side Stick").
General MIDI percussion 38 ("Snare Drum 1").
General MIDI percussion 39 ("Hand Clap").
General MIDI percussion 40 ("Snare Drum 2").
General MIDI percussion 41 ("Low Tom 2").
General MIDI percussion 42 ("Closed Hi-hat").
General MIDI percussion 43 ("Low Tom 1").
General MIDI percussion 44 ("Pedal Hi-hat").
General MIDI percussion 45 ("Mid Tom 2").
General MIDI percussion 46 ("Open Hi-hat").
General MIDI percussion 47 ("Mid Tom 1").
General MIDI percussion 48 ("High Tom 2").
General MIDI percussion 49 ("Crash Cymbal 1").
General MIDI percussion 50 ("High Tom 1").
General MIDI percussion 51 ("Ride Cymbal 1").
General MIDI percussion 52 ("Chinese Cymbal").
General MIDI percussion 53 ("Ride Bell").
General MIDI percussion 54 ("Tambourine").
General MIDI percussion 55 ("Splash Cymbal").
General MIDI percussion 56 ("Cowbell").
General MIDI percussion 57 ("Crash Cymbal 2").
General MIDI percussion 58 ("Vibra Slap").
General MIDI percussion 59 ("Ride Cymbal 2").
General MIDI percussion 60 ("High Bongo").
General MIDI percussion 61 ("Low Bongo").
General MIDI percussion 62 ("Mute High Conga").
General MIDI percussion 63 ("Open High Conga").
General MIDI percussion 64 ("Low Conga").
General MIDI percussion 65 ("High Timbale").
General MIDI percussion 66 ("Low Timbale").
General MIDI percussion 67 ("High Agogo").
General MIDI percussion 68 ("Low Agogo").
General MIDI percussion 69 ("Cabasa").
General MIDI percussion 70 ("Maracas").
General MIDI percussion 71 ("Short Whistle").
General MIDI percussion 72 ("Long Whistle").
General MIDI percussion 73 ("Short Guiro").
General MIDI percussion 74 ("Long Guiro").
General MIDI percussion 75 ("Claves").
General MIDI percussion 76 ("High Wood Block").
General MIDI percussion 77 ("Low Wood Block").
General MIDI percussion 78 ("Mute Cuica").
General MIDI percussion 79 ("Open Cuica").
General MIDI percussion 80 ("Mute Triangle").
General MIDI percussion 81 ("Open Triangle").
Extension methods for the Percussion enum.
Be sure to "using midi" if you want to use these as extension methods.
Returns true if the specified percussion is valid.
The percussion to test.
Throws an exception if percussion is not valid.
The percussion to validate.
The percussion is out-of-range.
Returns the human-readable name of a MIDI percussion.
The percussion.
A letter and accidental, which together form an octave-independent note.
This class lets you define a note by combining a letters A-G with accidentals
(sharps and flats). Examples of notes are D, B#, and Gbb. This is the conventional
way to refer to notes in an octave independent way.
Each note unambiguously identifies a pitch (modulo octave), but each pitch has
potentially many notes. For example, the notes F, E#, D###, and Gbb all resolve to the
same pitch, though the last two names are unlikely to be used in practice.
Double-flat accidental value.
Flat accidental value.
Natural accidental value.
Sharp accidental value.
Double-sharp accidental value.
Constructs a note from a letter.
The letter, which must be in ['A'..'G'].
letter is out of range.
Constructs a note from a string.
The name to parse. Must begin with a letter in ['A'..'G'],
then optionally be followed by a series of '#' (sharps) or a series of 'b' (flats).
name is null.
name cannot be parsed.
Constructs a note name from a letter and accidental.
The letter, which must be in ['A'..'G'].
The accidental. Zero means natural, positive values are
sharp by that many semitones, and negative values are flat by that many semitones.
Likely values are (0), (1),
(2), (-1), and
(-2).
letter is out of range.
ToString returns the note name.
The note name with '#' for sharp and 'b' for flat. For example, "G", "A#",
"Cb", "Fbb".
Parses a Note from s, starting at position pos.
The string to parse from.
The position to start at. On success, advances pos to after the
end of the note.
The note.
A note cannot be parsed.
This function must find a valid letter at s[pos], and then optionally a
sequence of '#' (sharps) or 'b' (flats). It finds as many of the accidental as it can
and then stops at the first character that can't be part of the accidental.
Returns true if this note name is enharmonic with otherNote.
Another note.
True if the names can refer to the same pitch.
Returns the pitch for this note in the specified octave.
The octave, where octaves begin at each C and Middle C is the
first note in octave 4.
The pitch with this name in the specified octave.
Returns the pitch for this note that is at or above nearPitch.
The pitch from which the search is based.
The pitch for this note at or above nearPitch.
Returns the pitch for this note that is at or below nearPitch.
The pitch from which the search is based.
The pitch for this note at or below nearPitch.
Returns the number of semitones it takes to move up to the next otherNote.
The other note.
The number of semitones.
Returns the number of semitones it takes to move down to the next otherNote.
The other note.
The number of semitones.
Equality operator does value comparison.
Inequality operator does value comparison.
Value equality for Note.
Hash code.
Table mapping (letter-'A') to the Note in octave -1, used to compute positionInOctave.
The letter for this note name, in ['A'..'G'].
The accidental for this note name.
Zero means natural, positive values are
sharp by that many semitones, and negative values are flat by that many semitones.
Likely values are (0), (1),
(2), (-1), and
(-2).
This note's position in the octave, where octaves start at each C.
A MIDI output device.
Each instance of this class describes a MIDI output device installed on the system.
You cannot create your own instances, but instead must go through the
property to find which devices are available. You may wish
to examine the property of each one and present the user with
a choice of which device to use.
Open an output device with and close it with .
While it is open, you may send MIDI messages with functions such as
, and .
All notes may be silenced on the device by calling .
Note that the above methods send their messages immediately. If you wish to arrange
for a message to be sent at a specific future time, you'll need to instantiate some subclass
of (eg ) and then pass it to
Clock.Schedule.
Opens this output device.
The device is already open.
The device cannot be opened.
Closes this output device.
The device is not open.
The device cannot be closed.
Silences all notes on this output device.
The device is not open.
The message cannot be sent.
Sends a Note On message to this MIDI output device.
The channel.
The pitch.
The velocity 0..127.
channel, pitch, or velocity is
out-of-range.
The device is not open.
The message cannot be sent.
Sends a Note Off message to this MIDI output device.
The channel.
The pitch.
The velocity 0..127.
channel, note, or velocity is
out-of-range.
The device is not open.
The message cannot be sent.
Sends a Note On message to Channel10 of this MIDI output device.
The percussion.
The velocity 0..127.
This is simply shorthand for a Note On message on Channel10 with a
percussion-specific note, so there is no corresponding message to receive from an input
device.
percussion or velocity is out-of-range.
The device is not open.
The message cannot be sent.
Sends a Control Change message to this MIDI output device.
The channel.
The control.
The new value 0..127.
channel, control, or value is
out-of-range.
The device is not open.
The message cannot be sent.
Sends a Pitch Bend message to this MIDI output device.
The channel.
The pitch bend value, 0..16383, 8192 is centered.
channel or value is out-of-range.
The device is not open.
The message cannot be sent.
Sends a Program Change message to this MIDI output device.
The channel.
The instrument.
channel or instrument is out-of-range.
The device is not open.
The message cannot be sent.
A Program Change message is used to switch among instrument settings, generally
instrument voices. An instrument conforming to General Midi 1 will have the
instruments described in the enum; other instruments
may have different instrument sets.
Makes sure rc is MidiWin32Wrapper.MMSYSERR_NOERROR. If not, throws an exception with an
appropriate error message.
Throws a MidiDeviceException if this device is not open.
Throws a MidiDeviceException if this device is open.
Private Constructor, only called by the getter for the InstalledDevices property.
Position of this device in the list of all devices.
Win32 Struct with device metadata
Private method for constructing the array of MidiOutputDevices by calling the Win32 api.
List of devices installed on this system.
True if this device is open.
MIDI Control, used in Control Change messages.
In MIDI, Control Change messages are used to influence various auxiliary "controls"
on a device, such as knobs, levers, and pedals. Controls are specified with
integers in [0..127]. This enum provides an incomplete list of controls, because
most controls are too obscure to document effetively here. Even for the ones listed
here, the details of how the value is interpreted are arcane. Please see the MIDI spec for
details.
The most commonly used control is SustainPedal, which is considered off when < 64,
on when > 64.
This enum has extension methods, such as
and , defined in
.
General MIDI Control--See MIDI spec for details.
General MIDI Control--See MIDI spec for details.
General MIDI Control--See MIDI spec for details.
General MIDI Control--See MIDI spec for details.
General MIDI Control--See MIDI spec for details.
General MIDI Control--See MIDI spec for details.
General MIDI Control--See MIDI spec for details.
General MIDI Control--See MIDI spec for details.
General MIDI Control--See MIDI spec for details.
General MIDI Control--See MIDI spec for details.
General MIDI Control--See MIDI spec for details.
General MIDI Control--See MIDI spec for details.
General MIDI Control--See MIDI spec for details.
General MIDI Control--See MIDI spec for details.
General MIDI Control--See MIDI spec for details.
General MIDI Control--See MIDI spec for details.
General MIDI Control--See MIDI spec for details.
General MIDI Control--See MIDI spec for details.
Extension methods for the Control enum.
Be sure to "using midi" if you want to use these as extension methods.
Returns true if the specified control is valid.
The Control to test.
Throws an exception if control is not valid.
The control to validate.
The control is out-of-range.
Table of control names.
Returns the human-readable name of a MIDI control.
The control.
The control is out-of-range.
C# wrappers for the Win32 MIDI API.
Because .NET does not provide MIDI support itself, in C# we must use P/Invoke to wrap the
Win32 API. That API consists of the MMSystem.h C header and the winmm.dll library. The API
is described in detail here: http://msdn.microsoft.com/en-us/library/ms712733(VS.85).aspx.
The P/Invoke interop mechanism is described here:
http://msdn.microsoft.com/en-us/library/aa288468(VS.71).aspx.
This file covers the subset of the MIDI protocol needed to manage input and output devices
and send and receive Note On/Off, Control Change, Pitch Bend and Program Change messages.
Other portions of the MIDI protocol (such as sysex events) are supported in the Win32 API
but are not wrapped here.
Some of the C functions are not typesafe when wrapped, so those wrappers are made private
and typesafe variants are provided.
Max length of a manufacturer name in the Win32 API.
Returns the number of MIDI output devices on this system.
Win32 docs: http://msdn.microsoft.com/en-us/library/ms711627(VS.85).aspx
Fills in the capabilities struct for a specific output device.
NOTE: This is adapted from the original Win32 function in order to make it typesafe.
Win32 docs: http://msdn.microsoft.com/en-us/library/ms711621(VS.85).aspx
Opens a MIDI output device.
NOTE: This is adapted from the original Win32 function in order to make it typesafe.
Win32 docs: http://msdn.microsoft.com/en-us/library/ms711632(VS.85).aspx
Turns off all notes and sustains on a MIDI output device.
Win32 docs: http://msdn.microsoft.com/en-us/library/dd798479(VS.85).aspx
Closes a MIDI output device.
Win32 docs: http://msdn.microsoft.com/en-us/library/ms711620(VS.85).aspx
Sends a short MIDI message (anything but sysex or stream).
Win32 docs: http://msdn.microsoft.com/en-us/library/ms711640(VS.85).aspx
Gets the error text for a return code related to an output device.
NOTE: This is adapted from the original Win32 function in order to make it typesafe.
Win32 docs: http://msdn.microsoft.com/en-us/library/ms711622(VS.85).aspx
Returns the number of MIDI input devices on this system.
Win32 docs: http://msdn.microsoft.com/en-us/library/ms711608(VS.85).aspx
Fills in the capabilities struct for a specific input device.
NOTE: This is adapted from the original Win32 function in order to make it typesafe.
Win32 docs: http://msdn.microsoft.com/en-us/library/ms711604(VS.85).aspx
Opens a MIDI input device.
NOTE: This is adapted from the original Win32 function in order to make it typesafe.
Win32 docs: http://msdn.microsoft.com/en-us/library/ms711610(VS.85).aspx
Starts input on a MIDI input device.
Win32 docs: http://msdn.microsoft.com/en-us/library/ms711614(VS.85).aspx
Stops input on a MIDI input device.
Win32 docs: http://msdn.microsoft.com/en-us/library/ms711615(VS.85).aspx
Resets input on a MIDI input device.
Win32 docs: http://msdn.microsoft.com/en-us/library/ms711613(VS.85).aspx
Closes a MIDI input device.
Win32 docs: http://msdn.microsoft.com/en-us/library/ms711602(VS.85).aspx
Gets the error text for a return code related to an input device.
NOTE: This is adapted from the original Win32 function in order to make it typesafe.
Win32 docs: http://msdn.microsoft.com/en-us/library/ms711605(VS.85).aspx
Status type returned from most functions in the Win32 API.
Flags passed to midiInOpen() and midiOutOpen().
Values for wTechnology field of MIDIOUTCAPS structure.
Flags for dwSupport field of MIDIOUTCAPS structure.
"Midi Out Messages", passed to wMsg param of MidiOutProc.
"Midi In Messages", passed to wMsg param of MidiInProc.
Win32 handle for a MIDI output device.
Win32 handle for a MIDI input device.
Struct representing the capabilities of an output device.
Win32 docs: http://msdn.microsoft.com/en-us/library/ms711619(VS.85).aspx
Struct representing the capabilities of an input device.
Win32 docs: http://msdn.microsoft.com/en-us/library/ms711596(VS.85).aspx
Callback invoked when a MIDI output device is opened, closed, or finished with a buffer.
Win32 docs: http://msdn.microsoft.com/en-us/library/ms711637(VS.85).aspx
Callback invoked when a MIDI event is received from an input device.
Win32 docs: http://msdn.microsoft.com/en-us/library/ms711612(VS.85).aspx
Interval measuring the relationship between pitches.
This enum is simply for making interval operations more explicit. When adding to or
subtracting from the enum, one can either use ints...
Pitch p = Pitch.C4 + 5;
...or use the Interval enum, cast to int...
Pitch p = Pitch.C4 + (int)Interval.PerfectFourth;
These two examples are equivalent. The benefit of the latter is simply that it makes
the intention more explicit.
This enum has extension methods, such as ,
defined in .
Unison interval, 0 semitones
Semitone interval, 1 semitone
Whole Tone interval, 2 semitones
Minor Third interval, 3 semitones
Major Third interval, 4 semitones
Perfect Fourth interval, 5 semitones
Tritone interval, 6 semitones
Perfect Fifth interval, 7 semitones
Minor Sixth interval, 8 semitones
Major Sixth interval, 9 semitones
Minor seventh interval, 10 semitones
Major Seventh interval, 11 semitones
Octave interval, 12 semitones
Extension methods for the Interval enum.
Table of interval names.
Returns the human-readable name of an interval.
The interval.
The human-readable name. If the interval is less than an octave, it gives
the standard term (eg, "Major third"). If the interval is more than an octave, it
gives the number of semitones in the interval.
A MIDI input device.
Each instance of this class describes a MIDI input device installed on the system.
You cannot create your own instances, but instead must go through the
property to find which devices are available. You may wish
to examine the property of each one and present the user with
a choice of which device(s) to use.
Open an input device with and close it with .
While it is open, you may arrange to start receiving messages with
and then stop receiving them with .
An input device can only receive messages when it is both open and started.
Incoming messages are routed to the corresponding events, such as
and . The event handlers are invoked on a background thread
which is started in and stopped in .
As each message is received, it is assigned a timestamp in one of two ways. If
is called with a , then each message is
assigned a time by querying the clock's property. If
is called with null, then each message is assigned a time
based on the number of seconds since was called.
Removes all event handlers from the input events on this device.
Opens this input device.
The device is already open.
The device cannot be opened.
Note that Open() establishes a connection to the device, but no messages will
be received until is called.
Closes this input device.
The device is not open or is still
receiving.
The device cannot be closed.
Starts this input device receiving messages.
If non-null, the clock's property will
be used to assign a timestamp to each incoming message. If null, timestamps will be in
seconds since StartReceiving() was called.
The device is not open or is already
receiving.
The device cannot start receiving.
This method launches a background thread to listen for input events, and as events
are received, the event handlers are invoked on that background thread. Event handlers
should be written to work from a background thread. (For example, if they want to
update the GUI, they may need to BeginInvoke to arrange for GUI updates to happen on
the correct thread.)
The background thread which is created by this method is joined (shut down) in
.
Stops this input device from receiving messages.
This method waits for all in-progress input event handlers to finish, and then
joins (shuts down) the background thread that was created in
. Thus, when this function returns you can be sure that no
more event handlers will be invoked.
It is illegal to call this method from an input event handler (ie, from the
background thread), and doing so throws an exception. If an event handler really needs
to call this method, consider using BeginInvoke to schedule it on another thread.
The device is not open; is not receiving;
or called from within an event handler (ie, from the background thread).
The device cannot start receiving.
Makes sure rc is MidiWin32Wrapper.MMSYSERR_NOERROR. If not, throws an exception with an
appropriate error message.
Throws a MidiDeviceException if this device is not open.
Throws a MidiDeviceException if this device is open.
Throws a MidiDeviceException if this device is not receiving.
Throws a MidiDeviceException if this device is receiving.
Private Constructor, only called by the getter for the InstalledDevices property.
Position of this device in the list of all devices.
Win32 Struct with device metadata
Private method for constructing the array of MidiInputDevices by calling the Win32 api.
The input callback for midiOutOpen.
Thread-local, set to true when called by an input handler, false in all other threads.
Event called when an input device receives a Note On message.
Event called when an input device receives a Note Off message.
Event called when an input device receives a Control Change message.
Event called when an input device receives a Program Change message.
Event called when an input device receives a Pitch Bend message.
List of input devices installed on this system.
True if this device has been successfully opened.
True if this device is receiving messages.
Delegate called when an input device receives a Note On message.
Delegate called when an input device receives a Note Off message.
Delegate called when an input device receives a Control Change message.
Delegate called when an input device receives a Program Change message.
Delegate called when an input device receives a Pitch Bend message.
A MIDI Channel.
Each MIDI device has 16 independent channels. Channels are named starting at 1, but
are encoded programmatically starting at 0.
All of the channels are general-purpose except for Channel10, which is the
dedicated percussion channel. Any notes sent to that channel will play
percussion notes, regardless of any
Program Change messages sent on that
channel.
This enum has extension methods, such as
and , defined in
.
MIDI Channel 1.
MIDI Channel 2.
MIDI Channel 3.
MIDI Channel 4.
MIDI Channel 5.
MIDI Channel 6.
MIDI Channel 7.
MIDI Channel 8.
MIDI Channel 9.
MIDI Channel 10, the dedicated percussion channel.
MIDI Channel 11.
MIDI Channel 12.
MIDI Channel 13.
MIDI Channel 14.
MIDI Channel 15.
MIDI Channel 16.
Extension methods for the Channel enum.
Returns true if the specified channel is valid.
The channel to test.
Throws an exception if channel is not valid.
The channel to validate.
The channel is out-of-range.
Table of channel names.
Returns the human-readable name of a MIDI channel.
The channel.
The channel is out-of-range.
A clock for scheduling MIDI messages in a rate-adjustable, pausable timeline.
Clock is used for scheduling MIDI messages. Though you can always send messages
synchronously with the various .Send* methods, doing so
requires your code to be "ready" at the precise moment each message needs to
be sent. In most cases, and especially in interactive programs, it's more convenient
to describe messages that will be sent at specified points in the future, and then
rely on a scheduler to make it happen. Clock is such a scheduler.
Basic usage
In the simplest case, Clock can be used to schedule a sequence of messages which is
known in its entirety ahead of time. For example, this code snippet schedules two notes to
play one after the other:
Clock clock(120); // beatsPerMinute=120
OutputDevice outputDevice = ...;
clock.Schedule(new NoteOnMessage(outputDevice, Channel.Channel1, Note.E4, 80, 0));
clock.Schedule(new NoteOffMessage(outputDevice, Channel.Channel1, Note.E4, 80, 1));
clock.Schedule(new NoteOnMessage(outputDevice, Channel.Channel1, Note.D4, 80, 1));
clock.Schedule(new NoteOffMessage(outputDevice, Channel.Channel1, Note.D4, 80, 2));
At this point, four messages have been scheduled, but they haven't been sent because
the clock has not started. We can start the clock with , pause it with
, and reset it with . We can change the
beats-per-minute at any time, even as the sequence is playing. And the playing happens
in a background thread, so your client code can focus on arranging the notes and controlling
the clock.
You can even schedule new notes as the clock is playing. Generally you should
schedule messages for times in the future; scheduling a message with a time in the past
simply causes it to play immediately, which is probably not what you wanted.
NoteOnOffMessage and Self-Propagating Messages
In the above example, we wanted to play two notes but had to schedule four messages.
This case is so common that we provide a convenience class, ,
which encapsulates a Note On message and its corresponding Note Off message in a single
unit. We could rewrite the above example as follows:
Clock clock(120); // beatsPerMinute=120
OutputDevice outputDevice = ...;
clock.Schedule(new NoteOnOffMessage(outputDevice, Channel.Channel1, Note.E4, 80, 0, 1));
clock.Schedule(new NoteOnOffMessage(outputDevice, Channel.Channel1, Note.D4, 80, 1, 1));
This works because each NoteOnOffMessage, when it is actually sent, does two things:
it sends the Note On message to the output device, and also schedules the
correponding Note Off message for the appropriate time in the future. This is an example
of a self-propagating message: a message which, when triggered, schedules additional
events for the future.
You can design your own self-propagating messages by subclassing from
. For example, you could make a self-propagating MetronomeMessage
which keeps a steady beat by always scheduling the next MetronomeMessage when it
plays the current beat. However, subclassing can be tedious, and it is usually preferable
to use to call-out to your own code instead.
Constructs a midi clock with a given beats-per-minute.
The initial beats-per-minute, which can be changed later.
When constructed, the clock is not running, and so will
return zero. Call when you are ready for the clock to start
progressing (and scheduled messages to actually trigger).
beatsPerMinute is non-positive
Starts or resumes the clock.
This method causes the clock to start progressing at the rate given in the
property. It may only be called when the clock is
not yet rnuning.
If this is the first time Start is called,
the clock starts at time zero and progresses from there. If the clock was previously
started, stopped, and not reset, then Start effectively "unpauses" the clock, picking up
at the left-off time, and resuming scheduling of any as-yet-unsent messages.
This method creates a new thread which runs in the background and sends
messages at the appropriate times. All
Message.SendNow methods and
s will be called in that thread.
The scheduler thread is joined (shut down) in .
Clock is already running.
Stops the clock (but does not reset its time or discard pending events).
This method stops the progression of the clock. It may only be called when
the clock is running.
Any scheduled but as-yet-unsent messages remain in the queue. A consecutive call
to can re-start the progress of the clock, or
can discard pending messages and reset the clock to zero.
This method waits for any in-progress messages to be processed and joins
(shuts down) the scheduler thread before returning, so when it returns you can be sure
that no more messages will be sent or callbacks invoked.
It is illegal to call Stop from the scheduler thread (ie, from any
Message.SendNow method or
. If a callback really needs to stop the clock,
consider using BeginInvoke to arrange for it to happen in another thread.
Clock is not running or Stop was invoked
from the scheduler thread.
Resets the clock to zero and discards pending messages.
This method resets the clock to zero and discards any scheduled but
as-yet-unsent messages. It may only be called when the clock is not running.
Clock is running.
Schedules a single message based on its beatTime.
The message to schedule.
This method schedules a message to be sent at the time indicated in the message's
property. It may be called at any time, whether
the clock is running or not. The message will not be sent until the clock progresses
to the specified time. (If the clock is never started, or is paused before that time
and not re-started, then the message will never be sent.)
If a message is scheduled for a time that has already passed, then the scheduler
will send the message at the first opportunity.
Schedules a collection of messages, applying an optional time delta to the scheduled
beatTime.
The message to send
The delta to apply (or zero).
Returns the number of milliseconds from now until the specified beat time.
The beat time.
The positive number of milliseconds, or 0 if beatTime is in the past.
Worker thread function.
Thread-local, set to true in the scheduler thread, false in all other threads.
This clock's current time in beats.
Normally, this method polls the clock's current time, and thus changes from
moment to moment as long as the clock is running. However, when called from the
scheduler thread (that is, from a Message.SendNow
method or a ), it returns the precise time at which the
message was scheduled.
For example, suppose a callback was scheduled for time T, and the scheduler
managed to call that callback at time T+delta. In the callback, Time will
return T for the duration of the callback. In any other thread, Time would
return approximately T+delta.
Beats per minute property.
Setting this property changes the rate at which the clock progresses. If the
clock is currently running, the new rate is effectively immediately.
Returns true if this clock is currently running.