private void LoadMidiFile(MidiFile midiFile)
{
_tempoChanges = new FastList<MidiFileSequencerTempoChange>();
//Converts midi to sample based format for easy sequencing
float bpm = 120.0f;
//Combine all tracks into 1 track that is organized from lowest to highest absolute time
if (midiFile.Tracks.Length > 1 || midiFile.Tracks[0].EndTime == 0)
midiFile.CombineTracks();
//Convert delta time to sample time
_synthData = new SynthEvent[midiFile.Tracks[0].MidiEvents.Length];
_division = midiFile.Division;
_eventIndex = 0;
CurrentTime = 0;
CurrentTempo = (int)bpm;
//Calculate sample based time using double counter and round down to nearest integer sample.
var absDelta = 0.0;
var absTick = 0;
var absTime = 0.0;
for (int x = 0; x < midiFile.Tracks[0].MidiEvents.Length; x++)
{
var mEvent = midiFile.Tracks[0].MidiEvents[x];
_synthData[x] = new SynthEvent(mEvent);
absTick += mEvent.DeltaTime;
absTime += mEvent.DeltaTime * (60000.0 / (bpm * midiFile.Division));
absDelta += Synth.SampleRate * mEvent.DeltaTime * (60.0 / (bpm * midiFile.Division));
_synthData[x].Delta = (int)(absDelta);
//Update tempo
if (IsTempoMessage(mEvent.Command, mEvent.Data1))
{
var meta = (MetaNumberEvent)mEvent;
bpm = MidiHelper.MicroSecondsPerMinute / meta.Value;
_tempoChanges.Add(new MidiFileSequencerTempoChange(bpm, absTick, (int)(absTime)));
}
}
EndTime = _synthData[_synthData.Length - 1].Delta;
}