From: nick_m Date: Thu, 26 May 2016 15:25:47 +0000 (+1000) Subject: Tempo ramps - rename tempo_at() -> tempo_at_frame().. 3 decimals for the audioclock... X-Git-Tag: 5.0-pre0~331 X-Git-Url: https://main.carlh.net/gitweb/?p=ardour.git;a=commitdiff_plain;h=8f3bc6f8099d7fc3bcc7f0dc88434afa0084e35f Tempo ramps - rename tempo_at() -> tempo_at_frame().. 3 decimals for the audioclock tempo display. --- diff --git a/gtk2_ardour/audio_clock.cc b/gtk2_ardour/audio_clock.cc index e7aff0ef13..7cdf66123d 100644 --- a/gtk2_ardour/audio_clock.cc +++ b/gtk2_ardour/audio_clock.cc @@ -1287,7 +1287,7 @@ AudioClock::set_bbt (framepos_t when, bool /*force*/) TempoMetric m (_session->tempo_map().metric_at (pos)); - sprintf (buf, "%-5.1f", _session->tempo_map().tempo_at (pos).beats_per_minute()); + sprintf (buf, "%-5.3f", _session->tempo_map().tempo_at_frame (pos).beats_per_minute()); _left_layout->set_markup (string_compose ("" TXTSPAN "%3 %2", INFO_FONT_SIZE, buf, _("Tempo"))); diff --git a/gtk2_ardour/automation_controller.cc b/gtk2_ardour/automation_controller.cc index b598f44f94..66c051ee19 100644 --- a/gtk2_ardour/automation_controller.cc +++ b/gtk2_ardour/automation_controller.cc @@ -261,7 +261,7 @@ AutomationController::set_freq_beats(double beats) const ARDOUR::ParameterDescriptor& desc = _controllable->desc(); const ARDOUR::Session& session = _controllable->session(); const framepos_t pos = session.transport_frame(); - const ARDOUR::Tempo& tempo = session.tempo_map().tempo_at(pos); + const ARDOUR::Tempo& tempo = session.tempo_map().tempo_at_frame (pos); const double bpm = tempo.beats_per_minute(); const double bps = bpm / 60.0; const double freq = bps / beats; diff --git a/gtk2_ardour/automation_line.cc b/gtk2_ardour/automation_line.cc index 2094d43eff..47e91021ae 100644 --- a/gtk2_ardour/automation_line.cc +++ b/gtk2_ardour/automation_line.cc @@ -547,7 +547,7 @@ AutomationLine::ContiguousControlPoints::compute_x_bounds (PublicEditor& e) const framepos_t pos = e.pixel_to_sample(before_x); const Meter& meter = map.meter_at (pos); - const framecnt_t len = ceil (meter.frames_per_bar (map.tempo_at (pos), e.session()->frame_rate()) + const framecnt_t len = ceil (meter.frames_per_bar (map.tempo_at_frame (pos), e.session()->frame_rate()) / (Timecode::BBT_Time::ticks_per_beat * meter.divisions_per_bar()) ); const double one_tick_in_pixels = e.sample_to_pixel_unrounded (len); @@ -563,7 +563,7 @@ AutomationLine::ContiguousControlPoints::compute_x_bounds (PublicEditor& e) const framepos_t pos = e.pixel_to_sample(after_x); const Meter& meter = map.meter_at (pos); - const framecnt_t len = ceil (meter.frames_per_bar (map.tempo_at (pos), e.session()->frame_rate()) + const framecnt_t len = ceil (meter.frames_per_bar (map.tempo_at_frame (pos), e.session()->frame_rate()) / (Timecode::BBT_Time::ticks_per_beat * meter.divisions_per_bar())); const double one_tick_in_pixels = e.sample_to_pixel_unrounded (len); diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 9547a0f574..07b2eabbad 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -3418,7 +3418,7 @@ BBTRulerDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor) ostringstream sstr; _tempo = const_cast (&map.tempo_section_at (raw_grab_frame())); - sstr << "^" << fixed << setprecision(3) << map.tempo_at (adjusted_current_frame (event)).beats_per_minute() << "\n"; + sstr << "^" << fixed << setprecision(3) << map.tempo_at_frame (adjusted_current_frame (event)).beats_per_minute() << "\n"; sstr << "<" << fixed << setprecision(3) << _tempo->beats_per_minute(); show_verbose_cursor_text (sstr.str()); finished (event, false); @@ -3461,7 +3461,7 @@ BBTRulerDrag::motion (GdkEvent* event, bool first_move) _editor->session()->tempo_map().gui_dilate_tempo (_tempo, map.frame_at_pulse (_pulse), pf, _pulse); } ostringstream sstr; - sstr << "^" << fixed << setprecision(3) << map.tempo_at (pf).beats_per_minute() << "\n"; + sstr << "^" << fixed << setprecision(3) << map.tempo_at_frame (pf).beats_per_minute() << "\n"; sstr << "<" << fixed << setprecision(3) << _tempo->beats_per_minute(); show_verbose_cursor_text (sstr.str()); } diff --git a/gtk2_ardour/editor_tempodisplay.cc b/gtk2_ardour/editor_tempodisplay.cc index ef04f84b76..adf0f72fe3 100644 --- a/gtk2_ardour/editor_tempodisplay.cc +++ b/gtk2_ardour/editor_tempodisplay.cc @@ -316,7 +316,7 @@ Editor::mouse_add_new_tempo_event (framepos_t frame) if (pulse > 0.0) { XMLNode &before = map.get_state(); /* add music-locked ramped (?) tempo using the bpm/note type at frame*/ - map.add_tempo (map.tempo_at (frame), pulse, 0, TempoSection::Ramp, MusicTime); + map.add_tempo (map.tempo_at_frame (frame), pulse, 0, TempoSection::Ramp, MusicTime); XMLNode &after = map.get_state(); _session->add_command(new MementoCommand(map, &before, &after)); diff --git a/gtk2_ardour/step_editor.cc b/gtk2_ardour/step_editor.cc index e8579a94f5..62b2646b81 100644 --- a/gtk2_ardour/step_editor.cc +++ b/gtk2_ardour/step_editor.cc @@ -116,7 +116,7 @@ StepEditor::prepare_step_edit_region () } else { const Meter& m = _mtv.session()->tempo_map().meter_at (step_edit_insert_position); - const Tempo& t = _mtv.session()->tempo_map().tempo_at (step_edit_insert_position); + const Tempo& t = _mtv.session()->tempo_map().tempo_at_frame (step_edit_insert_position); double baf = _mtv.session()->tempo_map().beat_at_frame (step_edit_insert_position); double next_bar_in_beats = baf + m.divisions_per_bar(); diff --git a/gtk2_ardour/tempo_dialog.cc b/gtk2_ardour/tempo_dialog.cc index 5cb897e148..b68e82f30b 100644 --- a/gtk2_ardour/tempo_dialog.cc +++ b/gtk2_ardour/tempo_dialog.cc @@ -46,7 +46,7 @@ TempoDialog::TempoDialog (TempoMap& map, framepos_t frame, const string&) , tap_tempo_button (_("Tap tempo")) { Timecode::BBT_Time when; - Tempo tempo (map.tempo_at (frame)); + Tempo tempo (map.tempo_at_frame (frame)); map.bbt_time (frame, when); init (when, tempo.beats_per_minute(), tempo.note_type(), TempoSection::Constant, true, MusicTime); diff --git a/libs/ardour/ardour/tempo.h b/libs/ardour/ardour/tempo.h index 663b8a9411..52caaf5030 100644 --- a/libs/ardour/ardour/tempo.h +++ b/libs/ardour/ardour/tempo.h @@ -327,44 +327,9 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible void get_grid (std::vector&, framepos_t start, framepos_t end); - /* TEMPO- AND METER-SENSITIVE FUNCTIONS - - bbt_time(), beat_at_frame(), frame_at_beat(), tick_at_frame(), - frame_at_tick(),frame_time() and bbt_duration_at() - are all sensitive to tempo and meter, and will give answers - that align with the grid formed by tempo and meter sections. - - They SHOULD NOT be used to determine the position of events - whose location is canonically defined in beats. - */ - - void bbt_time (framepos_t when, Timecode::BBT_Time&); - - double beat_at_frame (const framecnt_t& frame) const; - framecnt_t frame_at_beat (const double& beat) const; - - framepos_t frame_time (const Timecode::BBT_Time&); - framecnt_t bbt_duration_at (framepos_t, const Timecode::BBT_Time&, int dir); - - /* TEMPO-SENSITIVE FUNCTIONS - - These next 4 functions will all take tempo in account and should be - used to determine position (and in the last case, distance in beats) - when tempo matters but meter does not. - - They SHOULD be used to determine the position of events - whose location is canonically defined in beats. - */ - - framepos_t framepos_plus_bbt (framepos_t pos, Timecode::BBT_Time b) const; - framepos_t framepos_plus_beats (framepos_t, Evoral::Beats) const; - framepos_t framepos_minus_beats (framepos_t, Evoral::Beats) const; - Evoral::Beats framewalk_to_beats (framepos_t pos, framecnt_t distance) const; - static const Tempo& default_tempo() { return _default_tempo; } static const Meter& default_meter() { return _default_meter; } - const Tempo tempo_at (const framepos_t& frame) const; double frames_per_beat_at (const framepos_t&, const framecnt_t& sr) const; const Meter& meter_at (framepos_t) const; @@ -397,16 +362,6 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible void replace_meter (const MeterSection&, const Meter&, const Timecode::BBT_Time& where, const framepos_t& frame , PositionLockStyle pls); - std::pair predict_tempo_position (TempoSection* section, const Timecode::BBT_Time& bbt); - - void gui_move_tempo (TempoSection*, const framepos_t& frame); - void gui_move_meter (MeterSection*, const framepos_t& frame); - - bool gui_change_tempo (TempoSection*, const Tempo& bpm); - void gui_dilate_tempo (TempoSection* tempo, const framepos_t& frame, const framepos_t& end_frame, const double& pulse); - - bool can_solve_bbt (TempoSection* section, const Timecode::BBT_Time& bbt); - framepos_t round_to_bar (framepos_t frame, RoundMode dir); framepos_t round_to_beat (framepos_t frame, RoundMode dir); framepos_t round_to_beat_subdivision (framepos_t fr, int sub_num, RoundMode dir); @@ -441,11 +396,19 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible framecnt_t frame_rate () const { return _frame_rate; } - double beat_at_bbt (const Timecode::BBT_Time& bbt); - Timecode::BBT_Time bbt_at_beat (const double& beats); + /* TEMPO- AND METER-SENSITIVE FUNCTIONS - double pulse_at_bbt (const Timecode::BBT_Time& bbt); - Timecode::BBT_Time bbt_at_pulse (const double& pulse); + bbt_time(), beat_at_frame(), frame_at_beat(), frame_time() + and bbt_duration_at() + are all sensitive to tempo and meter, and will give answers + that align with the grid formed by tempo and meter sections. + + They SHOULD NOT be used to determine the position of events + whose location is canonically defined in beats. + */ + + double beat_at_frame (const framecnt_t& frame) const; + framecnt_t frame_at_beat (const double& beat) const; double pulse_at_beat (const double& beat) const; double beat_at_pulse (const double& pulse) const; @@ -453,6 +416,42 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible double pulse_at_frame (const framecnt_t& frame) const; framecnt_t frame_at_pulse (const double& pulse) const; + const Tempo tempo_at_frame (const framepos_t& frame) const; + + double beat_at_bbt (const Timecode::BBT_Time& bbt); + Timecode::BBT_Time bbt_at_beat (const double& beats); + + double pulse_at_bbt (const Timecode::BBT_Time& bbt); + Timecode::BBT_Time bbt_at_pulse (const double& pulse); + + std::pair predict_tempo_position (TempoSection* section, const Timecode::BBT_Time& bbt); + + void bbt_time (framepos_t when, Timecode::BBT_Time&); + framepos_t frame_time (const Timecode::BBT_Time&); + framecnt_t bbt_duration_at (framepos_t, const Timecode::BBT_Time&, int dir); + + /* TEMPO-SENSITIVE FUNCTIONS + + These next 4 functions will all take tempo in account and should be + used to determine position (and in the last case, distance in beats) + when tempo matters but meter does not. + + They SHOULD be used to determine the position of events + whose location is canonically defined in beats. + */ + + framepos_t framepos_plus_bbt (framepos_t pos, Timecode::BBT_Time b) const; + framepos_t framepos_plus_beats (framepos_t, Evoral::Beats) const; + framepos_t framepos_minus_beats (framepos_t, Evoral::Beats) const; + Evoral::Beats framewalk_to_beats (framepos_t pos, framecnt_t distance) const; + + void gui_move_tempo (TempoSection*, const framepos_t& frame); + void gui_move_meter (MeterSection*, const framepos_t& frame); + bool gui_change_tempo (TempoSection*, const Tempo& bpm); + void gui_dilate_tempo (TempoSection* tempo, const framepos_t& frame, const framepos_t& end_frame, const double& pulse); + + bool can_solve_bbt (TempoSection* section, const Timecode::BBT_Time& bbt); + PBD::Signal0 MetricPositionChanged; private: @@ -471,12 +470,13 @@ private: double pulse_at_bbt_locked (const Metrics& metrics, const Timecode::BBT_Time& bbt) const; Timecode::BBT_Time bbt_at_pulse_locked (const Metrics& metrics, const double& pulse) const; + const Tempo tempo_at_frame_locked (const Metrics& metrics, const framepos_t& frame) const; + framepos_t frame_time_locked (const Metrics& metrics, const Timecode::BBT_Time&) const; const TempoSection& tempo_section_at_locked (const Metrics& metrics, framepos_t frame) const; const TempoSection& tempo_section_at_beat_locked (const Metrics& metrics, const double& beat) const; const TempoSection& tempo_section_at_pulse_locked (const Metrics& metrics, const double& pulse) const; - const Tempo tempo_at_locked (const Metrics& metrics, const framepos_t& frame) const; const MeterSection& meter_section_at_locked (const Metrics& metrics, framepos_t frame) const; const MeterSection& meter_section_at_beat_locked (const Metrics& metrics, const double& beat) const; diff --git a/libs/ardour/midi_clock_slave.cc b/libs/ardour/midi_clock_slave.cc index c7acb1b58c..9743327ec6 100644 --- a/libs/ardour/midi_clock_slave.cc +++ b/libs/ardour/midi_clock_slave.cc @@ -82,7 +82,7 @@ MIDIClock_Slave::rebind (MidiPort& port) void MIDIClock_Slave::calculate_one_ppqn_in_frames_at(framepos_t time) { - const Tempo& current_tempo = session->tempo_map().tempo_at(time); + const Tempo& current_tempo = session->tempo_map().tempo_at_frame (time); double const frames_per_beat = session->tempo_map().frames_per_beat_at (time, session->frame_rate()); double quarter_notes_per_beat = 4.0 / current_tempo.note_type(); diff --git a/libs/ardour/session_vst.cc b/libs/ardour/session_vst.cc index 34df6bd52e..ad732e052a 100644 --- a/libs/ardour/session_vst.cc +++ b/libs/ardour/session_vst.cc @@ -357,7 +357,7 @@ intptr_t Session::vst_callback ( SHOW_CALLBACK ("audioMasterTempoAt"); // returns tempo (in bpm * 10000) at sample frame location passed in if (session) { - const Tempo& t (session->tempo_map().tempo_at (value)); + const Tempo& t (session->tempo_map().tempo_at_frame (value)); return t.beats_per_minute() * 1000; } else { return 0; diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc index ca21d32e48..fcb840c0ed 100644 --- a/libs/ardour/tempo.cc +++ b/libs/ardour/tempo.cc @@ -1014,7 +1014,7 @@ TempoMap::add_meter_locked (const Meter& meter, double beat, const Timecode::BBT if (pls == AudioTime) { /* add meter-locked tempo */ - add_tempo_locked (tempo_at_locked (_metrics, frame), pulse, frame, TempoSection::Ramp, AudioTime, true, true); + add_tempo_locked (tempo_at_frame_locked (_metrics, frame), pulse, frame, TempoSection::Ramp, AudioTime, true, true); } MeterSection* new_meter = new MeterSection (pulse, frame, beat, where, meter.divisions_per_bar(), meter.note_divisor(), pls); @@ -1385,6 +1385,70 @@ TempoMap::metric_at (BBT_Time bbt) const return m; } +double +TempoMap::beat_at_frame (const framecnt_t& frame) const +{ + Glib::Threads::RWLock::ReaderLock lm (lock); + return beat_at_frame_locked (_metrics, frame); +} + +/* meter / tempo section based */ +double +TempoMap::beat_at_frame_locked (const Metrics& metrics, const framecnt_t& frame) const +{ + const TempoSection& ts = tempo_section_at_locked (metrics, frame); + MeterSection* prev_m = 0; + MeterSection* next_m = 0; + + for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) { + MeterSection* m; + if ((m = dynamic_cast (*i)) != 0) { + if (prev_m && m->frame() > frame) { + next_m = m; + break; + } + prev_m = m; + } + } + if (frame < prev_m->frame()) { + return 0.0; + } + const double beat = prev_m->beat() + (ts.pulse_at_frame (frame, _frame_rate) - prev_m->pulse()) * prev_m->note_divisor(); + + if (next_m && next_m->beat() < beat) { + return next_m->beat(); + } + + return beat; +} + +framecnt_t +TempoMap::frame_at_beat (const double& beat) const +{ + Glib::Threads::RWLock::ReaderLock lm (lock); + return frame_at_beat_locked (_metrics, beat); +} + +/* meter section based */ +framecnt_t +TempoMap::frame_at_beat_locked (const Metrics& metrics, const double& beat) const +{ + const TempoSection& prev_t = tempo_section_at_beat_locked (metrics, beat); + MeterSection* prev_m = 0; + + for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) { + MeterSection* m; + if ((m = dynamic_cast (*i)) != 0) { + if (prev_m && m->beat() > beat) { + break; + } + prev_m = m; + } + } + + return prev_t.frame_at_pulse (((beat - prev_m->beat()) / prev_m->note_divisor()) + prev_m->pulse(), _frame_rate); +} + double TempoMap::pulse_at_beat (const double& beat) const { @@ -1512,69 +1576,42 @@ TempoMap::frame_at_pulse_locked (const Metrics& metrics, const double& pulse) co return ret; } -double -TempoMap::beat_at_frame (const framecnt_t& frame) const +const Tempo +TempoMap::tempo_at_frame (const framepos_t& frame) const { Glib::Threads::RWLock::ReaderLock lm (lock); - return beat_at_frame_locked (_metrics, frame); + return tempo_at_frame_locked (_metrics, frame); } -/* meter / tempo section based */ -double -TempoMap::beat_at_frame_locked (const Metrics& metrics, const framecnt_t& frame) const +const Tempo +TempoMap::tempo_at_frame_locked (const Metrics& metrics, const framepos_t& frame) const { - const TempoSection& ts = tempo_section_at_locked (metrics, frame); - MeterSection* prev_m = 0; - MeterSection* next_m = 0; + TempoSection* prev_t = 0; - for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) { - MeterSection* m; - if ((m = dynamic_cast (*i)) != 0) { - if (prev_m && m->frame() > frame) { - next_m = m; - break; + Metrics::const_iterator i; + + for (i = _metrics.begin(); i != _metrics.end(); ++i) { + TempoSection* t; + if ((t = dynamic_cast (*i)) != 0) { + if (!t->active()) { + continue; } - prev_m = m; + if ((prev_t) && t->frame() > frame) { + /* t is the section past frame */ + const double ret_bpm = prev_t->tempo_at_frame (frame, _frame_rate) * prev_t->note_type(); + const Tempo ret_tempo (ret_bpm, prev_t->note_type()); + return ret_tempo; + } + prev_t = t; } } - if (frame < prev_m->frame()) { - return 0.0; - } - const double beat = prev_m->beat() + (ts.pulse_at_frame (frame, _frame_rate) - prev_m->pulse()) * prev_m->note_divisor(); - - if (next_m && next_m->beat() < beat) { - return next_m->beat(); - } - return beat; -} + const double ret = prev_t->beats_per_minute(); + const Tempo ret_tempo (ret, prev_t->note_type ()); -framecnt_t -TempoMap::frame_at_beat (const double& beat) const -{ - Glib::Threads::RWLock::ReaderLock lm (lock); - return frame_at_beat_locked (_metrics, beat); + return ret_tempo; } -/* meter section based */ -framecnt_t -TempoMap::frame_at_beat_locked (const Metrics& metrics, const double& beat) const -{ - const TempoSection& prev_t = tempo_section_at_beat_locked (metrics, beat); - MeterSection* prev_m = 0; - - for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) { - MeterSection* m; - if ((m = dynamic_cast (*i)) != 0) { - if (prev_m && m->beat() > beat) { - break; - } - prev_m = m; - } - } - - return prev_t.frame_at_pulse (((beat - prev_m->beat()) / prev_m->note_divisor()) + prev_m->pulse(), _frame_rate); -} double TempoMap::beat_at_bbt (const Timecode::BBT_Time& bbt) @@ -2814,7 +2851,7 @@ TempoMap::get_grid (vector& points, const TempoSection tempo = tempo_section_at_locked (_metrics, pos); const MeterSection meter = meter_section_at_locked (_metrics, pos); const BBT_Time bbt = bbt_at_beat_locked (_metrics, cnt); - points.push_back (BBTPoint (meter, tempo_at_locked (_metrics, pos), pos, bbt.bars, bbt.beats, tempo.c_func())); + points.push_back (BBTPoint (meter, tempo_at_frame_locked (_metrics, pos), pos, bbt.bars, bbt.beats, tempo.c_func())); ++cnt; } } @@ -2925,42 +2962,6 @@ TempoMap::frames_per_beat_at (const framepos_t& frame, const framecnt_t& sr) con return ts_at->frames_per_beat (_frame_rate); } -const Tempo -TempoMap::tempo_at_locked (const Metrics& metrics, const framepos_t& frame) const -{ - TempoSection* prev_t = 0; - - Metrics::const_iterator i; - - for (i = _metrics.begin(); i != _metrics.end(); ++i) { - TempoSection* t; - if ((t = dynamic_cast (*i)) != 0) { - if (!t->active()) { - continue; - } - if ((prev_t) && t->frame() > frame) { - /* t is the section past frame */ - const double ret_bpm = prev_t->tempo_at_frame (frame, _frame_rate) * prev_t->note_type(); - const Tempo ret_tempo (ret_bpm, prev_t->note_type()); - return ret_tempo; - } - prev_t = t; - } - } - - const double ret = prev_t->beats_per_minute(); - const Tempo ret_tempo (ret, prev_t->note_type ()); - - return ret_tempo; -} - -const Tempo -TempoMap::tempo_at (const framepos_t& frame) const -{ - Glib::Threads::RWLock::ReaderLock lm (lock); - return tempo_at_locked (_metrics, frame); -} - const MeterSection& TempoMap::meter_section_at_locked (const Metrics& metrics, framepos_t frame) const { diff --git a/libs/ardour/ticker.cc b/libs/ardour/ticker.cc index 6236044499..58a1c4573d 100644 --- a/libs/ardour/ticker.cc +++ b/libs/ardour/ticker.cc @@ -307,7 +307,7 @@ MidiClockTicker::tick (const framepos_t& /* transport_frame */, pframes_t nframe double MidiClockTicker::one_ppqn_in_frames (framepos_t transport_position) { - const Tempo& current_tempo = _session->tempo_map().tempo_at (transport_position); + const Tempo& current_tempo = _session->tempo_map().tempo_at_frame (transport_position); double frames_per_beat = _session->tempo_map().frames_per_beat_at (transport_position, _session->nominal_frame_rate()); double quarter_notes_per_beat = 4.0 / current_tempo.note_type();