Delta-times
Time attached to every event in a MIDI file is an offset from the previous event. This offset is called delta-time.
As said by Hans Passant it is stored in a file before an event in special form called variable-length quantity (VLQ). Yes, standard says that VLQ representations must fit in 32 bits (4 bytes). But, theoretically (and there are some real files on the web), larger numbers are possible, so it is much better if a library which provides MIDI file parsing uses integer type bigger than regular int
. long
for the AbsoluteTime
in NAudio is a good choice.
Absolute time
AbsoluteTime
property returns just sum of all preceding delta-times and the current event's one.
Meaning of time
What every delta-time or an absolute one actually means depends on time division of a MIDI file. There are two different types of time division:
- Ticks Per Quarter Note
- SMPTE Time Division
In first case all times expressed as number of ticks. For example, if division is 96, then a delta-time of 48 defines interval of an eighth-note. As also said by Hans Passant NAudio exposes it as the MidiFile.DeltaTicksPerQuarterNote
property
In second case all times expressed as number of subdivisions of a second in a way consistent with SMPTE and MIDI Time Code. In practice it is very very very rare type of time division.
"Understandable" representations of time
I think the most "understandable" format for time is metric time (hours, minutes, seconds). As said by Hans Passant and CL you need to know changes of tempo through a MIDI file to calculate metric time of a MIDi event.
There are some libraries that do this calculation for you. For example, with DryWetMIDI you can get metric time of an event with this code:
MidiFile midiFile = MidiFile.Read("Some MIDI file.mid");
TempoMap tempoMap = midiFile.GetTempoMap();
MetricTimeSpan timeOf10thEvent = midiFile.GetTimedEvents()
.Skip(9)
.First()
.TimeAs<MetricTimeSpan>(tempoMap);
With this library you can also get time as bars, beats (using BarBeatTicksTimeSpan
or BarBeatFractionTimeSpan
) or a fraction of the whole note's length (using MusicalTimeSpan
).
Calculation of musical time uses changes of time signature. Both tempo and time signature changes provided by tempo map of a MIDI file that can be obtained with GetTempoMap
extension method for MidiFile
.