mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-07 15:25:01 +01:00
Tempo ramps - rename tempo_at() -> tempo_at_frame().. 3 decimals for the audioclock tempo display.
This commit is contained in:
parent
250c88c038
commit
8f3bc6f809
12 changed files with 152 additions and 151 deletions
|
|
@ -1287,7 +1287,7 @@ AudioClock::set_bbt (framepos_t when, bool /*force*/)
|
||||||
|
|
||||||
TempoMetric m (_session->tempo_map().metric_at (pos));
|
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 ("<span size=\"%1\">" TXTSPAN "%3</span> <span foreground=\"green\">%2</span></span>",
|
_left_layout->set_markup (string_compose ("<span size=\"%1\">" TXTSPAN "%3</span> <span foreground=\"green\">%2</span></span>",
|
||||||
INFO_FONT_SIZE, buf, _("Tempo")));
|
INFO_FONT_SIZE, buf, _("Tempo")));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -261,7 +261,7 @@ AutomationController::set_freq_beats(double beats)
|
||||||
const ARDOUR::ParameterDescriptor& desc = _controllable->desc();
|
const ARDOUR::ParameterDescriptor& desc = _controllable->desc();
|
||||||
const ARDOUR::Session& session = _controllable->session();
|
const ARDOUR::Session& session = _controllable->session();
|
||||||
const framepos_t pos = session.transport_frame();
|
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 bpm = tempo.beats_per_minute();
|
||||||
const double bps = bpm / 60.0;
|
const double bps = bpm / 60.0;
|
||||||
const double freq = bps / beats;
|
const double freq = bps / beats;
|
||||||
|
|
|
||||||
|
|
@ -547,7 +547,7 @@ AutomationLine::ContiguousControlPoints::compute_x_bounds (PublicEditor& e)
|
||||||
|
|
||||||
const framepos_t pos = e.pixel_to_sample(before_x);
|
const framepos_t pos = e.pixel_to_sample(before_x);
|
||||||
const Meter& meter = map.meter_at (pos);
|
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()) );
|
/ (Timecode::BBT_Time::ticks_per_beat * meter.divisions_per_bar()) );
|
||||||
const double one_tick_in_pixels = e.sample_to_pixel_unrounded (len);
|
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 framepos_t pos = e.pixel_to_sample(after_x);
|
||||||
const Meter& meter = map.meter_at (pos);
|
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()));
|
/ (Timecode::BBT_Time::ticks_per_beat * meter.divisions_per_bar()));
|
||||||
const double one_tick_in_pixels = e.sample_to_pixel_unrounded (len);
|
const double one_tick_in_pixels = e.sample_to_pixel_unrounded (len);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3418,7 +3418,7 @@ BBTRulerDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
|
||||||
ostringstream sstr;
|
ostringstream sstr;
|
||||||
|
|
||||||
_tempo = const_cast<TempoSection*> (&map.tempo_section_at (raw_grab_frame()));
|
_tempo = const_cast<TempoSection*> (&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();
|
sstr << "<" << fixed << setprecision(3) << _tempo->beats_per_minute();
|
||||||
show_verbose_cursor_text (sstr.str());
|
show_verbose_cursor_text (sstr.str());
|
||||||
finished (event, false);
|
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);
|
_editor->session()->tempo_map().gui_dilate_tempo (_tempo, map.frame_at_pulse (_pulse), pf, _pulse);
|
||||||
}
|
}
|
||||||
ostringstream sstr;
|
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();
|
sstr << "<" << fixed << setprecision(3) << _tempo->beats_per_minute();
|
||||||
show_verbose_cursor_text (sstr.str());
|
show_verbose_cursor_text (sstr.str());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -316,7 +316,7 @@ Editor::mouse_add_new_tempo_event (framepos_t frame)
|
||||||
if (pulse > 0.0) {
|
if (pulse > 0.0) {
|
||||||
XMLNode &before = map.get_state();
|
XMLNode &before = map.get_state();
|
||||||
/* add music-locked ramped (?) tempo using the bpm/note type at frame*/
|
/* 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();
|
XMLNode &after = map.get_state();
|
||||||
_session->add_command(new MementoCommand<TempoMap>(map, &before, &after));
|
_session->add_command(new MementoCommand<TempoMap>(map, &before, &after));
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,7 @@ StepEditor::prepare_step_edit_region ()
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
const Meter& m = _mtv.session()->tempo_map().meter_at (step_edit_insert_position);
|
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 baf = _mtv.session()->tempo_map().beat_at_frame (step_edit_insert_position);
|
||||||
double next_bar_in_beats = baf + m.divisions_per_bar();
|
double next_bar_in_beats = baf + m.divisions_per_bar();
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ TempoDialog::TempoDialog (TempoMap& map, framepos_t frame, const string&)
|
||||||
, tap_tempo_button (_("Tap tempo"))
|
, tap_tempo_button (_("Tap tempo"))
|
||||||
{
|
{
|
||||||
Timecode::BBT_Time when;
|
Timecode::BBT_Time when;
|
||||||
Tempo tempo (map.tempo_at (frame));
|
Tempo tempo (map.tempo_at_frame (frame));
|
||||||
map.bbt_time (frame, when);
|
map.bbt_time (frame, when);
|
||||||
|
|
||||||
init (when, tempo.beats_per_minute(), tempo.note_type(), TempoSection::Constant, true, MusicTime);
|
init (when, tempo.beats_per_minute(), tempo.note_type(), TempoSection::Constant, true, MusicTime);
|
||||||
|
|
|
||||||
|
|
@ -327,44 +327,9 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
|
||||||
void get_grid (std::vector<BBTPoint>&,
|
void get_grid (std::vector<BBTPoint>&,
|
||||||
framepos_t start, framepos_t end);
|
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 Tempo& default_tempo() { return _default_tempo; }
|
||||||
static const Meter& default_meter() { return _default_meter; }
|
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;
|
double frames_per_beat_at (const framepos_t&, const framecnt_t& sr) const;
|
||||||
|
|
||||||
const Meter& meter_at (framepos_t) 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
|
void replace_meter (const MeterSection&, const Meter&, const Timecode::BBT_Time& where, const framepos_t& frame
|
||||||
, PositionLockStyle pls);
|
, PositionLockStyle pls);
|
||||||
|
|
||||||
std::pair<double, framepos_t> 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_bar (framepos_t frame, RoundMode dir);
|
||||||
framepos_t round_to_beat (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);
|
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; }
|
framecnt_t frame_rate () const { return _frame_rate; }
|
||||||
|
|
||||||
double beat_at_bbt (const Timecode::BBT_Time& bbt);
|
/* TEMPO- AND METER-SENSITIVE FUNCTIONS
|
||||||
Timecode::BBT_Time bbt_at_beat (const double& beats);
|
|
||||||
|
|
||||||
double pulse_at_bbt (const Timecode::BBT_Time& bbt);
|
bbt_time(), beat_at_frame(), frame_at_beat(), frame_time()
|
||||||
Timecode::BBT_Time bbt_at_pulse (const double& pulse);
|
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 pulse_at_beat (const double& beat) const;
|
||||||
double beat_at_pulse (const double& pulse) 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;
|
double pulse_at_frame (const framecnt_t& frame) const;
|
||||||
framecnt_t frame_at_pulse (const double& pulse) 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<double, framepos_t> 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<void> MetricPositionChanged;
|
PBD::Signal0<void> MetricPositionChanged;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -471,12 +470,13 @@ private:
|
||||||
double pulse_at_bbt_locked (const Metrics& metrics, const Timecode::BBT_Time& bbt) const;
|
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;
|
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;
|
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_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_beat_locked (const Metrics& metrics, const double& beat) const;
|
||||||
const TempoSection& tempo_section_at_pulse_locked (const Metrics& metrics, const double& pulse) 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_locked (const Metrics& metrics, framepos_t frame) const;
|
||||||
const MeterSection& meter_section_at_beat_locked (const Metrics& metrics, const double& beat) const;
|
const MeterSection& meter_section_at_beat_locked (const Metrics& metrics, const double& beat) const;
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ MIDIClock_Slave::rebind (MidiPort& port)
|
||||||
void
|
void
|
||||||
MIDIClock_Slave::calculate_one_ppqn_in_frames_at(framepos_t time)
|
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 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();
|
double quarter_notes_per_beat = 4.0 / current_tempo.note_type();
|
||||||
|
|
|
||||||
|
|
@ -357,7 +357,7 @@ intptr_t Session::vst_callback (
|
||||||
SHOW_CALLBACK ("audioMasterTempoAt");
|
SHOW_CALLBACK ("audioMasterTempoAt");
|
||||||
// returns tempo (in bpm * 10000) at sample frame location passed in <value>
|
// returns tempo (in bpm * 10000) at sample frame location passed in <value>
|
||||||
if (session) {
|
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;
|
return t.beats_per_minute() * 1000;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -1014,7 +1014,7 @@ TempoMap::add_meter_locked (const Meter& meter, double beat, const Timecode::BBT
|
||||||
|
|
||||||
if (pls == AudioTime) {
|
if (pls == AudioTime) {
|
||||||
/* add meter-locked tempo */
|
/* 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);
|
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;
|
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<MeterSection*> (*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<MeterSection*> (*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
|
double
|
||||||
TempoMap::pulse_at_beat (const double& beat) const
|
TempoMap::pulse_at_beat (const double& beat) const
|
||||||
{
|
{
|
||||||
|
|
@ -1512,70 +1576,43 @@ TempoMap::frame_at_pulse_locked (const Metrics& metrics, const double& pulse) co
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
double
|
const Tempo
|
||||||
TempoMap::beat_at_frame (const framecnt_t& frame) const
|
TempoMap::tempo_at_frame (const framepos_t& frame) const
|
||||||
{
|
{
|
||||||
Glib::Threads::RWLock::ReaderLock lm (lock);
|
Glib::Threads::RWLock::ReaderLock lm (lock);
|
||||||
return beat_at_frame_locked (_metrics, frame);
|
return tempo_at_frame_locked (_metrics, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* meter / tempo section based */
|
const Tempo
|
||||||
double
|
TempoMap::tempo_at_frame_locked (const Metrics& metrics, const framepos_t& frame) const
|
||||||
TempoMap::beat_at_frame_locked (const Metrics& metrics, const framecnt_t& frame) const
|
|
||||||
{
|
{
|
||||||
const TempoSection& ts = tempo_section_at_locked (metrics, frame);
|
TempoSection* prev_t = 0;
|
||||||
MeterSection* prev_m = 0;
|
|
||||||
MeterSection* next_m = 0;
|
|
||||||
|
|
||||||
for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
|
Metrics::const_iterator i;
|
||||||
MeterSection* m;
|
|
||||||
if ((m = dynamic_cast<MeterSection*> (*i)) != 0) {
|
for (i = _metrics.begin(); i != _metrics.end(); ++i) {
|
||||||
if (prev_m && m->frame() > frame) {
|
TempoSection* t;
|
||||||
next_m = m;
|
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
|
||||||
break;
|
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();
|
||||||
if (frame < prev_m->frame()) {
|
const Tempo ret_tempo (ret_bpm, prev_t->note_type());
|
||||||
return 0.0;
|
return ret_tempo;
|
||||||
}
|
|
||||||
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<MeterSection*> (*i)) != 0) {
|
|
||||||
if (prev_m && m->beat() > beat) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
prev_m = m;
|
prev_t = t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return prev_t.frame_at_pulse (((beat - prev_m->beat()) / prev_m->note_divisor()) + prev_m->pulse(), _frame_rate);
|
const double ret = prev_t->beats_per_minute();
|
||||||
|
const Tempo ret_tempo (ret, prev_t->note_type ());
|
||||||
|
|
||||||
|
return ret_tempo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double
|
double
|
||||||
TempoMap::beat_at_bbt (const Timecode::BBT_Time& bbt)
|
TempoMap::beat_at_bbt (const Timecode::BBT_Time& bbt)
|
||||||
{
|
{
|
||||||
|
|
@ -2814,7 +2851,7 @@ TempoMap::get_grid (vector<TempoMap::BBTPoint>& points,
|
||||||
const TempoSection tempo = tempo_section_at_locked (_metrics, pos);
|
const TempoSection tempo = tempo_section_at_locked (_metrics, pos);
|
||||||
const MeterSection meter = meter_section_at_locked (_metrics, pos);
|
const MeterSection meter = meter_section_at_locked (_metrics, pos);
|
||||||
const BBT_Time bbt = bbt_at_beat_locked (_metrics, cnt);
|
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;
|
++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);
|
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<TempoSection*> (*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&
|
const MeterSection&
|
||||||
TempoMap::meter_section_at_locked (const Metrics& metrics, framepos_t frame) const
|
TempoMap::meter_section_at_locked (const Metrics& metrics, framepos_t frame) const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -307,7 +307,7 @@ MidiClockTicker::tick (const framepos_t& /* transport_frame */, pframes_t nframe
|
||||||
double
|
double
|
||||||
MidiClockTicker::one_ppqn_in_frames (framepos_t transport_position)
|
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 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();
|
double quarter_notes_per_beat = 4.0 / current_tempo.note_type();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue