public void AddMidiEvent(MidiMessage midiMsg)
 {
     midiMsg.delta = 0;
     synth.midiEventQueue.Enqueue(midiMsg);
     synth.midiEventCounts[0]++;
 }
 //--Private Methods
 private void LoadMidiFile(MidiFile midiFile)
 {
     //Converts midi to sample based format for easy sequencing
     double BPM = 120.0;
     //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();
     mdata = new MidiMessage[midiFile.Tracks[0].MidiEvents.Length];
     //Convert delta time to sample time
     eventIndex = 0;
     sampleTime = 0;
     //Calculate sample based time using double counter and round down to nearest integer sample.
     double absDelta = 0.0;
     for (int x = 0; x < mdata.Length; x++)
     {
         MidiEvent mEvent = midiFile.Tracks[0].MidiEvents[x];
         mdata[x] = new MidiMessage((byte)mEvent.Channel, (byte)mEvent.Command, (byte)mEvent.Data1, (byte)mEvent.Data2);
         absDelta += synth.SampleRate * mEvent.DeltaTime * (60.0 / (BPM * midiFile.Division));
         mdata[x].delta = (int)absDelta;
         //Update tempo
         if (mEvent.Command == 0xFF && mEvent.Data1 == 0x51)
             BPM = Math.Round(MidiHelper.MicroSecondsPerMinute / (double)((MetaNumberEvent)mEvent).Value, 2);
     }
     //Set total time to proper value
     totalTime = mdata[mdata.Length - 1].delta;
 }