Tempo ramps - music-locked meters now use beats rather than pulses as their reference.

- fixes many problems with a non-zero audio-locked first meter.
This commit is contained in:
nick_m 2016-03-23 01:11:00 +11:00
parent ba3ae54f51
commit 58d4889ad3
5 changed files with 72 additions and 57 deletions

View file

@ -3182,7 +3182,7 @@ MeterMarkerDrag::motion (GdkEvent* event, bool first_move)
_marker->hide(); _marker->hide();
} }
framepos_t const pf = adjusted_current_frame (event); framepos_t const pf = adjusted_current_frame (event, false);
_marker->set_position (pf); _marker->set_position (pf);
if (_marker->meter().position_lock_style() == MusicTime) { if (_marker->meter().position_lock_style() == MusicTime) {
double const baf = _editor->session()->tempo_map().beat_at_frame (_editor->session()->tempo_map().round_to_bar (pf, (RoundMode) 0)); double const baf = _editor->session()->tempo_map().beat_at_frame (_editor->session()->tempo_map().round_to_bar (pf, (RoundMode) 0));
@ -3366,8 +3366,8 @@ TempoMarkerDrag::finished (GdkEvent* event, bool movement_occurred)
XMLNode &before = map.get_state(); XMLNode &before = map.get_state();
if (_marker->tempo().position_lock_style() == MusicTime) { if (_marker->tempo().position_lock_style() == MusicTime) {
double const beat = map.predict_tempo_beat (_real_section, _marker->tempo(), _real_section->frame()); double const pulse = map.predict_tempo_pulse (_real_section, _marker->tempo(), _real_section->frame());
map.add_tempo (_marker->tempo(), beat, _marker->tempo().type()); map.add_tempo (_marker->tempo(), pulse, _marker->tempo().type());
} else { } else {
map.add_tempo (_marker->tempo(), _real_section->frame(), _marker->tempo().type()); map.add_tempo (_marker->tempo(), _real_section->frame(), _marker->tempo().type());
} }
@ -3377,11 +3377,10 @@ TempoMarkerDrag::finished (GdkEvent* event, bool movement_occurred)
_editor->commit_reversible_command (); _editor->commit_reversible_command ();
} else { } else {
/* we removed it before, so add it back now */
if (_marker->tempo().position_lock_style() == MusicTime) { if (_marker->tempo().position_lock_style() == MusicTime) {
double const beat = map.predict_tempo_beat (_real_section, _marker->tempo(), _real_section->frame()); double const pulse = map.predict_tempo_pulse (_real_section, _marker->tempo(), _real_section->frame());
map.replace_tempo (*_real_section, Tempo (_marker->tempo().beats_per_minute(), _marker->tempo().note_type()) map.replace_tempo (*_real_section, Tempo (_marker->tempo().beats_per_minute(), _marker->tempo().note_type())
, beat, _marker->tempo().type()); , pulse, _marker->tempo().type());
} else { } else {
map.replace_tempo (*_real_section, Tempo (_marker->tempo().beats_per_minute(), _marker->tempo().note_type()) map.replace_tempo (*_real_section, Tempo (_marker->tempo().beats_per_minute(), _marker->tempo().note_type())
, _real_section->frame(), _marker->tempo().type()); , _real_section->frame(), _marker->tempo().type());

View file

@ -6552,7 +6552,7 @@ Editor::define_one_bar (framepos_t start, framepos_t end)
} else if (t.frame() == start) { } else if (t.frame() == start) {
_session->tempo_map().change_existing_tempo_at (start, beats_per_minute, t.note_type()); _session->tempo_map().change_existing_tempo_at (start, beats_per_minute, t.note_type());
} else { } else {
_session->tempo_map().add_tempo (Tempo (beats_per_minute, t.note_type()), _session->tempo_map().beat_at_frame (start), TempoSection::Constant); _session->tempo_map().add_tempo (Tempo (beats_per_minute, t.note_type()), start, TempoSection::Constant);
} }
XMLNode& after (_session->tempo_map().get_state()); XMLNode& after (_session->tempo_map().get_state());

View file

@ -242,7 +242,7 @@ Editor::mouse_add_new_tempo_event (framepos_t frame)
begin_reversible_command (_("add tempo mark")); begin_reversible_command (_("add tempo mark"));
XMLNode &before = map.get_state(); XMLNode &before = map.get_state();
if (tempo_dialog.get_lock_style() == MusicTime) { if (tempo_dialog.get_lock_style() == MusicTime) {
map.add_tempo (Tempo (bpm,nt), map.bbt_to_beats (requested), tempo_dialog.get_tempo_type()); map.add_tempo (Tempo (bpm,nt), map.pulse_at_beat (map.bbt_to_beats (requested)), tempo_dialog.get_tempo_type());
} else { } else {
map.add_tempo (Tempo (bpm,nt), frame, tempo_dialog.get_tempo_type()); map.add_tempo (Tempo (bpm,nt), frame, tempo_dialog.get_tempo_type());
} }
@ -373,7 +373,7 @@ Editor::edit_tempo_section (TempoSection* section)
begin_reversible_command (_("replace tempo mark")); begin_reversible_command (_("replace tempo mark"));
XMLNode &before = _session->tempo_map().get_state(); XMLNode &before = _session->tempo_map().get_state();
if (tempo_dialog.get_lock_style() == MusicTime) { if (tempo_dialog.get_lock_style() == MusicTime) {
_session->tempo_map().replace_tempo (*section, Tempo (bpm, nt), beat, tempo_dialog.get_tempo_type()); _session->tempo_map().replace_tempo (*section, Tempo (bpm, nt), _session->tempo_map().pulse_at_beat (beat), tempo_dialog.get_tempo_type());
} else { } else {
framepos_t const f = _session->tempo_map().predict_tempo_frame (section, Tempo (bpm, nt), when); framepos_t const f = _session->tempo_map().predict_tempo_frame (section, Tempo (bpm, nt), when);
_session->tempo_map().replace_tempo (*section, Tempo (bpm, nt), f, tempo_dialog.get_tempo_type()); _session->tempo_map().replace_tempo (*section, Tempo (bpm, nt), f, tempo_dialog.get_tempo_type());

View file

@ -365,7 +365,7 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
const TempoSection& tempo_section_at (framepos_t frame) const; const TempoSection& tempo_section_at (framepos_t frame) const;
const MeterSection& meter_section_at (framepos_t frame) const; const MeterSection& meter_section_at (framepos_t frame) const;
void add_tempo (const Tempo&, const double& beat, TempoSection::Type type); void add_tempo (const Tempo&, const double& pulse, TempoSection::Type type);
void add_tempo (const Tempo&, const framepos_t& frame, TempoSection::Type type); void add_tempo (const Tempo&, const framepos_t& frame, TempoSection::Type type);
void add_meter (const Meter&, const double& beat, const Timecode::BBT_Time& where); void add_meter (const Meter&, const double& beat, const Timecode::BBT_Time& where);
@ -375,7 +375,7 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
void remove_meter (const MeterSection&, bool send_signal); void remove_meter (const MeterSection&, bool send_signal);
framepos_t predict_tempo_frame (TempoSection* section, const Tempo& bpm, const Timecode::BBT_Time& bbt); framepos_t predict_tempo_frame (TempoSection* section, const Tempo& bpm, const Timecode::BBT_Time& bbt);
double predict_tempo_beat (TempoSection* section, const Tempo& bpm, const framepos_t& beat); double predict_tempo_pulse (TempoSection* section, const Tempo& bpm, const framepos_t& frame);
void replace_tempo (const TempoSection&, const Tempo&, const double& where, TempoSection::Type type); void replace_tempo (const TempoSection&, const Tempo&, const double& where, TempoSection::Type type);
void replace_tempo (const TempoSection&, const Tempo&, const framepos_t& frame, TempoSection::Type type); void replace_tempo (const TempoSection&, const Tempo&, const framepos_t& frame, TempoSection::Type type);
@ -399,7 +399,7 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
XMLNode& get_state (void); XMLNode& get_state (void);
int set_state (const XMLNode&, int version); int set_state (const XMLNode&, int version);
void dump (Metrics& metrics, std::ostream&) const; void dump (const Metrics& metrics, std::ostream&) const;
void clear (); void clear ();
TempoMetric metric_at (Timecode::BBT_Time bbt) const; TempoMetric metric_at (Timecode::BBT_Time bbt) const;
@ -426,20 +426,24 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
Timecode::BBT_Time beats_to_bbt (const double& beats); Timecode::BBT_Time beats_to_bbt (const double& beats);
Timecode::BBT_Time pulse_to_bbt (const double& pulse); Timecode::BBT_Time pulse_to_bbt (const double& pulse);
double pulse_at_beat (const double& beat) const;
double beat_at_pulse (const double& pulse) const;
PBD::Signal0<void> MetricPositionChanged; PBD::Signal0<void> MetricPositionChanged;
private: private:
double pulse_at_beat (const Metrics& metrics, const double& beat) const; double pulse_at_beat_locked (const Metrics& metrics, const double& beat) const;
double beat_at_pulse (const Metrics& metrics, const double& pulse) const; double beat_at_pulse_locked (const Metrics& metrics, const double& pulse) const;
double pulse_at_frame_locked (const Metrics& metrics, const framecnt_t& frame) const;
framecnt_t frame_at_pulse_locked (const Metrics& metrics, const double& beat) const;
double pulse_offset_at (const Metrics& metrics, const double& pulse) const;
frameoffset_t frame_offset_at (const Metrics& metrics, const framepos_t& frame) const;
double beat_at_frame_locked (const Metrics& metrics, const framecnt_t& frame) const; double beat_at_frame_locked (const Metrics& metrics, const framecnt_t& frame) const;
framecnt_t frame_at_beat_locked (const Metrics& metrics, const double& beat) const; framecnt_t frame_at_beat_locked (const Metrics& metrics, const double& beat) const;
double bbt_to_beats_locked (const Metrics& metrics, const Timecode::BBT_Time& bbt) const ; double bbt_to_beats_locked (const Metrics& metrics, const Timecode::BBT_Time& bbt) const ;
Timecode::BBT_Time beats_to_bbt_locked (const Metrics& metrics, const double& beats) const; Timecode::BBT_Time beats_to_bbt_locked (const Metrics& metrics, const double& beats) const;
double pulse_at_frame_locked (const Metrics& metrics, const framecnt_t& frame) const;
framecnt_t frame_at_pulse_locked (const Metrics& metrics, const double& beat) const;
double beat_offset_at (const Metrics& metrics, const double& beat) const;
frameoffset_t frame_offset_at (const Metrics& metrics, const framepos_t& frame) const;
framepos_t frame_time_locked (const Metrics& metrics, const Timecode::BBT_Time&) const; framepos_t frame_time_locked (const Metrics& metrics, const Timecode::BBT_Time&) const;
@ -476,7 +480,7 @@ private:
void do_insert (MetricSection* section); void do_insert (MetricSection* section);
void add_tempo_locked (const Tempo&, double where, bool recompute, TempoSection::Type type); void add_tempo_locked (const Tempo&, double pulse, bool recompute, TempoSection::Type type);
void add_tempo_locked (const Tempo&, framepos_t frame, bool recompute, TempoSection::Type type); void add_tempo_locked (const Tempo&, framepos_t frame, bool recompute, TempoSection::Type type);
void add_meter_locked (const Meter&, double beat, Timecode::BBT_Time where, bool recompute); void add_meter_locked (const Meter&, double beat, Timecode::BBT_Time where, bool recompute);

View file

@ -715,7 +715,7 @@ TempoMap::do_insert (MetricSection* section)
corrected.first = bbt_to_beats_locked (_metrics, corrected.second); corrected.first = bbt_to_beats_locked (_metrics, corrected.second);
warning << string_compose (_("Meter changes can only be positioned on the first beat of a bar. Moving from %1 to %2"), warning << string_compose (_("Meter changes can only be positioned on the first beat of a bar. Moving from %1 to %2"),
m->bbt(), corrected.second) << endmsg; m->bbt(), corrected.second) << endmsg;
m->set_pulse (corrected); //m->set_pulse (corrected);
} }
} }
@ -822,14 +822,14 @@ TempoMap::do_insert (MetricSection* section)
} }
void void
TempoMap::replace_tempo (const TempoSection& ts, const Tempo& tempo, const double& where, TempoSection::Type type) TempoMap::replace_tempo (const TempoSection& ts, const Tempo& tempo, const double& pulse, TempoSection::Type type)
{ {
{ {
Glib::Threads::RWLock::WriterLock lm (lock); Glib::Threads::RWLock::WriterLock lm (lock);
TempoSection& first (first_tempo()); TempoSection& first (first_tempo());
if (ts.pulse() != first.pulse()) { if (ts.pulse() != first.pulse()) {
remove_tempo_locked (ts); remove_tempo_locked (ts);
add_tempo_locked (tempo, where, true, type); add_tempo_locked (tempo, pulse, true, type);
} else { } else {
first.set_type (type); first.set_type (type);
{ {
@ -865,11 +865,11 @@ TempoMap::replace_tempo (const TempoSection& ts, const Tempo& tempo, const frame
} }
void void
TempoMap::add_tempo (const Tempo& tempo, const double& where, ARDOUR::TempoSection::Type type) TempoMap::add_tempo (const Tempo& tempo, const double& pulse, ARDOUR::TempoSection::Type type)
{ {
{ {
Glib::Threads::RWLock::WriterLock lm (lock); Glib::Threads::RWLock::WriterLock lm (lock);
add_tempo_locked (tempo, where, true, type); add_tempo_locked (tempo, pulse, true, type);
} }
PropertyChanged (PropertyChange ()); PropertyChanged (PropertyChange ());
@ -888,9 +888,8 @@ TempoMap::add_tempo (const Tempo& tempo, const framepos_t& frame, ARDOUR::TempoS
} }
void void
TempoMap::add_tempo_locked (const Tempo& tempo, double where, bool recompute, ARDOUR::TempoSection::Type type) TempoMap::add_tempo_locked (const Tempo& tempo, double pulse, bool recompute, ARDOUR::TempoSection::Type type)
{ {
double pulse = pulse_at_beat (_metrics, where);
TempoSection* ts = new TempoSection (pulse, tempo.beats_per_minute(), tempo.note_type(), type); TempoSection* ts = new TempoSection (pulse, tempo.beats_per_minute(), tempo.note_type(), type);
do_insert (ts); do_insert (ts);
@ -1007,7 +1006,7 @@ TempoMap::add_meter_locked (const Meter& meter, double beat, BBT_Time where, boo
} }
/* new meters *always* start on a beat. */ /* new meters *always* start on a beat. */
where.ticks = 0; where.ticks = 0;
double pulse = pulse_at_beat (_metrics, beat); double pulse = pulse_at_beat_locked (_metrics, beat);
MeterSection* new_meter = new MeterSection (pulse, where, meter.divisions_per_bar(), meter.note_divisor()); MeterSection* new_meter = new MeterSection (pulse, where, meter.divisions_per_bar(), meter.note_divisor());
do_insert (new_meter); do_insert (new_meter);
@ -1024,7 +1023,7 @@ TempoMap::add_meter_locked (const Meter& meter, framepos_t frame, bool recompute
MeterSection* new_meter = new MeterSection (frame, meter.divisions_per_bar(), meter.note_divisor()); MeterSection* new_meter = new MeterSection (frame, meter.divisions_per_bar(), meter.note_divisor());
double paf = pulse_at_frame_locked (_metrics, frame); double paf = pulse_at_frame_locked (_metrics, frame);
pair<double, BBT_Time> beat = make_pair (paf, beats_to_bbt_locked (_metrics, beat_at_pulse (_metrics, paf))); pair<double, BBT_Time> beat = make_pair (paf, beats_to_bbt_locked (_metrics, beat_at_pulse_locked (_metrics, paf)));
new_meter->set_pulse (beat); new_meter->set_pulse (beat);
do_insert (new_meter); do_insert (new_meter);
@ -1050,7 +1049,7 @@ TempoMap::predict_tempo_frame (TempoSection* section, const Tempo& bpm, const BB
framepos_t ret = 0; framepos_t ret = 0;
TempoSection* new_section = copy_metrics_and_point (future_map, section); TempoSection* new_section = copy_metrics_and_point (future_map, section);
double const beat = bbt_to_beats_locked (future_map, bbt); double const beat = bbt_to_beats_locked (future_map, bbt);
if (solve_map (future_map, new_section, bpm, pulse_at_beat (future_map, beat))) { if (solve_map (future_map, new_section, bpm, pulse_at_beat_locked (future_map, beat))) {
ret = new_section->frame(); ret = new_section->frame();
} else { } else {
ret = frame_at_beat_locked (_metrics, beat); ret = frame_at_beat_locked (_metrics, beat);
@ -1065,7 +1064,7 @@ TempoMap::predict_tempo_frame (TempoSection* section, const Tempo& bpm, const BB
} }
double double
TempoMap::predict_tempo_beat (TempoSection* section, const Tempo& bpm, const framepos_t& frame) TempoMap::predict_tempo_pulse (TempoSection* section, const Tempo& bpm, const framepos_t& frame)
{ {
Glib::Threads::RWLock::ReaderLock lm (lock); Glib::Threads::RWLock::ReaderLock lm (lock);
Metrics future_map; Metrics future_map;
@ -1073,9 +1072,9 @@ TempoMap::predict_tempo_beat (TempoSection* section, const Tempo& bpm, const fra
TempoSection* new_section = copy_metrics_and_point (future_map, section); TempoSection* new_section = copy_metrics_and_point (future_map, section);
if (solve_map (future_map, new_section, bpm, frame)) { if (solve_map (future_map, new_section, bpm, frame)) {
ret = beat_at_pulse (future_map, new_section->pulse()); ret = new_section->pulse();
} else { } else {
ret = beat_at_frame_locked (_metrics, frame); ret = pulse_at_frame_locked (_metrics, frame);
} }
Metrics::const_iterator d = future_map.begin(); Metrics::const_iterator d = future_map.begin();
@ -1114,7 +1113,7 @@ TempoMap::gui_move_tempo_beat (TempoSection* ts, const Tempo& bpm, const double
{ {
Glib::Threads::RWLock::WriterLock lm (lock); Glib::Threads::RWLock::WriterLock lm (lock);
TempoSection* new_section = copy_metrics_and_point (future_map, ts); TempoSection* new_section = copy_metrics_and_point (future_map, ts);
if (solve_map (future_map, new_section, bpm, pulse_at_beat (future_map, beat))) { if (solve_map (future_map, new_section, bpm, pulse_at_beat_locked (future_map, beat))) {
solve_map (_metrics, ts, bpm, beat); solve_map (_metrics, ts, bpm, beat);
} }
} }
@ -1144,7 +1143,7 @@ TempoMap::gui_move_meter (MeterSection* ms, const Meter& mt, const double& beat
{ {
{ {
Glib::Threads::RWLock::WriterLock lm (lock); Glib::Threads::RWLock::WriterLock lm (lock);
solve_map (_metrics, ms, mt, pulse_at_beat (_metrics, beat)); solve_map (_metrics, ms, mt, pulse_at_beat_locked (_metrics, beat));
} }
MetricPositionChanged (); // Emit Signal MetricPositionChanged (); // Emit Signal
@ -1388,7 +1387,7 @@ TempoMap::recompute_meters (Metrics& metrics)
if (meter->position_lock_style() == AudioTime) { if (meter->position_lock_style() == AudioTime) {
pair<double, BBT_Time> pr; pair<double, BBT_Time> pr;
pr.first = pulse_at_frame_locked (metrics, meter->frame()); pr.first = pulse_at_frame_locked (metrics, meter->frame());
BBT_Time const where = BBT_Time (accumulated_bars + 1, 1, 0); BBT_Time const where = BBT_Time (accumulated_bars + 1, 1, 0);
pr.second = where; pr.second = where;
meter->set_pulse (pr); meter->set_pulse (pr);
@ -1429,7 +1428,14 @@ TempoMap::recompute_map (Metrics& metrics, framepos_t end)
} }
double double
TempoMap::pulse_at_beat (const Metrics& metrics, const double& beat) const TempoMap::pulse_at_beat (const double& beat) const
{
Glib::Threads::RWLock::ReaderLock lm (lock);
return pulse_at_beat_locked (_metrics, beat);
}
double
TempoMap::pulse_at_beat_locked (const Metrics& metrics, const double& beat) const
{ {
MeterSection* prev_ms = 0; MeterSection* prev_ms = 0;
double accumulated_beats = 0.0; double accumulated_beats = 0.0;
@ -1450,11 +1456,17 @@ TempoMap::pulse_at_beat (const Metrics& metrics, const double& beat) const
} }
double double
TempoMap::beat_at_pulse (const Metrics& metrics, const double& pulse) const TempoMap::beat_at_pulse (const double& pulse) const
{
Glib::Threads::RWLock::ReaderLock lm (lock);
return beat_at_pulse_locked (_metrics, pulse);
}
double
TempoMap::beat_at_pulse_locked (const Metrics& metrics, const double& pulse) const
{ {
MeterSection* prev_ms = 0; MeterSection* prev_ms = 0;
double accumulated_beats = 0.0; double accumulated_beats = 0.0;
for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) { for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
MeterSection* m; MeterSection* m;
if ((m = dynamic_cast<MeterSection*> (*i)) != 0) { if ((m = dynamic_cast<MeterSection*> (*i)) != 0) {
@ -1543,7 +1555,7 @@ TempoMap::bbt_time (framepos_t frame, BBT_Time& bbt)
} }
Glib::Threads::RWLock::ReaderLock lm (lock); Glib::Threads::RWLock::ReaderLock lm (lock);
frameoffset_t const frame_off = frame_offset_at (_metrics, frame); frameoffset_t const frame_off = frame_offset_at (_metrics, frame);
double const beat = beat_at_pulse (_metrics, pulse_at_frame_locked (_metrics, frame + frame_off)); double const beat = beat_at_pulse_locked (_metrics, pulse_at_frame_locked (_metrics, frame + frame_off));
bbt = beats_to_bbt_locked (_metrics, beat); bbt = beats_to_bbt_locked (_metrics, beat);
} }
@ -1727,7 +1739,7 @@ TempoMap::beat_at_frame_locked (const Metrics& metrics, const framecnt_t& frame)
framecnt_t const offset_frame = frame + frame_offset_at (metrics, frame); framecnt_t const offset_frame = frame + frame_offset_at (metrics, frame);
double const pulse = pulse_at_frame_locked (metrics, offset_frame); double const pulse = pulse_at_frame_locked (metrics, offset_frame);
return beat_at_pulse (metrics, pulse); return beat_at_pulse_locked (metrics, pulse);
} }
double double
@ -1741,12 +1753,10 @@ TempoMap::pulse_at_frame_locked (const Metrics& metrics, const framecnt_t& frame
TempoSection* t; TempoSection* t;
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) { if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
if (prev_ts) { if (prev_ts && t->frame() > frame) {
if (t->frame() > frame) { /*the previous ts is the one containing the frame */
/*the previous ts is the one containing the frame */ double const ret = prev_ts->pulse_at_frame (frame, _frame_rate);
double const ret = prev_ts->pulse_at_frame (frame, _frame_rate); return ret;
return ret;
}
} }
accumulated_pulses = t->pulse(); accumulated_pulses = t->pulse();
prev_ts = t; prev_ts = t;
@ -1769,7 +1779,7 @@ TempoMap::frame_at_beat (const double& beat) const
framecnt_t framecnt_t
TempoMap::frame_at_beat_locked (const Metrics& metrics, const double& beat) const TempoMap::frame_at_beat_locked (const Metrics& metrics, const double& beat) const
{ {
framecnt_t const frame = frame_at_pulse_locked (metrics, pulse_at_beat (metrics, beat)); 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); frameoffset_t const frame_off = frame_offset_at (metrics, frame);
return frame - frame_off; return frame - frame_off;
} }
@ -1805,28 +1815,28 @@ TempoMap::frame_at_pulse_locked (const Metrics& metrics, const double& pulse) co
} }
double double
TempoMap::beat_offset_at (const Metrics& metrics, const double& beat) const TempoMap::pulse_offset_at (const Metrics& metrics, const double& pulse) const
{ {
MeterSection* prev_m = 0; MeterSection* prev_m = 0;
double beat_off = 0.0; double pulse_off = first_meter().pulse();
for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) { for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
MeterSection* m = 0; MeterSection* m = 0;
if ((m = dynamic_cast<MeterSection*> (*i)) != 0) { if ((m = dynamic_cast<MeterSection*> (*i)) != 0) {
if (prev_m) { if (prev_m) {
if (m->beat() > beat) { if (m->pulse() > pulse) {
break; break;
} }
if (m->position_lock_style() == AudioTime) { if (m->position_lock_style() == AudioTime) {
beat_off += ((m->pulse() - prev_m->pulse()) / prev_m->note_divisor()) - floor ((m->pulse() - prev_m->pulse()) / prev_m->note_divisor()); pulse_off += (m->pulse() - prev_m->pulse()) - floor (m->pulse() - prev_m->pulse());
} }
} }
prev_m = m; prev_m = m;
} }
} }
return beat_off; return pulse_off;
} }
frameoffset_t frameoffset_t
@ -1871,7 +1881,7 @@ TempoMap::frame_time_locked (const Metrics& metrics, const BBT_Time& bbt) const
{ {
/* HOLD THE READER LOCK */ /* HOLD THE READER LOCK */
framepos_t const ret = frame_at_pulse_locked (metrics, pulse_at_beat (metrics, bbt_to_beats_locked (metrics, bbt))); framepos_t const ret = frame_at_pulse_locked (metrics, pulse_at_beat_locked (metrics, bbt_to_beats_locked (metrics, bbt)));
return ret; return ret;
} }
@ -1891,6 +1901,7 @@ TempoMap::check_solved (Metrics& metrics, bool by_frame)
if (by_frame && t->frame() != prev_ts->frame_at_tempo (t->pulses_per_minute(), t->pulse(), _frame_rate)) { if (by_frame && t->frame() != prev_ts->frame_at_tempo (t->pulses_per_minute(), t->pulse(), _frame_rate)) {
return false; return false;
} }
/*
if (!by_frame && fabs (t->pulse() - prev_ts->pulse_at_tempo (t->pulses_per_minute(), t->frame(), _frame_rate)) > 0.00001) { if (!by_frame && fabs (t->pulse() - prev_ts->pulse_at_tempo (t->pulses_per_minute(), t->frame(), _frame_rate)) > 0.00001) {
std::cerr << "beat precision too low for bpm: " << t->beats_per_minute() << std::endl << std::cerr << "beat precision too low for bpm: " << t->beats_per_minute() << std::endl <<
" |error :" << t->pulse() - prev_ts->pulse_at_tempo (t->pulses_per_minute(), t->frame(), _frame_rate) << std::endl << " |error :" << t->pulse() - prev_ts->pulse_at_tempo (t->pulses_per_minute(), t->frame(), _frame_rate) << std::endl <<
@ -1898,6 +1909,7 @@ TempoMap::check_solved (Metrics& metrics, bool by_frame)
" |frame at tempo : " << prev_ts->frame_at_tempo (t->pulses_per_minute(), t->pulse(), _frame_rate) << std::endl; " |frame at tempo : " << prev_ts->frame_at_tempo (t->pulses_per_minute(), t->pulse(), _frame_rate) << std::endl;
return false; return false;
} }
*/
} }
prev_ts = t; prev_ts = t;
} }
@ -2441,7 +2453,7 @@ const Tempo
TempoMap::tempo_at (const framepos_t& frame) const TempoMap::tempo_at (const framepos_t& frame) const
{ {
Glib::Threads::RWLock::ReaderLock lm (lock); Glib::Threads::RWLock::ReaderLock lm (lock);
frameoffset_t const frame_off = frame_offset_at (_metrics, frame); //frameoffset_t const frame_off = frame_offset_at (_metrics, frame);
TempoSection* prev_ts = 0; TempoSection* prev_ts = 0;
Metrics::const_iterator i; Metrics::const_iterator i;
@ -2475,7 +2487,7 @@ TempoMap::meter_section_at (framepos_t frame) const
const MeterSection& const MeterSection&
TempoMap::meter_section_at_locked (framepos_t frame) const TempoMap::meter_section_at_locked (framepos_t frame) const
{ {
framepos_t const frame_off = frame + frame_offset_at (_metrics, frame); //framepos_t const frame_off = frame + frame_offset_at (_metrics, frame);
Metrics::const_iterator i; Metrics::const_iterator i;
MeterSection* prev = 0; MeterSection* prev = 0;
@ -2636,7 +2648,7 @@ TempoMap::set_state (const XMLNode& node, int /*version*/)
} }
void void
TempoMap::dump (Metrics& metrics, std::ostream& o) const TempoMap::dump (const Metrics& metrics, std::ostream& o) const
{ {
Glib::Threads::RWLock::ReaderLock lm (lock, Glib::Threads::TRY_LOCK); Glib::Threads::RWLock::ReaderLock lm (lock, Glib::Threads::TRY_LOCK);
const MeterSection* m; const MeterSection* m;