public void addTempo(Tempo tempo) { //insert the tempo into the tempo list int pos = 0; if (tempo.tick > tempos[tempos.Count - 1].tick) //if tempo goes at end of list { tempos.Add(tempo); pos = tempos.Count - 1; } else { while ((pos < tempos.Count) && (tempo.tick > tempos[pos].tick)) { pos++; } if (tempo.tick == tempos[pos].tick) //if we already have a temp change at this tick, replace it { tempos[pos] = tempo; } else { tempos.Insert(pos, tempo); //else insert new tempo change into list at this pos } } count = tempos.Count; calcTempoMap(pos); }
public TempoMap(Sequence _seq) { seq = _seq; tempos = new List <Tempo>(); Tempo tempo = new Tempo(0, DEFAULTTEMPO); tempos.Add(tempo); count = 1; }
public void calcTempoMap(int pos) //calc time of each tempo change from this tempo to tempo list end { for (int i = pos; i < tempos.Count; i++) { if (i == 0) { tempos[i].time = 0; } else { Tempo prev = tempos[i - 1]; int delta = tempos[i].tick - prev.tick; //amount of ticks from prev tempo to this one double deltatime = (((double)delta) / seq.division) * prev.rate; tempos[i].time = prev.time + (int)deltatime; //calc time in microsec of this tempo event } } }
//build the tempo, meter and marker maps from tempo message from track 0 private static void loadTrackZeroData(MidiInStream stream, Sequence seq) { //read track header String trackSig = stream.getString(4); uint trackDataLength = stream.getFour(); if (!trackSig.Equals("MTrk")) { throw new MidiFileException(stream.filename + " has an invalid track 0 at ", stream.getDataPos() - 8); } int currentTime = 0; //event time in ticks runningStatus = 0; sysexCont = false; prevSysEx = null; Event evt; Meter prevMeter = null; int startpos = stream.getDataPos(); while ((stream.getDataPos() - startpos) < trackDataLength) { currentTime += (int)stream.getVariableLengthVal(); //add delta time to current num of ticks evt = loadEventData(stream); if (evt is TempoEvent) { Tempo tempo = new Tempo(currentTime, ((TempoEvent)evt).tempo); seq.tempoMap.addTempo(tempo); } else if (evt is SMPTEOffsetEvent) //not handling smpte timing yet { } else if (evt is TimeSignatureEvent) { int keysig = (prevMeter != null) ? prevMeter.keysig : 0; Meter meter = new Meter(currentTime, ((TimeSignatureEvent)evt).numer, ((TimeSignatureEvent)evt).denom, keysig); seq.meterMap.addMeter(meter); prevMeter = meter; } else if (evt is KeySignatureEvent) { int numer = 4; int denom = 4; if (prevMeter != null) { numer = prevMeter.numer; denom = prevMeter.denom; } Meter meter = new Meter(currentTime, numer, denom, ((KeySignatureEvent)evt).keySig); seq.meterMap.addMeter(meter); prevMeter = meter; } else if (evt is MarkerEvent) { } else if (evt is CuePointEvent) { } } }