diff options
author | nick_m <mainsbridge@gmail.com> | 2015-12-24 05:42:58 +1100 |
---|---|---|
committer | nick_m <mainsbridge@gmail.com> | 2016-05-27 23:38:09 +1000 |
commit | 8d007e8a77f9d3225fae72324b788ab74d68ed2b (patch) | |
tree | ee5ef33d9e4ac7d04fa35f8174eb83985cb9466f /libs/ardour | |
parent | feece5383823df094a670833514d84b594bc4b8d (diff) |
Tempo ramps - fix many problems wrt dragging tempos over each other.
- also preparation for metric lock style and meter bug fix.
Diffstat (limited to 'libs/ardour')
-rw-r--r-- | libs/ardour/ardour/tempo.h | 13 | ||||
-rw-r--r-- | libs/ardour/tempo.cc | 115 |
2 files changed, 107 insertions, 21 deletions
diff --git a/libs/ardour/ardour/tempo.h b/libs/ardour/ardour/tempo.h index 403b4c59c9..e8f40e4236 100644 --- a/libs/ardour/ardour/tempo.h +++ b/libs/ardour/ardour/tempo.h @@ -100,9 +100,9 @@ class LIBARDOUR_API Meter { class LIBARDOUR_API MetricSection { public: MetricSection (const Timecode::BBT_Time& start) - : _start (start), _frame (0), _movable (true) {} + : _start (start), _frame (0), _movable (true), _position_lock_style (MusicTime) {} MetricSection (framepos_t start) - : _frame (start), _movable (true) {} + : _frame (start), _movable (true), _position_lock_style (MusicTime) {} virtual ~MetricSection() {} @@ -125,12 +125,15 @@ class LIBARDOUR_API MetricSection { XML state information. */ virtual XMLNode& get_state() const = 0; + PositionLockStyle position_lock_style () const { return _position_lock_style; } + void set_position_lock_style (PositionLockStyle ps) { _position_lock_style = ps; } - private: +private: Timecode::BBT_Time _start; framepos_t _frame; bool _movable; + PositionLockStyle _position_lock_style; }; /** A section of timeline with a certain Meter. */ @@ -387,8 +390,10 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible int n_meters () const; framecnt_t frame_rate () const { return _frame_rate; } + PBD::Signal0<void> MetricPositionChanged; - private: + +private: friend class ::BBTTest; friend class ::FrameposPlusBeatsTest; diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc index d4ccffdd9e..73e27a2814 100644 --- a/libs/ardour/tempo.cc +++ b/libs/ardour/tempo.cc @@ -426,6 +426,12 @@ struct MetricSectionSorter { } }; +struct MetricSectionFrameSorter { + bool operator() (const MetricSection* a, const MetricSection* b) { + return a->frame() < b->frame(); + } +}; + TempoMap::TempoMap (framecnt_t fr) { _frame_rate = fr; @@ -666,15 +672,64 @@ TempoMap::gui_set_tempo_frame (TempoSection& ts, framepos_t frame) { { TempoSection& first (first_tempo()); + if (ts.frame() != first.frame()) { + const MeterSection* meter = &meter_section_at (frame); - if (ts.start() != first.start()) { BBT_Time bbt; - bbt_time (frame, bbt); { Glib::Threads::RWLock::WriterLock lm (lock); + ts.set_frame (frame); - ts.set_start (bbt); + MetricSectionFrameSorter fcmp; + metrics.sort (fcmp); + + Metrics::const_iterator i; + TempoSection* prev_ts = 0; + for (i = metrics.begin(); i != metrics.end(); ++i) { + TempoSection* t; + + if ((t = dynamic_cast<TempoSection*> (*i)) != 0) { + + if ((*i)->frame() > frame - 1) { + break; + } + + prev_ts = t; + } + } + + if (prev_ts) { + + /* set the start bbt */ + double const ticks_to_ts = prev_ts->tick_at_frame (frame - prev_ts->frame(), ts.beats_per_minute(), frame - prev_ts->frame(), _frame_rate); + double beats = ticks_to_ts / BBT_Time::ticks_per_beat; + Timecode::BBT_Time bbt; + + bbt.bars = (uint32_t) floor (beats / meter->divisions_per_bar()); + beats -= bbt.bars * meter->divisions_per_bar(); + bbt.beats = (uint32_t) floor (beats); + beats -= bbt.beats; + bbt.ticks = (uint32_t) floor (beats * BBT_Time::ticks_per_beat); + + /* now add the prev ts bbt */ + bbt.bars += prev_ts->start().bars; + bbt.beats += prev_ts->start().beats; + + if (bbt.beats > meter->divisions_per_bar()) { + ++bbt.bars; + bbt.beats -= meter->divisions_per_bar(); + } + bbt.ticks += prev_ts->start().ticks; + if (bbt.ticks > BBT_Time::ticks_per_beat) { + ++bbt.beats; + bbt.ticks -= BBT_Time::ticks_per_beat; + } + ts.set_start (bbt); + } + + MetricSectionSorter cmp; + metrics.sort (cmp); recompute_map (false); } } @@ -726,7 +781,7 @@ TempoMap::add_tempo_locked (const Tempo& tempo, BBT_Time where, bool recompute, } } - ts->update_bar_offset_from_bbt (*meter); + //ts->update_bar_offset_from_bbt (*meter); /* and insert it */ @@ -957,9 +1012,6 @@ TempoMap::recompute_map (bool reassign_tempo_bbt, framepos_t end) } - MetricSectionSorter cmp; - metrics.sort (cmp); - DEBUG_TRACE (DEBUG::TempoMath, string_compose ("recomputing tempo map, zero to %1\n", end)); for (Metrics::iterator i = metrics.begin(); i != metrics.end(); ++i) { @@ -1010,7 +1062,7 @@ TempoMap::recompute_map (bool reassign_tempo_bbt, framepos_t end) * based on its bar offset position. */ - ts->update_bbt_time_from_bar_offset (*rmeter); + //ts->update_bbt_time_from_bar_offset (*rmeter); } else if ((ms = dynamic_cast<MeterSection*>(*i)) != 0) { rmeter = ms; @@ -1062,8 +1114,42 @@ TempoMap::_extend_map (TempoSection* tempo, MeterSection* meter, TempoSection* t; if ((t = dynamic_cast<TempoSection*> (*i)) != 0) { + if (t->position_lock_style() == AudioTime) { + /* set the start bbt */ + double const ticks_at_ts = prev_ts->tick_at_frame (t->frame(), t->beats_per_minute(), t->frame(), _frame_rate); + double const ticks_at_prev_ts = ((((prev_ts->start().bars - 1) * meter->divisions_per_bar()) + (prev_ts->start().beats - 1)) * BBT_Time::ticks_per_beat) + prev_ts->start().ticks; - if (t->start() >= m->start() && t->start() > prev_ts->start()) { + double const ticks_relative_to_prev_ts = ticks_at_ts - ticks_at_prev_ts; + double beats = ticks_relative_to_prev_ts / BBT_Time::ticks_per_beat; + + Timecode::BBT_Time bbt; + bbt.bars = (uint32_t) floor (beats / meter->divisions_per_bar()); + beats -= bbt.bars * meter->divisions_per_bar(); + bbt.beats = (uint32_t) floor (beats); + beats -= bbt.beats; + bbt.ticks = (uint32_t) floor (beats * BBT_Time::ticks_per_beat); + /* now add the prev ts bbt */ + bbt.bars += prev_ts->start().bars; + bbt.beats += prev_ts->start().beats; + + if (bbt.beats > meter->divisions_per_bar()) { + ++bbt.bars; + bbt.beats -= meter->divisions_per_bar(); + } + bbt.ticks += prev_ts->start().ticks; + if (bbt.ticks > BBT_Time::ticks_per_beat) { + ++bbt.beats; + bbt.ticks -= BBT_Time::ticks_per_beat; + } + t->set_start (bbt); + + if (m->start() < t->start() && m->start() == prev_ts->start()) { + m->set_frame (prev_ts->frame()); + } else if (m->start() < t->start() && m->start() > prev_ts->start()) { + m->set_frame (prev_ts->frame_at_tick ((first_tick_in_new_meter - ticks_at_prev_ts), t->beats_per_minute(), t->frame(), _frame_rate) + prev_ts->frame()); + } + + } else if (t->start() >= m->start() && t->start() > prev_ts->start()) { //cerr << "new ts start bars = " << t->start().bars << " beats = " << t->start().beats << " ticks = " << t->start().ticks << endl; //cerr << "prev ts start bars = " << prev_ts->start().bars << " beats = " << prev_ts->start().beats << " ticks = " << prev_ts->start().ticks << endl; @@ -1086,19 +1172,15 @@ TempoMap::_extend_map (TempoSection* tempo, MeterSection* meter, double const actual_ticks = prev_ts->tick_at_frame (length_estimate, t->beats_per_minute(), (framepos_t) length_estimate, _frame_rate); tick_error = ticks_relative_to_prev_ts - actual_ticks; length_estimate += (tick_error / BBT_Time::ticks_per_beat) * meter->frames_per_grid (*t, _frame_rate); - //cerr << "actual ticks = " << actual_ticks << endl; - - //cerr << "tick error = " << tick_error << endl; } - cerr << "setting t frame to " << length_estimate + prev_ts->frame() << " tick error = " << tick_error << endl; t->set_frame (length_estimate + prev_ts->frame()); if (m->start() < t->start() && m->start() == prev_ts->start()) { m->set_frame (prev_ts->frame()); } else if (m->start() < t->start() && m->start() > prev_ts->start()) { - cerr << "recompute map - setting meter frame to " << prev_ts->frame_at_tick ((first_tick_in_new_meter - ticks_at_prev_ts), t->beats_per_minute(), (framepos_t) length_estimate, _frame_rate) << " ticks = " << first_tick_in_new_meter - ticks_at_prev_ts << endl; + cerr << "recompute map - music lock style setting meter frame to " << prev_ts->frame_at_tick ((first_tick_in_new_meter - ticks_at_prev_ts), t->beats_per_minute(), (framepos_t) length_estimate, _frame_rate) << " ticks = " << first_tick_in_new_meter - ticks_at_prev_ts << endl; - m->set_frame (prev_ts->frame_at_tick ((first_tick_in_new_meter - ticks_at_prev_ts), t->beats_per_minute(), (framepos_t) length_estimate, _frame_rate)); + m->set_frame (prev_ts->frame_at_tick ((first_tick_in_new_meter - ticks_at_prev_ts), t->beats_per_minute(), (framepos_t) length_estimate, _frame_rate) + prev_ts->frame()); } } prev_ts = t; @@ -1344,7 +1426,6 @@ TempoMap::beats_to_bbt (double beats) double TempoMap::tick_at_frame (framecnt_t frame) const { - Glib::Threads::RWLock::ReaderLock lm (lock); Metrics::const_iterator i; const TempoSection* prev_ts = &first_tempo(); @@ -1927,7 +2008,7 @@ TempoMap::set_state (const XMLNode& node, int /*version*/) if (ts->bar_offset() < 0.0) { if (last_meter) { - ts->update_bar_offset_from_bbt (*last_meter); + //ts->update_bar_offset_from_bbt (*last_meter); } } } |