Tempo ramps -update audio-locked meter bbt correctly, a bit more explanation.
[ardour.git] / libs / ardour / tempo.cc
index 2f1678467e018e5e506115280b077fe02ac1d513..45c26b8c361015ce657e607bf5f23a8e25f55f13 100644 (file)
@@ -567,26 +567,36 @@ MeterSection::get_state() const
 /*
   Tempo Map Overview
 
-  We have tempos, which are nice to think of in whole pulses per minute,
-  and meters which divide tempo pulses into bars (via divisions_per_bar)
-  and beats (via note_divisor).
-  Tempos and meters may be locked to audio or music.
-  Because the notion of a beat cannot be determined without both tempo and meter, the first tempo
-  and first meter are special. they must move together, and must be locked to audio.
+  Tempos can be thought of as a source of the musical pulse.
+
+  Note that Tempo::beats_per_minute() has nothing to do with musical beats.
+  It should rather be thought of as tempo note divisions per minute.
+
+  TempoSections, which are nice to think of in whole pulses per minute,
+  and MeterSecions which divide tempo pulses into measures (via divisions_per_bar)
+  and beats (via note_divisor) are used to form a tempo map.
+  TempoSections and MeterSections may be locked to either audio or music (position lock style).
+  We construct the tempo map by first using the frame or pulse position (depending on position lock style) of each tempo.
+  We then use this pulse/frame layout to find the beat & pulse or frame position of each meter (again depending on lock style).
+
+  Having done this, we can now find any one of tempo, beat, frame or pulse if a beat, frame, pulse or tempo is known.
+
+  The first tempo and first meter are special. they must move together, and must be locked to audio.
   Audio locked tempos which lie before the first meter are made inactive.
   They will be re-activated if the first meter is again placed before them.
 
   Both tempos and meters have a pulse position and a frame position.
-  Meters also have a beat position, which is 0.0 for the first meter.
-  A tempo locked to music is locked to pulses.
+  Meters also have a beat position, which is always 0.0 for the first meter.
+
+  A tempo locked to music is locked to musical pulses.
   A meter locked to music is locked to beats.
+
   Recomputing the tempo map is the process where the 'missing' position
-  (tempo pulse or meter pulse & beat in the case of AudioTime and frame for MusicTime) is calculated
-  based on the lock preference (position_lock_style).
+  (tempo pulse or meter pulse & beat in the case of AudioTime, frame for MusicTime) is calculated.
 
   It is important to keep the _metrics in an order that makes sense.
-  Because ramped MusicTime and AudioTime tempos can interact with each other
-  and cause reordering, care must be taken to keep _metrics in a solved state.
+  Because ramped MusicTime and AudioTime tempos can interact with each other,
+  reordering is frequent. Care must be taken to keep _metrics in a solved state.
   Solved means ordered by frame or pulse with frame-accurate precision (see check_solved()).
 */
 struct MetricSectionSorter {
@@ -925,11 +935,11 @@ TempoMap::replace_meter (const MeterSection& ms, const Meter& meter, const BBT_T
                Glib::Threads::RWLock::WriterLock lm (lock);
                MeterSection& first (first_meter());
 
-               const PositionLockStyle pl = ms.position_lock_style();
-               if (ms.pulse() != first.pulse()) {
+               if (ms.movable()) {
                        remove_meter_locked (ms);
                        add_meter_locked (meter, bbt_to_beats_locked (_metrics, where), where, true);
                } else {
+                       const PositionLockStyle pl = ms.position_lock_style();
                        /* cannot move the first meter section */
                        *static_cast<Meter*>(&first) = meter;
                        first.set_position_lock_style (pl);
@@ -945,13 +955,15 @@ TempoMap::replace_meter (const MeterSection& ms, const Meter& meter, const frame
 {
        {
                Glib::Threads::RWLock::WriterLock lm (lock);
-               MeterSection& first (first_meter());
-               TempoSection& first_t (first_tempo());
 
-               if (ms.pulse() != first.pulse()) {
+               const double beat = ms.beat();
+               const BBT_Time bbt = ms.bbt();
+               if (ms.movable()) {
                        remove_meter_locked (ms);
-                       add_meter_locked (meter, frame, true);
+                       add_meter_locked (meter, frame, beat, bbt, true);
                } else {
+                       MeterSection& first (first_meter());
+                       TempoSection& first_t (first_tempo());
                        /* cannot move the first meter section */
                        *static_cast<Meter*>(&first) = meter;
                        first.set_position_lock_style (AudioTime);
@@ -959,7 +971,6 @@ TempoMap::replace_meter (const MeterSection& ms, const Meter& meter, const frame
                        first.set_frame (frame);
                        pair<double, BBT_Time> beat = make_pair (0.0, BBT_Time (1, 1, 0));
                        first.set_beat (beat);
-                       recompute_meters (_metrics);
                        first_t.set_frame (first.frame());
                        first_t.set_pulse (0.0);
                        first_t.set_position_lock_style (AudioTime);
@@ -990,11 +1001,11 @@ TempoMap::add_meter (const Meter& meter, const double& beat, const BBT_Time& whe
 }
 
 void
-TempoMap::add_meter (const Meter& meter, const framepos_t& frame)
+TempoMap::add_meter (const Meter& meter, const framepos_t& frame, const double& beat, const Timecode::BBT_Time& where)
 {
        {
                Glib::Threads::RWLock::WriterLock lm (lock);
-               add_meter_locked (meter, frame, true);
+               add_meter_locked (meter, frame, beat, where, true);
        }
 
 
@@ -1035,10 +1046,13 @@ TempoMap::add_meter_locked (const Meter& meter, double beat, BBT_Time where, boo
 }
 
 void
-TempoMap::add_meter_locked (const Meter& meter, framepos_t frame, bool recompute)
+TempoMap::add_meter_locked (const Meter& meter, framepos_t frame, double beat, Timecode::BBT_Time where, bool recompute)
 {
 
-       MeterSection* new_meter = new MeterSection (frame, 0.0, meter.divisions_per_bar(), meter.note_divisor());
+       MeterSection* new_meter = new MeterSection (frame, beat, where, meter.divisions_per_bar(), meter.note_divisor());
+
+       double pulse = pulse_at_frame_locked (_metrics, frame);
+       new_meter->set_pulse (pulse);
 
        do_insert (new_meter);
 
@@ -1130,7 +1144,7 @@ TempoMap::gui_move_tempo_beat (TempoSection* ts,  const Tempo& bpm, const double
                Glib::Threads::RWLock::WriterLock lm (lock);
                TempoSection* new_section = copy_metrics_and_point (future_map, ts);
                if (solve_map (future_map, new_section, bpm, pulse_at_beat_locked (future_map, beat))) {
-                       solve_map (_metrics, ts, bpm,  pulse_at_beat_locked (_metrics, beat));
+                       solve_map (_metrics, ts, bpm, pulse_at_beat_locked (_metrics, beat));
                }
        }
 
@@ -1225,14 +1239,17 @@ TempoMap::copy_metrics_and_point (Metrics& copy, TempoSection* section)
                        copy.push_back (cp);
                }
                if ((m = dynamic_cast<MeterSection *> (*i)) != 0) {
+                       MeterSection* cp = 0;
                        if (m->position_lock_style() == MusicTime) {
-                               copy.push_back (new MeterSection (m->pulse(), m->beat(), m->bbt(), m->divisions_per_bar(), m->note_divisor()));
+                               cp = new MeterSection (m->pulse(), m->beat(), m->bbt(), m->divisions_per_bar(), m->note_divisor());
                        } else {
-                               copy.push_back (new MeterSection (m->frame(), m->beat(), m->divisions_per_bar(), m->note_divisor()));
+                               cp = new MeterSection (m->frame(), m->beat(), m->bbt(), m->divisions_per_bar(), m->note_divisor());
                        }
+                       cp->set_movable (m->movable());
+                       copy.push_back (cp);
                }
        }
-       recompute_map (copy);
+       //recompute_map (copy);
        return ret;
 }
 
@@ -1379,7 +1396,9 @@ TempoMap::first_tempo () const
                        if (!t->active()) {
                                continue;
                        }
-                       return *t;
+                       if (!t->movable()) {
+                               return *t;
+                       }
                }
        }
 
@@ -1398,7 +1417,9 @@ TempoMap::first_tempo ()
                        if (!t->active()) {
                                continue;
                        }
-                       return *t;
+                       if (!t->movable()) {
+                               return *t;
+                       }
                }
        }
 
@@ -1441,29 +1462,28 @@ TempoMap::recompute_meters (Metrics& metrics)
 {
        MeterSection* meter = 0;
        MeterSection* prev_m = 0;
-       double accumulated_beats = 0.0;
        uint32_t accumulated_bars = 0;
 
        for (Metrics::const_iterator mi = metrics.begin(); mi != metrics.end(); ++mi) {
                if ((meter = dynamic_cast<MeterSection*> (*mi)) != 0) {
                        if (prev_m) {
                                const double beats_in_m = (meter->pulse() - prev_m->pulse()) * prev_m->note_divisor();
-                               accumulated_beats += beats_in_m;
                                accumulated_bars += (beats_in_m + 1) / prev_m->divisions_per_bar();
                        }
                        if (meter->position_lock_style() == AudioTime) {
                                double pulse = 0.0;
-                               pair<double, BBT_Time> bt = make_pair (accumulated_beats, BBT_Time (accumulated_bars + 1, 1, 0));
-                               meter->set_beat (bt);
+                               pair<double, BBT_Time> b_bbt;
                                if (prev_m) {
-                                       pulse = prev_m->pulse() + (meter->beat() - prev_m->beat()) / prev_m->note_divisor();
-                               } else {
-                                       if (meter->movable()) {
-                                               pulse = pulse_at_frame_locked (metrics, meter->frame());
-                                       } else {
-                                               pulse = 0.0;
-                                       }
+                                       double beats = ((pulse_at_frame_locked (metrics, meter->frame()) - prev_m->pulse()) * prev_m->note_divisor()) - prev_m->beat();
+                                       b_bbt = make_pair (ceil (beats), BBT_Time (accumulated_bars + 1, 1, 0));
+                                       const double true_pulse = prev_m->pulse() + (ceil (beats) - prev_m->beat()) / prev_m->note_divisor();
+                                       const double pulse_off = true_pulse - ((beats - prev_m->beat()) / prev_m->note_divisor());
+                                       pulse = true_pulse - pulse_off;
+                               }
+                               if (!meter->movable()) {
+                                       b_bbt = make_pair (0.0, BBT_Time (1, 1, 0));
                                }
+                               meter->set_beat (b_bbt);
                                meter->set_pulse (pulse);
                        } else {
                                double pulse = 0.0;
@@ -1816,8 +1836,8 @@ TempoMap::beat_at_frame (const framecnt_t& frame) const
 double
 TempoMap::beat_at_frame_locked (const Metrics& metrics, const framecnt_t& frame) const
 {
-       framecnt_t const offset_frame = frame + frame_offset_at (metrics, frame);
-       double const pulse = pulse_at_frame_locked (metrics, offset_frame);
+       //framecnt_t const offset_frame = frame + frame_offset_at (metrics, frame);
+       double const pulse = pulse_at_frame_locked (metrics, frame);
 
        return beat_at_pulse_locked (metrics, pulse);
 }
@@ -1862,8 +1882,8 @@ framecnt_t
 TempoMap::frame_at_beat_locked (const Metrics& metrics, const double& beat) const
 {
        framecnt_t const frame = frame_at_pulse_locked (metrics, pulse_at_beat_locked (metrics, beat));
-       frameoffset_t const frame_off = frame_offset_at (metrics, frame);
-       return frame - frame_off;
+       //frameoffset_t const frame_off = frame_offset_at (metrics, frame);
+       return frame;
 }
 
 framecnt_t
@@ -2006,19 +2026,41 @@ TempoMap::check_solved (Metrics& metrics, bool by_frame)
 }
 
 bool
-TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm, const framepos_t& frame)
+TempoMap::set_active_tempos (const Metrics& metrics, const framepos_t& frame)
 {
+       for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
+               TempoSection* t;
+               if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
+                       if (!t->movable()) {
+                               t->set_active (true);
+                               continue;
+                       }
+                       if (t->movable() && t->active () && t->position_lock_style() == AudioTime && t->frame() < frame) {
+                               t->set_active (false);
+                               t->set_pulse (0.0);
+                       } else if (t->movable() && t->position_lock_style() == AudioTime && t->frame() > frame) {
+                               t->set_active (true);
+                       } else if (t->movable() && t->position_lock_style() == AudioTime && t->frame() == frame) {
+                               return false;
+                       }
+               }
+       }
+       return true;
+}
 
+bool
+TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm, const framepos_t& frame)
+{
        TempoSection* prev_ts = 0;
        TempoSection* section_prev = 0;
-       MetricSectionFrameSorter fcmp;
-       MetricSectionSorter cmp;
        framepos_t first_m_frame = 0;
+
        for (Metrics::iterator i = imaginary.begin(); i != imaginary.end(); ++i) {
                MeterSection* m;
                if ((m = dynamic_cast<MeterSection*> (*i)) != 0) {
                        if (!m->movable()) {
                                first_m_frame = m->frame();
+                               break;
                        }
                }
        }
@@ -2072,6 +2114,7 @@ TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm
                return true;
        }
 
+       MetricSectionFrameSorter fcmp;
        imaginary.sort (fcmp);
        if (section->position_lock_style() == MusicTime) {
                /* we're setting the frame */
@@ -2086,6 +2129,7 @@ TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm
                return true;
        }
 
+       MetricSectionSorter cmp;
        imaginary.sort (cmp);
        if (section->position_lock_style() == MusicTime) {
                /* we're setting the frame */
@@ -2107,8 +2151,6 @@ TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm
 bool
 TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm, const double& pulse)
 {
-       MetricSectionSorter cmp;
-       MetricSectionFrameSorter fcmp;
        TempoSection* prev_ts = 0;
        TempoSection* section_prev = 0;
 
@@ -2154,6 +2196,7 @@ TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm
                return true;
        }
 
+       MetricSectionSorter cmp;
        imaginary.sort (cmp);
        if (section->position_lock_style() == AudioTime) {
                /* we're setting the pulse */
@@ -2169,6 +2212,7 @@ TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm
                return true;
        }
 
+       MetricSectionFrameSorter fcmp;
        imaginary.sort (fcmp);
        if (section->position_lock_style() == AudioTime) {
                /* we're setting the pulse */
@@ -2190,27 +2234,65 @@ TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm
 }
 
 void
-TempoMap::solve_map (Metrics& imaginary, MeterSection* section, const Meter& mt, const double& pulse)
+TempoMap::solve_map (Metrics& imaginary, MeterSection* section, const Meter& mt, const framepos_t& frame)
 {
        MeterSection* prev_ms = 0;
-       double accumulated_beats = 0.0;
+
+       if (!section->movable()) {
+               /* lock the first tempo to our first meter */
+               if (!set_active_tempos (imaginary, frame)) {
+                       return;
+               }
+               TempoSection* first_t = &first_tempo();
+               Metrics future_map;
+               TempoSection* new_section = copy_metrics_and_point (future_map, first_t);
+
+               new_section->set_frame (frame);
+               new_section->set_pulse (0.0);
+               new_section->set_active (true);
+
+               if (solve_map (future_map, new_section, Tempo (new_section->beats_per_minute(), new_section->note_type()), frame)) {
+                       first_t->set_frame (frame);
+                       first_t->set_pulse (0.0);
+                       first_t->set_active (true);
+                       solve_map (imaginary, first_t, Tempo (first_t->beats_per_minute(), first_t->note_type()), frame);
+               } else {
+                       return;
+               }
+       }
+
        uint32_t accumulated_bars = 0;
 
-       section->set_pulse (pulse);
+       section->set_frame (frame);
 
        for (Metrics::iterator i = imaginary.begin(); i != imaginary.end(); ++i) {
                MeterSection* m;
                if ((m = dynamic_cast<MeterSection*> (*i)) != 0) {
                        if (prev_ms) {
-                               double const beats_in_m = (m->pulse() - prev_ms->pulse()) * prev_ms->note_divisor();
-                               accumulated_beats += beats_in_m;
+                               const double beats_in_m = (m->pulse() - prev_ms->pulse()) * prev_ms->note_divisor();
                                accumulated_bars += (beats_in_m + 1) / prev_ms->divisions_per_bar();
                        }
                        if (m == section){
-                               section->set_frame (frame_at_pulse_locked (imaginary, pulse));
-                               pair<double, BBT_Time> b_bbt = make_pair (accumulated_beats, BBT_Time (accumulated_bars + 1, 1, 0));
-                               section->set_beat (b_bbt);
-                               prev_ms = section;
+                               /*
+                                 here we set the beat for this frame.
+                                 we're going to set it 'incorrectly' to the next integer and use this difference
+                                 to find the meter's pulse later.
+                                 (meters should fall on absolute beats to keep us sane)
+                               */
+                               double pulse = 0.0;
+                               pair<double, BBT_Time> b_bbt;
+                               if (m->movable()) {
+                                       double beats = ((pulse_at_frame_locked (imaginary, frame) - prev_ms->pulse()) * prev_ms->note_divisor()) - prev_ms->beat();
+                                       b_bbt = make_pair (ceil (beats), BBT_Time (accumulated_bars + 1, 1, 0));
+                                       const double true_pulse = prev_ms->pulse() + ((ceil (beats) - prev_ms->beat()) / prev_ms->note_divisor());
+                                       const double pulse_off = true_pulse - ((beats - prev_ms->beat()) / prev_ms->note_divisor());
+                                       pulse = true_pulse - pulse_off;
+                               } else {
+                                       b_bbt = make_pair (0.0, BBT_Time (1, 1, 0));
+                               }
+                               m->set_beat (b_bbt);
+                               m->set_pulse (pulse);
+                               prev_ms = m;
                                continue;
                        }
                        if (prev_ms) {
@@ -2219,8 +2301,10 @@ TempoMap::solve_map (Metrics& imaginary, MeterSection* section, const Meter& mt,
                                        m->set_frame (frame_at_pulse_locked (imaginary, pulse));
                                        m->set_pulse (pulse);
                                } else {
-                                       pair<double, BBT_Time> b_bbt = make_pair (accumulated_beats, BBT_Time (accumulated_bars + 1, 1, 0));
-                                       m->set_beat (b_bbt);
+                                       if (!m->movable()) {
+                                               pair<double, BBT_Time> b_bbt = make_pair (0.0, BBT_Time (1, 1, 0));
+                                               m->set_beat (b_bbt);
+                                       }
                                        const double pulse = prev_ms->pulse() + (m->beat() - prev_ms->beat()) / prev_ms->note_divisor();
                                        m->set_pulse (pulse);
                                }
@@ -2229,86 +2313,39 @@ TempoMap::solve_map (Metrics& imaginary, MeterSection* section, const Meter& mt,
                }
        }
 
-       if (section->position_lock_style() == AudioTime) {
-               /* we're setting the pulse */
-               section->set_position_lock_style (MusicTime);
-               recompute_meters (imaginary);
+       if (section->position_lock_style() == MusicTime) {
+               /* we're setting the frame */
                section->set_position_lock_style (AudioTime);
+               recompute_meters (imaginary);
+               section->set_position_lock_style (MusicTime);
        } else {
                recompute_meters (imaginary);
        }
+       //dump (imaginary, std::cerr);
 }
 
 void
-TempoMap::solve_map (Metrics& imaginary, MeterSection* section, const Meter& mt, const framepos_t& frame)
+TempoMap::solve_map (Metrics& imaginary, MeterSection* section, const Meter& mt, const double& pulse)
 {
        MeterSection* prev_ms = 0;
-
-       if (!section->movable()) {
-               TempoSection* first_t;
-               for (Metrics::const_iterator i = imaginary.begin(); i != imaginary.end(); ++i) {
-                       TempoSection* t;
-                       if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
-                               if (!t->movable()) {
-                                       t->set_active (true);
-                                       first_t = t;
-                               }
-                               if (t->movable() && t->active () && t->position_lock_style() == AudioTime && t->frame() < frame) {
-                                       t->set_active (false);
-                                       t->set_pulse (0.0);
-                               } else if (t->movable() && t->position_lock_style() == AudioTime && t->frame() > frame) {
-                                       t->set_active (true);
-                               } else if (t->movable() && t->position_lock_style() == AudioTime && t->frame() == frame) {
-                                       return;
-                               }
-                       }
-               }
-
-               Metrics future_map;
-               TempoSection* new_section = copy_metrics_and_point (future_map, first_t);
-
-               new_section->set_frame (frame);
-               new_section->set_pulse (0.0);
-               new_section->set_active (true);
-
-               if (solve_map (future_map, new_section, Tempo (new_section->beats_per_minute(), new_section->note_type()), frame)) {
-                       first_t->set_frame (frame);
-                       first_t->set_pulse (0.0);
-                       first_t->set_active (true);
-                       solve_map (imaginary, first_t, Tempo (first_t->beats_per_minute(), first_t->note_type()), frame);
-               } else {
-                       return;
-               }
-       }
-
        double accumulated_beats = 0.0;
        uint32_t accumulated_bars = 0;
 
-       section->set_frame (frame);
+       section->set_pulse (pulse);
 
        for (Metrics::iterator i = imaginary.begin(); i != imaginary.end(); ++i) {
                MeterSection* m;
                if ((m = dynamic_cast<MeterSection*> (*i)) != 0) {
                        if (prev_ms) {
-                               const double beats_in_m = (m->pulse() - prev_ms->pulse()) * prev_ms->note_divisor();
+                               double const beats_in_m = (m->pulse() - prev_ms->pulse()) * prev_ms->note_divisor();
                                accumulated_beats += beats_in_m;
                                accumulated_bars += (beats_in_m + 1) / prev_ms->divisions_per_bar();
                        }
                        if (m == section){
-                               /*
-                                 here we define the pulse for this frame.
-                                 we're going to set it 'incorrectly' to the next integer and use this 'error'
-                                 as an offset to the map as far as users of the public methods are concerned.
-                                 (meters should go on absolute pulses to keep us sane)
-                               */
+                               section->set_frame (frame_at_pulse_locked (imaginary, pulse));
                                pair<double, BBT_Time> b_bbt = make_pair (accumulated_beats, BBT_Time (accumulated_bars + 1, 1, 0));
-                               if (m->movable()) {
-                                       m->set_pulse (pulse_at_frame_locked (imaginary, frame));
-                               } else {
-                                       m->set_pulse (0.0);
-                               }
-                               m->set_beat (b_bbt);
-                               prev_ms = m;
+                               section->set_beat (b_bbt);
+                               prev_ms = section;
                                continue;
                        }
                        if (prev_ms) {
@@ -2317,8 +2354,10 @@ TempoMap::solve_map (Metrics& imaginary, MeterSection* section, const Meter& mt,
                                        m->set_frame (frame_at_pulse_locked (imaginary, pulse));
                                        m->set_pulse (pulse);
                                } else {
-                                       pair<double, BBT_Time> b_bbt = make_pair (accumulated_beats, BBT_Time (accumulated_bars + 1, 1, 0));
-                                       m->set_beat (b_bbt);
+                                       if (!m->movable()) {
+                                               pair<double, BBT_Time> b_bbt = make_pair (0.0, BBT_Time (1, 1, 0));
+                                               m->set_beat (b_bbt);
+                                       }
                                        const double pulse = prev_ms->pulse() + (m->beat() - prev_ms->beat()) / prev_ms->note_divisor();
                                        m->set_pulse (pulse);
                                }
@@ -2327,15 +2366,14 @@ TempoMap::solve_map (Metrics& imaginary, MeterSection* section, const Meter& mt,
                }
        }
 
-       if (section->position_lock_style() == MusicTime) {
-               /* we're setting the frame */
-               section->set_position_lock_style (AudioTime);
-               recompute_meters (imaginary);
+       if (section->position_lock_style() == AudioTime) {
+               /* we're setting the pulse */
                section->set_position_lock_style (MusicTime);
+               recompute_meters (imaginary);
+               section->set_position_lock_style (AudioTime);
        } else {
                recompute_meters (imaginary);
        }
-       //dump (imaginary, std::cerr);
 }
 
 framecnt_t
@@ -2581,8 +2619,8 @@ TempoMap::get_grid (vector<TempoMap::BBTPoint>& points,
                TempoSection const tempo = tempo_section_at_locked (pos);
                MeterSection const meter = meter_section_at_locked (pos);
                BBT_Time const bbt = beats_to_bbt (cnt);
-
-               points.push_back (BBTPoint (meter, tempo_at_locked (pos), pos, bbt.bars, bbt.beats, tempo.get_c_func()));
+               BBTPoint point = BBTPoint (meter, tempo_at_locked (pos), pos, bbt.bars, bbt.beats, tempo.get_c_func());
+               points.push_back (point);
                ++cnt;
        }
 }