summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornick_m <mainsbridge@gmail.com>2016-03-23 01:11:00 +1100
committernick_m <mainsbridge@gmail.com>2016-05-27 23:38:12 +1000
commit58d4889ad359d43f12c7ce7a0a0e9355b936f30a (patch)
treea4ac37af2cb5667f87a47c598837c7044e60373d
parentba3ae54f516fc447ad1828cf99ca22d352189c71 (diff)
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.
-rw-r--r--gtk2_ardour/editor_drag.cc11
-rw-r--r--gtk2_ardour/editor_ops.cc2
-rw-r--r--gtk2_ardour/editor_tempodisplay.cc4
-rw-r--r--libs/ardour/ardour/tempo.h26
-rw-r--r--libs/ardour/tempo.cc86
5 files changed, 72 insertions, 57 deletions
diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc
index 3e46a0a3fe..fdb0f695fd 100644
--- a/gtk2_ardour/editor_drag.cc
+++ b/gtk2_ardour/editor_drag.cc
@@ -3182,7 +3182,7 @@ MeterMarkerDrag::motion (GdkEvent* event, bool first_move)
_marker->hide();
}
- framepos_t const pf = adjusted_current_frame (event);
+ framepos_t const pf = adjusted_current_frame (event, false);
_marker->set_position (pf);
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));
@@ -3366,8 +3366,8 @@ TempoMarkerDrag::finished (GdkEvent* event, bool movement_occurred)
XMLNode &before = map.get_state();
if (_marker->tempo().position_lock_style() == MusicTime) {
- double const beat = map.predict_tempo_beat (_real_section, _marker->tempo(), _real_section->frame());
- map.add_tempo (_marker->tempo(), beat, _marker->tempo().type());
+ double const pulse = map.predict_tempo_pulse (_real_section, _marker->tempo(), _real_section->frame());
+ map.add_tempo (_marker->tempo(), pulse, _marker->tempo().type());
} else {
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 ();
} else {
- /* we removed it before, so add it back now */
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())
- , beat, _marker->tempo().type());
+ , pulse, _marker->tempo().type());
} else {
map.replace_tempo (*_real_section, Tempo (_marker->tempo().beats_per_minute(), _marker->tempo().note_type())
, _real_section->frame(), _marker->tempo().type());
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index 1cc9d54cb6..960b7b3123 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -6552,7 +6552,7 @@ Editor::define_one_bar (framepos_t start, framepos_t end)
} else if (t.frame() == start) {
_session->tempo_map().change_existing_tempo_at (start, beats_per_minute, t.note_type());
} 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());
diff --git a/gtk2_ardour/editor_tempodisplay.cc b/gtk2_ardour/editor_tempodisplay.cc
index d817c44013..e1201579a6 100644
--- a/gtk2_ardour/editor_tempodisplay.cc
+++ b/gtk2_ardour/editor_tempodisplay.cc
@@ -242,7 +242,7 @@ Editor::mouse_add_new_tempo_event (framepos_t frame)
begin_reversible_command (_("add tempo mark"));
XMLNode &before = map.get_state();
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 {
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"));
XMLNode &before = _session->tempo_map().get_state();
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 {
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());
diff --git a/libs/ardour/ardour/tempo.h b/libs/ardour/ardour/tempo.h
index 5351d4fa94..737c288abe 100644
--- a/libs/ardour/ardour/tempo.h
+++ b/libs/ardour/ardour/tempo.h
@@ -365,7 +365,7 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
const TempoSection& tempo_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_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);
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 framepos_t& frame, TempoSection::Type type);
@@ -399,7 +399,7 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
XMLNode& get_state (void);
int set_state (const XMLNode&, int version);
- void dump (Metrics& metrics, std::ostream&) const;
+ void dump (const Metrics& metrics, std::ostream&) const;
void clear ();
TempoMetric metric_at (Timecode::BBT_Time bbt) const;
@@ -426,21 +426,25 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
Timecode::BBT_Time beats_to_bbt (const double& beats);
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;
private:
- double pulse_at_beat (const Metrics& metrics, const double& beat) const;
- double beat_at_pulse (const Metrics& metrics, const double& pulse) 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;
- 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;
+ double pulse_at_beat_locked (const Metrics& metrics, const double& beat) 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 beat_offset_at (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;
+ 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 ;
+ Timecode::BBT_Time beats_to_bbt_locked (const Metrics& metrics, const double& beats) const;
+
framepos_t frame_time_locked (const Metrics& metrics, const Timecode::BBT_Time&) const;
const MeterSection& meter_section_at_locked (framepos_t frame) const;
@@ -476,7 +480,7 @@ private:
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_meter_locked (const Meter&, double beat, Timecode::BBT_Time where, bool recompute);
diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc
index ee66f4015d..e6c9a829b9 100644
--- a/libs/ardour/tempo.cc
+++ b/libs/ardour/tempo.cc
@@ -715,7 +715,7 @@ TempoMap::do_insert (MetricSection* section)
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"),
m->bbt(), corrected.second) << endmsg;
- m->set_pulse (corrected);
+ //m->set_pulse (corrected);
}
}
@@ -822,14 +822,14 @@ TempoMap::do_insert (MetricSection* section)
}
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);
TempoSection& first (first_tempo());
if (ts.pulse() != first.pulse()) {
remove_tempo_locked (ts);
- add_tempo_locked (tempo, where, true, type);
+ add_tempo_locked (tempo, pulse, true, type);
} else {
first.set_type (type);
{
@@ -865,11 +865,11 @@ TempoMap::replace_tempo (const TempoSection& ts, const Tempo& tempo, const frame
}
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);
- add_tempo_locked (tempo, where, true, type);
+ add_tempo_locked (tempo, pulse, true, type);
}
PropertyChanged (PropertyChange ());
@@ -888,9 +888,8 @@ TempoMap::add_tempo (const Tempo& tempo, const framepos_t& frame, ARDOUR::TempoS
}
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);
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. */
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());
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());
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);
do_insert (new_meter);
@@ -1050,7 +1049,7 @@ TempoMap::predict_tempo_frame (TempoSection* section, const Tempo& bpm, const BB
framepos_t ret = 0;
TempoSection* new_section = copy_metrics_and_point (future_map, section);
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();
} else {
ret = frame_at_beat_locked (_metrics, beat);
@@ -1065,7 +1064,7 @@ TempoMap::predict_tempo_frame (TempoSection* section, const Tempo& bpm, const BB
}
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);
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);
if (solve_map (future_map, new_section, bpm, frame)) {
- ret = beat_at_pulse (future_map, new_section->pulse());
+ ret = new_section->pulse();
} else {
- ret = beat_at_frame_locked (_metrics, frame);
+ ret = pulse_at_frame_locked (_metrics, frame);
}
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);
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);
}
}
@@ -1144,7 +1143,7 @@ TempoMap::gui_move_meter (MeterSection* ms, const Meter& mt, const double& beat
{
{
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
@@ -1388,7 +1387,7 @@ TempoMap::recompute_meters (Metrics& metrics)
if (meter->position_lock_style() == AudioTime) {
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);
pr.second = where;
meter->set_pulse (pr);
@@ -1429,7 +1428,14 @@ TempoMap::recompute_map (Metrics& metrics, framepos_t end)
}
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;
double accumulated_beats = 0.0;
@@ -1450,11 +1456,17 @@ TempoMap::pulse_at_beat (const Metrics& metrics, const double& beat) const
}
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;
double accumulated_beats = 0.0;
-
for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
MeterSection* m;
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);
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);
}
@@ -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);
double const pulse = pulse_at_frame_locked (metrics, offset_frame);
- return beat_at_pulse (metrics, pulse);
+ return beat_at_pulse_locked (metrics, pulse);
}
double
@@ -1741,12 +1753,10 @@ TempoMap::pulse_at_frame_locked (const Metrics& metrics, const framecnt_t& frame
TempoSection* t;
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
- if (prev_ts) {
- if (t->frame() > frame) {
- /*the previous ts is the one containing the frame */
- double const ret = prev_ts->pulse_at_frame (frame, _frame_rate);
- return ret;
- }
+ if (prev_ts && t->frame() > frame) {
+ /*the previous ts is the one containing the frame */
+ double const ret = prev_ts->pulse_at_frame (frame, _frame_rate);
+ return ret;
}
accumulated_pulses = t->pulse();
prev_ts = t;
@@ -1769,7 +1779,7 @@ TempoMap::frame_at_beat (const double& beat) const
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 (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);
return frame - frame_off;
}
@@ -1805,28 +1815,28 @@ TempoMap::frame_at_pulse_locked (const Metrics& metrics, const double& pulse) co
}
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;
- double beat_off = 0.0;
+ double pulse_off = first_meter().pulse();
for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
MeterSection* m = 0;
if ((m = dynamic_cast<MeterSection*> (*i)) != 0) {
if (prev_m) {
- if (m->beat() > beat) {
+ if (m->pulse() > pulse) {
break;
}
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;
}
}
- return beat_off;
+ return pulse_off;
}
frameoffset_t
@@ -1871,7 +1881,7 @@ TempoMap::frame_time_locked (const Metrics& metrics, const BBT_Time& bbt) const
{
/* 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;
}
@@ -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)) {
return false;
}
+ /*
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 <<
" |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;
return false;
}
+ */
}
prev_ts = t;
}
@@ -2441,7 +2453,7 @@ const Tempo
TempoMap::tempo_at (const framepos_t& frame) const
{
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;
Metrics::const_iterator i;
@@ -2475,7 +2487,7 @@ TempoMap::meter_section_at (framepos_t frame) const
const MeterSection&
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;
MeterSection* prev = 0;
@@ -2636,7 +2648,7 @@ TempoMap::set_state (const XMLNode& node, int /*version*/)
}
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);
const MeterSection* m;