+ if (current.beats == 1) {
+ bar_start_frame = current_frame;
+ } else {
+ bar_start_frame = 0;
+ }
+
+ beat_frames = meter->frames_per_grid (*tempo,_frame_rate);
+
+ while (current_frame < end) {
+
+ current.beats++;
+ current_frame += beat_frames;
+
+ if (current.beats > meter->divisions_per_bar()) {
+ current.bars++;
+ current.beats = 1;
+ }
+
+ if (next_metric != metrics.end()) {
+
+ /* no operator >= so invert operator < */
+
+ DEBUG_TRACE (DEBUG::TempoMath, string_compose ("now at %1 next metric @ %2\n", current, (*next_metric)->start()));
+
+ if (!(current < (*next_metric)->start())) {
+
+ set_metrics:
+ if (((ts = dynamic_cast<TempoSection*> (*next_metric)) != 0)) {
+
+ tempo = ts;
+
+ /* new tempo section: if its on a beat,
+ * we don't have to do anything other
+ * than recompute various distances,
+ * done further below as we transition
+ * the next metric section.
+ *
+ * if its not on the beat, we have to
+ * compute the duration of the beat it
+ * is within, which will be different
+ * from the preceding following ones
+ * since it takes part of its duration
+ * from the preceding tempo and part
+ * from this new tempo.
+ */
+
+ if (tempo->start().ticks != 0) {
+
+ double next_beat_frames = tempo->frames_per_beat (_frame_rate);
+
+ DEBUG_TRACE (DEBUG::TempoMath, string_compose ("bumped into non-beat-aligned tempo metric at %1 = %2, adjust next beat using %3\n",
+ tempo->start(), current_frame, tempo->bar_offset()));
+
+ /* back up to previous beat */
+ current_frame -= beat_frames;
+
+ /* set tempo section location
+ * based on offset from last
+ * bar start
+ */
+ tempo->set_frame (bar_start_frame +
+ llrint ((ts->bar_offset() * meter->divisions_per_bar() * beat_frames)));
+
+ /* advance to the location of
+ * the new (adjusted) beat. do
+ * this by figuring out the
+ * offset within the beat that
+ * would have been there
+ * without the tempo
+ * change. then stretch the
+ * beat accordingly.
+ */
+
+ double offset_within_old_beat = (tempo->frame() - current_frame) / beat_frames;
+
+ current_frame += (offset_within_old_beat * beat_frames) + ((1.0 - offset_within_old_beat) * next_beat_frames);
+
+ /* next metric doesn't have to
+ * match this precisely to
+ * merit a reloop ...
+ */
+ DEBUG_TRACE (DEBUG::TempoMath, string_compose ("Adjusted last beat to %1\n", current_frame));
+
+ } else {
+
+ DEBUG_TRACE (DEBUG::TempoMath, string_compose ("bumped into beat-aligned tempo metric at %1 = %2\n",
+ tempo->start(), current_frame));
+ tempo->set_frame (current_frame);
+ }