Tempo map
Tempo map is a set of changes of time signature and tempo. Tempo map is one of the key objects in high-level management of MIDI data. You need to have a tempo map to convert time and length between different representations, either explicitly or internally at some parts of the library (for example, in tools). Following image shows how tempo map constructed for a given set of events or MIDI file:
So as you can see a tempo map doesn't reflect original MIDI events. Tempo map holds real tempo and time signature changes. Default tempo is 120 BPM by MIDI specifications so there is no need to hold first two tempo "changes" because tempo is not changed in fact. The same for time signature (which is 4/4
by default). Also any repeated values are ignored since they don't change tempo or time signature.
Instead of messing with Time Signature and Set Tempo events DryWetMIDI provides TempoMapManager which helps to manage tempo map of a MIDI file:
using (var tempoMapManager = new TempoMapManager(
midiFile.TimeDivision,
midiFile.GetTrackChunks().Select(c => c.Events)))
{
TempoMap tempoMap = tempoMapManager.TempoMap;
Tempo tempoAt123 = tempoMap.GetTempoAtTime((MidiTimeSpan)123);
// Change tempo to 400000 microseconds per quarter note at 20 seconds from
// MIDI file start
tempoMapManager.SetTempo(new MetricTimeSpan(0, 0, 20), new Tempo(400000));
tempoMapManager.ClearTimeSignature(456);
}
To get the tempo map being managed by the current TempoMapManager
you need to use TempoMap property which returns an instance of the TempoMap class.
Once you've got an instance of TempoMap you can use the GetTempoChanges method to get all tempo changes. Use GetTimeSignatureChanges method to get time signature changes. GetTempoAtTime and GetTimeSignatureAtTime methods allow to get tempo and time signature at the specified time.
You can also create new tempo map with TempoMapManager
:
using (var tempoMapManager = new TempoMapManager())
{
// ...
}
If you want to create a simple tempo map with some fixed tempo or/and time signature without changes, use Create static methods of the TempoMap
class.
There is another way to get an instance of the TempoMapManager
– through the ManageTempoMap extension method:
using (var tempoMapManager = midiFile.ManageTempoMap())
{
// ...
}
This method and other useful ones are placed in TempoMapManagingUtilities. For example, to get tempo map of a MIDI file you can write:
TempoMap tempoMap = midiFile.GetTempoMap();
Also you can replace the entire tempo map of a MIDI file using ReplaceTempoMap method:
midiFile.ReplaceTempoMap(TempoMap.Create(Tempo.FromBeatsPerMinute(140)));