summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2012-01-06 16:39:40 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2012-01-06 16:39:40 +0000
commit355183f1abea75d8fab0926cd7e7130796574cb0 (patch)
tree78cc092b820fda137e752529f2d45c794c375313
parentbdb15f942250ad3e8a42c6bef927374eedb0299f (diff)
partially revert some of the recent work on tempo to reflect new understanding of the problem. behaviour is now believed to be totally correct but awaiting a bit more testing
git-svn-id: svn://localhost/ardour2/branches/3.0@11171 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/audio_clock.cc2
-rw-r--r--gtk2_ardour/editor_drag.cc2
-rw-r--r--gtk2_ardour/editor_rulers.cc14
-rw-r--r--gtk2_ardour/editor_tempodisplay.cc2
-rw-r--r--gtk2_ardour/midi_list_editor.cc2
-rw-r--r--gtk2_ardour/midi_region_view.cc4
-rw-r--r--gtk2_ardour/step_editor.cc6
-rw-r--r--gtk2_ardour/verbose_cursor.cc2
-rw-r--r--libs/ardour/ardour/tempo.h38
-rw-r--r--libs/ardour/audio_unit.cc8
-rw-r--r--libs/ardour/beats_frames_converter.cc6
-rw-r--r--libs/ardour/session_click.cc2
-rw-r--r--libs/ardour/session_time.cc2
-rw-r--r--libs/ardour/tempo.cc496
-rw-r--r--libs/surfaces/mackie/mackie_control_protocol.cc4
-rw-r--r--libs/timecode/src/bbt_time.cc13
-rw-r--r--libs/timecode/timecode/bbt_time.h2
17 files changed, 417 insertions, 188 deletions
diff --git a/gtk2_ardour/audio_clock.cc b/gtk2_ardour/audio_clock.cc
index 37ed13595a..a4cb473a72 100644
--- a/gtk2_ardour/audio_clock.cc
+++ b/gtk2_ardour/audio_clock.cc
@@ -1779,7 +1779,7 @@ AudioClock::bbt_validate_edit (const string& str)
return false;
}
- if (any.bbt.ticks > Timecode::BBT_Time::ticks_per_bar_division) {
+ if (any.bbt.ticks > Timecode::BBT_Time::ticks_per_beat) {
return false;
}
diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc
index cda4a26440..830efbfeef 100644
--- a/gtk2_ardour/editor_drag.cc
+++ b/gtk2_ardour/editor_drag.cc
@@ -4448,7 +4448,7 @@ NoteCreateDrag::finished (GdkEvent* event, bool had_movement)
framecnt_t length = abs (_note[0] - _note[1]);
framecnt_t const g = grid_frames (start);
- double const one_tick = 1 / Timecode::BBT_Time::ticks_per_bar_division;
+ double const one_tick = 1 / Timecode::BBT_Time::ticks_per_beat;
if (_editor->snap_mode() == SnapNormal && length < g) {
length = g - one_tick;
diff --git a/gtk2_ardour/editor_rulers.cc b/gtk2_ardour/editor_rulers.cc
index c9fb7fc65d..f11e584c18 100644
--- a/gtk2_ardour/editor_rulers.cc
+++ b/gtk2_ardour/editor_rulers.cc
@@ -1261,7 +1261,7 @@ Editor::compute_bbt_ruler_scale (framepos_t lower, framepos_t upper)
bbt_ruler_scale = bbt_show_ticks_detail;
}
- if ((bbt_ruler_scale == bbt_show_ticks_detail) && (lower_beat.beats == upper_beat.beats) && (upper_beat.ticks - lower_beat.ticks <= Timecode::BBT_Time::ticks_per_bar_division / 4)) {
+ if ((bbt_ruler_scale == bbt_show_ticks_detail) && (lower_beat.beats == upper_beat.beats) && (upper_beat.ticks - lower_beat.ticks <= Timecode::BBT_Time::ticks_per_beat / 4)) {
bbt_ruler_scale = bbt_show_ticks_super_detail;
}
}
@@ -1386,14 +1386,14 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble /*upp
frame_skip = (framepos_t) floor (frame_skip_error = (_session->frame_rate() * 60) / (bbt_beat_subdivision * (*i).tempo->beats_per_minute()));
frame_skip_error -= frame_skip;
- skip = (uint32_t) (Timecode::BBT_Time::ticks_per_bar_division / bbt_beat_subdivision);
+ skip = (uint32_t) (Timecode::BBT_Time::ticks_per_beat / bbt_beat_subdivision);
pos = (*i).frame + frame_skip;
accumulated_error = frame_skip_error;
tick = skip;
- for (t = 0; (tick < Timecode::BBT_Time::ticks_per_bar_division) && (n < bbt_nmarks) && (pos < next_beat_pos) ; pos += frame_skip, tick += skip, ++t) {
+ for (t = 0; (tick < Timecode::BBT_Time::ticks_per_beat) && (n < bbt_nmarks) && (pos < next_beat_pos) ; pos += frame_skip, tick += skip, ++t) {
if (t % bbt_accent_modulo == (bbt_accent_modulo - 1)) {
i_am_accented = true;
@@ -1476,14 +1476,14 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble /*upp
frame_skip = (framepos_t) floor (frame_skip_error = (_session->frame_rate() * 60) / (bbt_beat_subdivision * (*i).tempo->beats_per_minute()));
frame_skip_error -= frame_skip;
- skip = (uint32_t) (Timecode::BBT_Time::ticks_per_bar_division / bbt_beat_subdivision);
+ skip = (uint32_t) (Timecode::BBT_Time::ticks_per_beat / bbt_beat_subdivision);
pos = (*i).frame + frame_skip;
accumulated_error = frame_skip_error;
tick = skip;
- for (t = 0; (tick < Timecode::BBT_Time::ticks_per_bar_division) && (n < bbt_nmarks) && (pos < next_beat_pos) ; pos += frame_skip, tick += skip, ++t) {
+ for (t = 0; (tick < Timecode::BBT_Time::ticks_per_beat) && (n < bbt_nmarks) && (pos < next_beat_pos) ; pos += frame_skip, tick += skip, ++t) {
if (t % bbt_accent_modulo == (bbt_accent_modulo - 1)) {
i_am_accented = true;
@@ -1571,14 +1571,14 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble /*upp
frame_skip = (framepos_t) floor (frame_skip_error = (_session->frame_rate() * 60) / (bbt_beat_subdivision * (*i).tempo->beats_per_minute()));
frame_skip_error -= frame_skip;
- skip = (uint32_t) (Timecode::BBT_Time::ticks_per_bar_division / bbt_beat_subdivision);
+ skip = (uint32_t) (Timecode::BBT_Time::ticks_per_beat / bbt_beat_subdivision);
pos = (*i).frame + frame_skip;
accumulated_error = frame_skip_error;
tick = skip;
- for (t = 0; (tick < Timecode::BBT_Time::ticks_per_bar_division) && (n < bbt_nmarks) && (pos < next_beat_pos) ; pos += frame_skip, tick += skip, ++t) {
+ for (t = 0; (tick < Timecode::BBT_Time::ticks_per_beat) && (n < bbt_nmarks) && (pos < next_beat_pos) ; pos += frame_skip, tick += skip, ++t) {
if (t % bbt_accent_modulo == (bbt_accent_modulo - 1)) {
i_am_accented = true;
diff --git a/gtk2_ardour/editor_tempodisplay.cc b/gtk2_ardour/editor_tempodisplay.cc
index 25fb5acbe7..14782e4bc5 100644
--- a/gtk2_ardour/editor_tempodisplay.cc
+++ b/gtk2_ardour/editor_tempodisplay.cc
@@ -169,7 +169,7 @@ Editor::compute_current_bbt_points (framepos_t leftmost, framepos_t rightmost)
}
next_beat.ticks = 0;
- _session->tempo_map().map (current_bbt_points_begin, current_bbt_points_end, _session->tempo_map().frame_time (previous_beat), _session->tempo_map().frame_time (next_beat) + 1);
+ _session->tempo_map().get_grid (current_bbt_points_begin, current_bbt_points_end, _session->tempo_map().frame_time (previous_beat), _session->tempo_map().frame_time (next_beat) + 1);
}
void
diff --git a/gtk2_ardour/midi_list_editor.cc b/gtk2_ardour/midi_list_editor.cc
index 5b42070e65..879b1a9f2f 100644
--- a/gtk2_ardour/midi_list_editor.cc
+++ b/gtk2_ardour/midi_list_editor.cc
@@ -221,7 +221,7 @@ MidiListEditor::redisplay_model ()
bbt.bars = 0;
dur = (*i)->end_time() - (*i)->time();
bbt.beats = floor (dur);
- bbt.ticks = (uint32_t) lrint (fmod (dur, 1.0) * Timecode::BBT_Time::ticks_per_bar_division);
+ bbt.ticks = (uint32_t) lrint (fmod (dur, 1.0) * Timecode::BBT_Time::ticks_per_beat);
_session->tempo_map().bbt_duration_at (region->position(), bbt, 0);
diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc
index ac3ac92ee4..bab797c8c7 100644
--- a/gtk2_ardour/midi_region_view.cc
+++ b/gtk2_ardour/midi_region_view.cc
@@ -485,7 +485,7 @@ MidiRegionView::button_release (GdkEventButton* ev)
/* Shorten the length by 1 tick so that we can add a new note at the next
grid snap without it overlapping this one.
*/
- beats -= 1.0 / Timecode::BBT_Time::ticks_per_bar_division;
+ beats -= 1.0 / Timecode::BBT_Time::ticks_per_beat;
create_note_at (editor.pixel_to_frame (event_x), event_y, beats, true);
}
@@ -504,7 +504,7 @@ MidiRegionView::button_release (GdkEventButton* ev)
/* Shorten the length by 1 tick so that we can add a new note at the next
grid snap without it overlapping this one.
*/
- beats -= 1.0 / Timecode::BBT_Time::ticks_per_bar_division;
+ beats -= 1.0 / Timecode::BBT_Time::ticks_per_beat;
create_note_at (editor.pixel_to_frame (event_x), event_y, beats, true);
diff --git a/gtk2_ardour/step_editor.cc b/gtk2_ardour/step_editor.cc
index aa0095b1d5..45e286dc70 100644
--- a/gtk2_ardour/step_editor.cc
+++ b/gtk2_ardour/step_editor.cc
@@ -272,8 +272,8 @@ StepEditor::step_add_note (uint8_t channel, uint8_t pitch, uint8_t velocity, Evo
up by 1 tick from where the last note ended
*/
- at += 1.0/Timecode::BBT_Time::ticks_per_bar_division;
- len -= 1.0/Timecode::BBT_Time::ticks_per_bar_division;
+ at += 1.0/Timecode::BBT_Time::ticks_per_beat;
+ len -= 1.0/Timecode::BBT_Time::ticks_per_beat;
}
step_edit_region_view->step_add_note (channel, pitch, velocity, at, len);
@@ -293,7 +293,7 @@ StepEditor::step_add_note (uint8_t channel, uint8_t pitch, uint8_t velocity, Evo
step_edit_beat_pos += beat_duration;
step_edit_region_view->move_step_edit_cursor (step_edit_beat_pos);
} else {
- step_edit_beat_pos += 1.0/Timecode::BBT_Time::ticks_per_bar_division; // tiny, but no longer overlapping
+ step_edit_beat_pos += 1.0/Timecode::BBT_Time::ticks_per_beat; // tiny, but no longer overlapping
_step_edit_chord_duration = max (_step_edit_chord_duration, beat_duration);
}
diff --git a/gtk2_ardour/verbose_cursor.cc b/gtk2_ardour/verbose_cursor.cc
index 89f8c19c56..f80b74c4f8 100644
--- a/gtk2_ardour/verbose_cursor.cc
+++ b/gtk2_ardour/verbose_cursor.cc
@@ -209,7 +209,7 @@ VerboseCursor::set_duration (framepos_t start, framepos_t end, double x, double
ticks -= sbbt.ticks;
if (ticks < 0) {
- ticks += int (Timecode::BBT_Time::ticks_per_bar_division);
+ ticks += int (Timecode::BBT_Time::ticks_per_beat);
--beats;
}
diff --git a/libs/ardour/ardour/tempo.h b/libs/ardour/ardour/tempo.h
index 7d9a9feb7d..e6f072eb0d 100644
--- a/libs/ardour/ardour/tempo.h
+++ b/libs/ardour/ardour/tempo.h
@@ -68,7 +68,7 @@ class Meter {
double note_divisor() const { return _note_type; }
double frames_per_bar (const Tempo&, framecnt_t sr) const;
- double frames_per_division (const Tempo&, framecnt_t sr) const;
+ double frames_per_grid (const Tempo&, framecnt_t sr) const;
protected:
/** The number of divisions in a bar. This is a floating point value because
@@ -226,20 +226,43 @@ class TempoMap : public PBD::StatefulDestructible
(obj.*method)(metrics);
}
- void map (BBTPointList::const_iterator&, BBTPointList::const_iterator&,
- framepos_t start, framepos_t end);
+ void get_grid (BBTPointList::const_iterator&, BBTPointList::const_iterator&,
+ framepos_t start, framepos_t end);
+ /* TEMPO- AND METER-SENSITIVE FUNCTIONS
+
+ bbt_time(), bbt_time_rt(), 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&);
/* realtime safe variant of ::bbt_time(), will throw
std::logic_error if the map is not large enough
to provide an answer.
*/
void bbt_time_rt (framepos_t when, Timecode::BBT_Time&);
-
-
framecnt_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::MusicalTime) const;
+ framepos_t framepos_minus_beats (framepos_t, Evoral::MusicalTime) const;
+ Evoral::MusicalTime 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; }
@@ -273,11 +296,6 @@ class TempoMap : public PBD::StatefulDestructible
TempoMetric metric_at (Timecode::BBT_Time bbt) const;
TempoMetric metric_at (framepos_t) const;
- framepos_t framepos_plus_bbt (framepos_t pos, Timecode::BBT_Time b);
- framepos_t framepos_plus_beats (framepos_t, Evoral::MusicalTime);
- framepos_t framepos_minus_bbt (framepos_t pos, Timecode::BBT_Time b);
- framepos_t framepos_minus_beats (framepos_t, Evoral::MusicalTime);
- Evoral::MusicalTime framewalk_to_beats (framepos_t pos, framecnt_t distance);
void change_existing_tempo_at (framepos_t, double bpm, double note_type);
void change_initial_tempo (double bpm, double note_type);
diff --git a/libs/ardour/audio_unit.cc b/libs/ardour/audio_unit.cc
index 3b1e91c329..5932b73949 100644
--- a/libs/ardour/audio_unit.cc
+++ b/libs/ardour/audio_unit.cc
@@ -1420,7 +1420,7 @@ AUPlugin::get_beat_and_tempo_callback (Float64* outCurrentBeat,
float beat;
beat = metric.meter().divisions_per_bar() * bbt.bars;
beat += bbt.beats;
- beat += bbt.ticks / Timecode::BBT_Time::ticks_per_bar_division;
+ beat += bbt.ticks / Timecode::BBT_Time::ticks_per_beat;
*outCurrentBeat = beat;
}
@@ -1461,7 +1461,7 @@ AUPlugin::get_musical_time_location_callback (UInt32* outDeltaSampleOffsetToNe
*outDeltaSampleOffsetToNextBeat = 0;
} else {
*outDeltaSampleOffsetToNextBeat = (UInt32)
- floor (((Timecode::BBT_Time::ticks_per_bar_division - bbt.ticks)/Timecode::BBT_Time::ticks_per_bar_division) * // fraction of a beat to next beat
+ floor (((Timecode::BBT_Time::ticks_per_beat - bbt.ticks)/Timecode::BBT_Time::ticks_per_beat) * // fraction of a beat to next beat
metric.meter().frames_per_division (metric.tempo(), _session.frame_rate())); // frames per beat
}
}
@@ -1553,7 +1553,7 @@ AUPlugin::get_transport_state_callback (Boolean* outIsPlaying,
float beat;
beat = metric.meter().divisions_per_bar() * bbt.bars;
beat += bbt.beats;
- beat += bbt.ticks / Timecode::BBT_Time::ticks_per_bar_division;
+ beat += bbt.ticks / Timecode::BBT_Time::ticks_per_beat;
*outCycleStartBeat = beat;
}
@@ -1565,7 +1565,7 @@ AUPlugin::get_transport_state_callback (Boolean* outIsPlaying,
float beat;
beat = metric.meter().divisions_per_bar() * bbt.bars;
beat += bbt.beats;
- beat += bbt.ticks / Timecode::BBT_Time::ticks_per_bar_division;
+ beat += bbt.ticks / Timecode::BBT_Time::ticks_per_beat;
*outCycleEndBeat = beat;
}
diff --git a/libs/ardour/beats_frames_converter.cc b/libs/ardour/beats_frames_converter.cc
index 215292f6c1..584732ff03 100644
--- a/libs/ardour/beats_frames_converter.cc
+++ b/libs/ardour/beats_frames_converter.cc
@@ -32,7 +32,8 @@ framecnt_t
BeatsFramesConverter::to (double beats) const
{
assert (beats >= 0);
- return _tempo_map.framepos_plus_beats (_origin_b, beats) - _origin_b;
+ framecnt_t r = _tempo_map.framepos_plus_beats (_origin_b, beats) - _origin_b;
+ return r;
}
/** Takes a duration in frames and considers it as a distance from the origin
@@ -42,7 +43,8 @@ BeatsFramesConverter::to (double beats) const
double
BeatsFramesConverter::from (framecnt_t frames) const
{
- return _tempo_map.framewalk_to_beats (_origin_b, frames);
+ double b = _tempo_map.framewalk_to_beats (_origin_b, frames);
+ return b;
}
} /* namespace ARDOUR */
diff --git a/libs/ardour/session_click.cc b/libs/ardour/session_click.cc
index 1fbf255448..d5a3bc5e42 100644
--- a/libs/ardour/session_click.cc
+++ b/libs/ardour/session_click.cc
@@ -60,7 +60,7 @@ Session::click (framepos_t start, framecnt_t nframes)
BufferSet& bufs = get_scratch_buffers(ChanCount(DataType::AUDIO, 1));
buf = bufs.get_audio(0).data();
- _tempo_map->map (points_begin, points_end, start, end);
+ _tempo_map->get_grid (points_begin, points_end, start, end);
if (distance (points_begin, points_end) == 0) {
goto run_clicks;
diff --git a/libs/ardour/session_time.cc b/libs/ardour/session_time.cc
index 04d8cf2fbb..205e2a0ba4 100644
--- a/libs/ardour/session_time.cc
+++ b/libs/ardour/session_time.cc
@@ -496,7 +496,7 @@ Session::jack_timebase_callback (jack_transport_state_t /*state*/,
pos->beats_per_bar = metric.meter().divisions_per_bar();
pos->beat_type = metric.meter().note_divisor();
- pos->ticks_per_beat = Timecode::BBT_Time::ticks_per_bar_division;
+ pos->ticks_per_beat = Timecode::BBT_Time::ticks_per_beat;
pos->beats_per_minute = metric.tempo().beats_per_minute();
pos->valid = jack_position_bits_t (pos->valid | JackPositionBBT);
diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc
index 8d1aba0210..096bcd8a67 100644
--- a/libs/ardour/tempo.cc
+++ b/libs/ardour/tempo.cc
@@ -54,15 +54,22 @@ Tempo::frames_per_beat (framecnt_t sr) const
/***********************************************************************/
double
-Meter::frames_per_division (const Tempo& tempo, framecnt_t sr) const
+Meter::frames_per_grid (const Tempo& tempo, framecnt_t sr) const
{
+ /* This is tempo- and meter-sensitive. The number it returns
+ is based on the interval between any two lines in the
+ grid that is constructed from tempo and meter sections.
+
+ The return value IS NOT interpretable in terms of "beats".
+ */
+
return (60.0 * sr) / (tempo.beats_per_minute() * (_note_type/tempo.note_type()));
}
double
Meter::frames_per_bar (const Tempo& tempo, framecnt_t sr) const
{
- return frames_per_division (tempo, sr) * _divisions_per_bar;
+ return frames_per_grid (tempo, sr) * _divisions_per_bar;
}
/***********************************************************************/
@@ -156,8 +163,8 @@ void
TempoSection::update_bar_offset_from_bbt (const Meter& m)
{
- _bar_offset = ((start().beats - 1) * BBT_Time::ticks_per_bar_division + start().ticks) /
- (m.divisions_per_bar() * BBT_Time::ticks_per_bar_division);
+ _bar_offset = ((start().beats - 1) * BBT_Time::ticks_per_beat + start().ticks) /
+ (m.divisions_per_bar() * BBT_Time::ticks_per_beat);
DEBUG_TRACE (DEBUG::TempoMath, string_compose ("Tempo set bar offset to %1 from %2 w/%3\n", _bar_offset, start(), m.divisions_per_bar()));
}
@@ -174,9 +181,9 @@ TempoSection::update_bbt_time_from_bar_offset (const Meter& meter)
new_start.bars = start().bars;
- double ticks = BBT_Time::ticks_per_bar_division * meter.divisions_per_bar() * _bar_offset;
- new_start.beats = (uint32_t) floor(ticks/BBT_Time::ticks_per_bar_division);
- new_start.ticks = (uint32_t) fmod (ticks, BBT_Time::ticks_per_bar_division);
+ double ticks = BBT_Time::ticks_per_beat * meter.divisions_per_bar() * _bar_offset;
+ new_start.beats = (uint32_t) floor(ticks/BBT_Time::ticks_per_beat);
+ new_start.ticks = (uint32_t) fmod (ticks, BBT_Time::ticks_per_beat);
/* remember the 1-based counting properties of beats */
new_start.beats += 1;
@@ -548,7 +555,6 @@ TempoMap::replace_meter (const MeterSection& ms, const Meter& meter, const BBT_T
/* cannot move the first meter section */
*((Meter*)&first) = meter;
recompute_map (true);
-
}
}
@@ -881,7 +887,7 @@ TempoMap::_extend_map (TempoSection* tempo, MeterSection* meter,
double beat_frames;
divisions_per_bar = meter->divisions_per_bar ();
- beat_frames = meter->frames_per_division (*tempo,_frame_rate);
+ beat_frames = meter->frames_per_grid (*tempo,_frame_rate);
while (current_frame < end) {
@@ -923,7 +929,7 @@ TempoMap::_extend_map (TempoSection* tempo, MeterSection* meter,
if (tempo->start().ticks != 0) {
- double next_beat_frames = meter->frames_per_division (*tempo,_frame_rate);
+ double next_beat_frames = tempo->frames_per_beat (_frame_rate);
DEBUG_TRACE (DEBUG::TempoMath, string_compose ("bumped into non-beat-aligned tempo metric at %1 = %2, adjust next beat using %3\n",
tempo->start(), current_frame, tempo->bar_offset()));
@@ -964,7 +970,7 @@ TempoMap::_extend_map (TempoSection* tempo, MeterSection* meter,
}
divisions_per_bar = meter->divisions_per_bar ();
- beat_frames = meter->frames_per_division (*tempo, _frame_rate);
+ beat_frames = meter->frames_per_grid (*tempo, _frame_rate);
DEBUG_TRACE (DEBUG::TempoMath, string_compose ("New metric with beat frames = %1 dpb %2 meter %3 tempo %4\n",
beat_frames, divisions_per_bar, *((Meter*)meter), *((Tempo*)tempo)));
@@ -1098,8 +1104,8 @@ TempoMap::bbt_time (framepos_t frame, BBT_Time& bbt, const BBTPointList::const_i
if ((*i).frame == frame) {
bbt.ticks = 0;
} else {
- bbt.ticks = llrint (((frame - (*i).frame) / (*i).meter->frames_per_division(*((*i).tempo), _frame_rate)) *
- BBT_Time::ticks_per_bar_division);
+ bbt.ticks = llrint (((frame - (*i).frame) / (*i).tempo->frames_per_beat(_frame_rate)) *
+ BBT_Time::ticks_per_beat);
}
}
@@ -1115,7 +1121,7 @@ TempoMap::frame_time (const BBT_Time& bbt)
if (bbt.ticks != 0) {
return ((*e).frame - (*s).frame) +
- llrint ((*e).meter->frames_per_division (*(*e).tempo, _frame_rate) * (bbt.ticks/BBT_Time::ticks_per_bar_division));
+ llrint ((*e).tempo->frames_per_beat (_frame_rate) * (bbt.ticks/BBT_Time::ticks_per_beat));
} else {
return ((*e).frame - (*s).frame);
}
@@ -1151,7 +1157,7 @@ TempoMap::bbt_duration_at_unlocked (const BBT_Time& when, const BBT_Time& bbt, i
/* compute how much rounding we did because of non-zero ticks */
if (when.ticks != 0) {
- tick_frames = (*wi).meter->frames_per_division (*(*wi).tempo, _frame_rate) * (when.ticks/BBT_Time::ticks_per_bar_division);
+ tick_frames = (*wi).tempo->frames_per_beat (_frame_rate) * (when.ticks/BBT_Time::ticks_per_beat);
}
uint32_t bars = 0;
@@ -1174,7 +1180,7 @@ TempoMap::bbt_duration_at_unlocked (const BBT_Time& when, const BBT_Time& bbt, i
/* add any additional frames related to ticks in the added value */
if (bbt.ticks != 0) {
- tick_frames += (*wi).meter->frames_per_division (*(*wi).tempo, _frame_rate) * (bbt.ticks/BBT_Time::ticks_per_bar_division);
+ tick_frames += (*wi).tempo->frames_per_beat (_frame_rate) * (bbt.ticks/BBT_Time::ticks_per_beat);
}
return ((*wi).frame - (*start).frame) + llrint (tick_frames);
@@ -1208,7 +1214,7 @@ TempoMap::round_to_beat_subdivision (framepos_t fr, int sub_num, int dir)
DEBUG_TRACE (DEBUG::SnapBBT, string_compose ("round %1 to nearest 1/%2 beat, before-or-at = %3 @ %4|%5 precise = %6\n",
fr, sub_num, (*i).frame, (*i).bar, (*i).beat, the_beat));
- ticks_one_subdivisions_worth = (uint32_t)BBT_Time::ticks_per_bar_division / sub_num;
+ ticks_one_subdivisions_worth = (uint32_t)BBT_Time::ticks_per_beat / sub_num;
if (dir > 0) {
@@ -1226,11 +1232,11 @@ TempoMap::round_to_beat_subdivision (framepos_t fr, int sub_num, int dir)
the_beat.ticks += ticks_one_subdivisions_worth - mod;
}
- if (the_beat.ticks > BBT_Time::ticks_per_bar_division) {
+ if (the_beat.ticks > BBT_Time::ticks_per_beat) {
assert (i != _map.end());
++i;
assert (i != _map.end());
- the_beat.ticks -= BBT_Time::ticks_per_bar_division;
+ the_beat.ticks -= BBT_Time::ticks_per_beat;
}
@@ -1257,7 +1263,7 @@ TempoMap::round_to_beat_subdivision (framepos_t fr, int sub_num, int dir)
return fr;
}
--i;
- the_beat.ticks = BBT_Time::ticks_per_bar_division - the_beat.ticks;
+ the_beat.ticks = BBT_Time::ticks_per_beat - the_beat.ticks;
} else {
the_beat.ticks -= difference;
}
@@ -1277,11 +1283,11 @@ TempoMap::round_to_beat_subdivision (framepos_t fr, int sub_num, int dir)
DEBUG_TRACE (DEBUG::SnapBBT, string_compose ("moved forward to %1\n", the_beat.ticks));
- if (the_beat.ticks > BBT_Time::ticks_per_bar_division) {
+ if (the_beat.ticks > BBT_Time::ticks_per_beat) {
assert (i != _map.end());
++i;
assert (i != _map.end());
- the_beat.ticks -= BBT_Time::ticks_per_bar_division;
+ the_beat.ticks -= BBT_Time::ticks_per_beat;
DEBUG_TRACE (DEBUG::SnapBBT, string_compose ("fold beat to %1\n", the_beat));
}
@@ -1296,7 +1302,7 @@ TempoMap::round_to_beat_subdivision (framepos_t fr, int sub_num, int dir)
}
/* step back to previous beat */
--i;
- the_beat.ticks = lrint (BBT_Time::ticks_per_bar_division - rem);
+ the_beat.ticks = lrint (BBT_Time::ticks_per_beat - rem);
DEBUG_TRACE (DEBUG::SnapBBT, string_compose ("step back beat to %1\n", the_beat));
} else {
the_beat.ticks = lrint (the_beat.ticks - rem);
@@ -1307,8 +1313,8 @@ TempoMap::round_to_beat_subdivision (framepos_t fr, int sub_num, int dir)
}
}
- return (*i).frame + (the_beat.ticks/BBT_Time::ticks_per_bar_division) *
- (*i).meter->frames_per_division (*((*i).tempo), _frame_rate);
+ return (*i).frame + (the_beat.ticks/BBT_Time::ticks_per_beat) *
+ (*i).tempo->frames_per_beat (_frame_rate);
}
framepos_t
@@ -1454,9 +1460,9 @@ TempoMap::round_to_type (framepos_t frame, int dir, BBTPointType type)
}
void
-TempoMap::map (TempoMap::BBTPointList::const_iterator& begin,
- TempoMap::BBTPointList::const_iterator& end,
- framepos_t lower, framepos_t upper)
+TempoMap::get_grid (TempoMap::BBTPointList::const_iterator& begin,
+ TempoMap::BBTPointList::const_iterator& end,
+ framepos_t lower, framepos_t upper)
{
{
Glib::RWLock::WriterLock lm (lock);
@@ -1697,7 +1703,7 @@ TempoMap::insert_time (framepos_t where, framecnt_t amount)
first = false;
} else {
- if (bbt.ticks > BBT_Time::ticks_per_bar_division/2) {
+ if (bbt.ticks > BBT_Time::ticks_per_beat/2) {
/* round up to next beat */
bbt.beats += 1;
}
@@ -1740,175 +1746,383 @@ TempoMap::insert_time (framepos_t where, framecnt_t amount)
* pos can be -ve, if required.
*/
framepos_t
-TempoMap::framepos_plus_beats (framepos_t pos, Evoral::MusicalTime beats)
+TempoMap::framepos_plus_beats (framepos_t pos, Evoral::MusicalTime beats) const
{
- return framepos_plus_bbt (pos, BBT_Time (beats));
-}
+ Glib::RWLock::ReaderLock lm (lock);
+ Metrics::const_iterator next_tempo;
+ const TempoSection* tempo;
-/** Subtract some (fractional) beats to a frame position, and return the result in frames */
-framepos_t
-TempoMap::framepos_minus_beats (framepos_t pos, Evoral::MusicalTime beats)
-{
- return framepos_minus_bbt (pos, BBT_Time (beats));
+ /* Find the starting tempo metric */
+
+ for (next_tempo = metrics.begin(); next_tempo != metrics.end(); ++next_tempo) {
+
+ const TempoSection* t;
+
+ if ((t = dynamic_cast<const TempoSection*>(*next_tempo)) != 0) {
+
+ /* This is a bit of a hack, but pos could be -ve, and if it is,
+ we consider the initial metric changes (at time 0) to actually
+ be in effect at pos.
+ */
+
+ framepos_t f = (*next_tempo)->frame ();
+
+ if (pos < 0 && f == 0) {
+ f = pos;
+ }
+
+ if (f > pos) {
+ break;
+ }
+
+ tempo = t;
+ }
+ }
+
+ /* We now have:
+
+ tempo -> the Tempo for "pos"
+ next_tempo -> first tempo after "pos", possibly metrics.end()
+ */
+
+ DEBUG_TRACE (DEBUG::TempoMath, string_compose ("frame %1 plus %2 beats, start with tempo = %3 @ %4\n",
+ pos, beats, *((Tempo*)tempo), tempo->frame()));
+
+ while (beats) {
+
+ /* Distance to the end of this section in frames */
+ framecnt_t distance_frames = (next_tempo == metrics.end() ? max_framepos : ((*next_tempo)->frame() - pos));
+
+ /* Distance to the end in beats */
+ Evoral::MusicalTime distance_beats = distance_frames / tempo->frames_per_beat (_frame_rate);
+
+ /* Amount to subtract this time */
+ double const delta = min (distance_beats, beats);
+
+ DEBUG_TRACE (DEBUG::TempoMath, string_compose ("\tdistance to %1 = %2 (%3 beats)\n",
+ (next_tempo == metrics.end() ? max_framepos : (*next_tempo)->frame()),
+ distance_frames, distance_beats));
+
+ /* Update */
+ beats -= delta;
+ pos += delta * tempo->frames_per_beat (_frame_rate);
+
+ DEBUG_TRACE (DEBUG::TempoMath, string_compose ("\tnow at %1, %2 beats left\n", pos, beats));
+
+ /* step forwards to next tempo section */
+
+ if (next_tempo != metrics.end()) {
+
+ tempo = dynamic_cast<const TempoSection*>(*next_tempo);
+
+ DEBUG_TRACE (DEBUG::TempoMath, string_compose ("\tnew tempo = %1 @ %2 fpb = %3\n",
+ *((Tempo*)tempo), tempo->frame(),
+ tempo->frames_per_beat (_frame_rate)));
+
+ while (next_tempo != metrics.end ()) {
+
+ ++next_tempo;
+
+ if (next_tempo != metrics.end() && dynamic_cast<const TempoSection*>(*next_tempo)) {
+ break;
+ }
+ }
+ }
+ }
+
+ return pos;
}
+/** Subtract some (fractional) beats to a frame position, and return the result in frames */
framepos_t
-TempoMap::framepos_minus_bbt (framepos_t pos, BBT_Time op)
+TempoMap::framepos_minus_beats (framepos_t pos, Evoral::MusicalTime beats) const
{
Glib::RWLock::ReaderLock lm (lock);
- BBTPointList::const_iterator i;
- framecnt_t extra_frames = 0;
- bool had_bars = (op.bars != 0);
+ Metrics::const_reverse_iterator prev_tempo;
+ const TempoSection* tempo = 0;
- /* start from the bar|beat right before (or at) pos */
+ /* Find the starting tempo metric */
- i = bbt_before_or_at (pos);
-
- /* we know that (*i).frame is less than or equal to pos */
- extra_frames = pos - (*i).frame;
-
- /* walk backwards */
+ for (prev_tempo = metrics.rbegin(); prev_tempo != metrics.rend(); ++prev_tempo) {
- while (i != _map.begin() && (op.bars || op.beats)) {
- --i;
+ const TempoSection* t;
- if (had_bars) {
- if ((*i).is_bar()) {
- if (op.bars) {
- op.bars--;
- }
+ if ((t = dynamic_cast<const TempoSection*>(*prev_tempo)) != 0) {
+
+ /* This is a bit of a hack, but pos could be -ve, and if it is,
+ we consider the initial metric changes (at time 0) to actually
+ be in effect at pos.
+ */
+
+ framepos_t f = (*prev_tempo)->frame ();
+
+ if (pos < 0 && f == 0) {
+ f = pos;
}
- }
- if ((had_bars && op.bars == 0) || !had_bars) {
- /* finished counting bars, or none to count,
- so decrement beat count
+ /* this is slightly more complex than the forward case
+ because we reach the tempo in effect at pos after
+ passing through pos (rather before, as in the
+ forward case). having done that, we then need to
+ keep going to get the previous tempo (or
+ metrics.rend())
*/
- if (op.beats) {
- op.beats--;
+
+ if (f <= pos) {
+ if (tempo == 0) {
+ /* first tempo with position at or
+ before pos
+ */
+ tempo = t;
+ } else if (f < pos) {
+ /* some other tempo section that
+ is even earlier than 'tempo'
+ */
+ break;
+ }
}
}
}
-
- /* handle ticks (assumed to be less than
- * BBT_Time::ticks_per_bar_division, as always.
- */
- if (op.ticks) {
- frameoffset_t tick_frames = llrint ((*i).meter->frames_per_division (*(*i).tempo, _frame_rate) * (op.ticks/BBT_Time::ticks_per_bar_division));
- framepos_t pre_tick_frames = (*i).frame + extra_frames;
- if (tick_frames < pre_tick_frames) {
- return pre_tick_frames - tick_frames;
- }
- return 0;
- } else {
- return (*i).frame + extra_frames;
+ /* We now have:
+
+ tempo -> the Tempo for "pos"
+ prev_tempo -> the first metric before "pos", possibly metrics.rend()
+ */
+
+ while (beats) {
+
+ /* Distance to the start of this section in frames */
+ framecnt_t distance_frames = ((prev_tempo == metrics.rend()) ? max_framepos : (pos - (*prev_tempo)->frame()));
+
+ /* Distance to the start in beats */
+ Evoral::MusicalTime distance_beats = distance_frames / tempo->frames_per_beat (_frame_rate);
+
+ /* Amount to subtract this time */
+ double const sub = min (distance_beats, beats);
+
+ /* Update */
+
+ beats -= sub;
+ pos -= sub * tempo->frames_per_beat (_frame_rate);
+
+ /* step backwards to prior TempoSection */
+
+ if (prev_tempo != metrics.rend()) {
+
+ tempo = dynamic_cast<const TempoSection*>(*prev_tempo);
+
+ while (prev_tempo != metrics.rend ()) {
+
+ ++prev_tempo;
+
+ if (prev_tempo != metrics.rend() && dynamic_cast<const TempoSection*>(*prev_tempo) != 0) {
+ break;
+ }
+ }
+ }
}
+
+ return pos;
}
/** Add the BBT interval op to pos and return the result */
framepos_t
-TempoMap::framepos_plus_bbt (framepos_t pos, BBT_Time op)
+TempoMap::framepos_plus_bbt (framepos_t pos, BBT_Time op) const
{
Glib::RWLock::ReaderLock lm (lock);
- BBT_Time op_copy (op);
- int additional_minutes = 1;
- BBTPointList::const_iterator i;
- framecnt_t backup_frames = 0;
- bool had_bars = (op.bars != 0);
-
- while (true) {
+ Metrics::const_iterator i;
+ const MeterSection* meter;
+ const MeterSection* m;
+ const TempoSection* tempo;
+ const TempoSection* t;
+ double frames_per_beat;
- i = bbt_before_or_at (pos);
+ meter = &first_meter ();
+ tempo = &first_tempo ();
- op = op_copy;
+ assert (meter);
+ assert (tempo);
- /* we know that (*i).frame is before or equal to pos */
- backup_frames = pos - (*i).frame;
+ /* find the starting metrics for tempo & meter */
- while (i != _map.end() && (op.bars || op.beats)) {
+ for (i = metrics.begin(); i != metrics.end(); ++i) {
- ++i;
+ if ((*i)->frame() > pos) {
+ break;
+ }
- if (had_bars) {
- if ((*i).is_bar()) {
- if (op.bars) {
- op.bars--;
- }
- }
- }
-
- if ((had_bars && op.bars == 0) || !had_bars) {
- /* finished counting bars, or none to count,
- so decrement beat count
- */
+ if ((t = dynamic_cast<const TempoSection*>(*i)) != 0) {
+ tempo = t;
+ } else if ((m = dynamic_cast<const MeterSection*>(*i)) != 0) {
+ meter = m;
+ }
+ }
+
+ /* We now have:
+
+ meter -> the Meter for "pos"
+ tempo -> the Tempo for "pos"
+ i -> for first new metric after "pos", possibly metrics.end()
+ */
+
+ /* now comes the complicated part. we have to add one beat a time,
+ checking for a new metric on every beat.
+ */
+
+ frames_per_beat = tempo->frames_per_beat (_frame_rate);
- if (op.beats) {
- op.beats--;
+ uint64_t bars = 0;
+
+ while (op.bars) {
+
+ bars++;
+ op.bars--;
+
+ /* check if we need to use a new metric section: has adding frames moved us
+ to or after the start of the next metric section? in which case, use it.
+ */
+
+ if (i != metrics.end()) {
+ if ((*i)->frame() <= pos) {
+
+ /* about to change tempo or meter, so add the
+ * number of frames for the bars we've just
+ * traversed before we change the
+ * frames_per_beat value.
+ */
+
+ pos += llrint (frames_per_beat * (bars * meter->divisions_per_bar()));
+ bars = 0;
+
+ if ((t = dynamic_cast<const TempoSection*>(*i)) != 0) {
+ tempo = t;
+ } else if ((m = dynamic_cast<const MeterSection*>(*i)) != 0) {
+ meter = m;
}
+ ++i;
+ frames_per_beat = tempo->frames_per_beat (_frame_rate);
+
}
}
-
- if (i != _map.end()) {
- break;
- }
- /* we hit the end of the map before finish the bbt walk.
- */
+ }
- recompute_map (false, pos + (_frame_rate * 60 * additional_minutes));
- additional_minutes *= 2;
+ pos += llrint (frames_per_beat * (bars * meter->divisions_per_bar()));
+
+ uint64_t beats = 0;
+
+ while (op.beats) {
+
+ /* given the current meter, have we gone past the end of the bar ? */
+
+ beats++;
+ op.beats--;
- /* go back and try again */
- warning << "reached end of map with op now at " << op << " end = "
- << _map.back().frame << ' ' << _map.back().bar << '|' << _map.back().beat << ", trying to walk "
- << op_copy << " ... retry"
- << endmsg;
+ /* check if we need to use a new metric section: has adding frames moved us
+ to or after the start of the next metric section? in which case, use it.
+ */
+
+ if (i != metrics.end()) {
+ if ((*i)->frame() <= pos) {
+
+ /* about to change tempo or meter, so add the
+ * number of frames for the beats we've just
+ * traversed before we change the
+ * frames_per_beat value.
+ */
+
+ pos += llrint (beats * frames_per_beat);
+ beats = 0;
+
+ if ((t = dynamic_cast<const TempoSection*>(*i)) != 0) {
+ tempo = t;
+ } else if ((m = dynamic_cast<const MeterSection*>(*i)) != 0) {
+ meter = m;
+ }
+ ++i;
+ frames_per_beat = tempo->frames_per_beat (_frame_rate);
+ }
+ }
}
-
+
+ pos += llrint (beats * frames_per_beat);
+
if (op.ticks) {
- return (*i).frame - backup_frames +
- llrint ((*i).meter->frames_per_division (*(*i).tempo, _frame_rate) * (op.ticks/BBT_Time::ticks_per_bar_division));
- } else {
- return (*i).frame - backup_frames;
+ if (op.ticks >= BBT_Time::ticks_per_beat) {
+ pos += llrint (frames_per_beat + /* extra beat */
+ (frames_per_beat * ((op.ticks % (uint32_t) BBT_Time::ticks_per_beat) /
+ (double) BBT_Time::ticks_per_beat)));
+ } else {
+ pos += llrint (frames_per_beat * (op.ticks / (double) BBT_Time::ticks_per_beat));
+ }
}
+
+ return pos;
}
/** Count the number of beats that are equivalent to distance when going forward,
starting at pos.
*/
Evoral::MusicalTime
-TempoMap::framewalk_to_beats (framepos_t pos, framecnt_t distance)
+TempoMap::framewalk_to_beats (framepos_t pos, framecnt_t distance) const
{
- framepos_t end = pos + distance;
+ Glib::RWLock::ReaderLock lm (lock);
+ Metrics::const_iterator next_tempo;
+ const TempoSection* tempo;
+
+ /* Find the relevant initial tempo metric */
- require_map_to (end);
+ for (next_tempo = metrics.begin(); next_tempo != metrics.end(); ++next_tempo) {
- Glib::RWLock::ReaderLock lm (lock);
- BBTPointList::const_iterator i = bbt_after_or_at (pos);
- Evoral::MusicalTime beats = 0;
+ const TempoSection* t;
- /* if our starting BBTPoint is after pos, add a fractional beat
- to represent that distance.
- */
+ if ((t = dynamic_cast<const TempoSection*>(*next_tempo)) != 0) {
- if ((*i).frame != pos) {
- beats += ((*i).frame - pos) / (*i).meter->frames_per_division (*(*i).tempo, _frame_rate);
- }
+ if ((*next_tempo)->frame() > pos) {
+ break;
+ }
- while (i != _map.end() && (*i).frame < end) {
- ++i;
- beats++;
+ tempo = t;
+ }
}
- assert (i != _map.end());
-
- /* if our ending BBTPoint is after the end, subtract a fractional beat
- to represent that distance.
+ /* We now have:
+
+ tempo -> the Tempo for "pos"
+ next_tempo -> the next tempo after "pos", possibly metrics.end()
*/
- if ((*i).frame > end) {
- beats -= ((*i).frame - end) / (*i).meter->frames_per_division (*(*i).tempo, _frame_rate);
+ Evoral::MusicalTime beats = 0;
+
+ while (distance) {
+
+ /* End of this section */
+ framepos_t const end = ((next_tempo == metrics.end()) ? max_framepos : (*next_tempo)->frame ());
+
+ /* Distance to the end in frames */
+ framecnt_t const distance_to_end = end - pos;
+
+ /* Amount to subtract this time */
+ double const sub = min (distance, distance_to_end);
+
+ /* Update */
+ pos += sub;
+ distance -= sub;
+ beats += sub / tempo->frames_per_beat (_frame_rate);
+
+ /* Move on if there's anything to move to */
+ while (next_tempo != metrics.end ()) {
+ const TempoSection* t;
+
+ ++next_tempo;
+
+ if (next_tempo != metrics.end() && (t = dynamic_cast<const TempoSection*>(*next_tempo)) != 0) {
+ tempo = t;
+ break;
+ }
+
+ }
}
return beats;
diff --git a/libs/surfaces/mackie/mackie_control_protocol.cc b/libs/surfaces/mackie/mackie_control_protocol.cc
index 6fda7d7404..7e208686ba 100644
--- a/libs/surfaces/mackie/mackie_control_protocol.cc
+++ b/libs/surfaces/mackie/mackie_control_protocol.cc
@@ -1025,8 +1025,8 @@ MackieControlProtocol::format_bbt_timecode (framepos_t now_frame)
subdiv = 3;
}
- uint32_t subdivisions = bbt_time.ticks / uint32_t (Timecode::BBT_Time::ticks_per_bar_division / subdiv);
- uint32_t ticks = bbt_time.ticks % uint32_t (Timecode::BBT_Time::ticks_per_bar_division / subdiv);
+ uint32_t subdivisions = bbt_time.ticks / uint32_t (Timecode::BBT_Time::ticks_per_beat / subdiv);
+ uint32_t ticks = bbt_time.ticks % uint32_t (Timecode::BBT_Time::ticks_per_beat / subdiv);
os << setw(2) << setfill('0') << subdivisions + 1;
os << setw(3) << setfill('0') << ticks;
diff --git a/libs/timecode/src/bbt_time.cc b/libs/timecode/src/bbt_time.cc
index 6de822524d..cdff66fd69 100644
--- a/libs/timecode/src/bbt_time.cc
+++ b/libs/timecode/src/bbt_time.cc
@@ -23,20 +23,15 @@
using namespace Timecode;
-/* This number doesn't describe the smallest division of a "beat" (which is
- only defined contextually anyway), but rather the smallest division of the the
- divisions of a bar. If using a meter of 4/8, there are 4 divisions per bar, and
- we can divide each one into ticks_per_bar_division pieces; in a separate meter
- (section) of 3/8, there are 3 divisions per bar, each of which can be divided
- into ticks_per_bar_division pieces.
+/* This defines the smallest division of a "beat".
The number is intended to have as many integer factors as possible so that
1/Nth divisions are integer numbers of ticks.
- 1920 is the largest legal value that be used inside an SMF file, and has many factors.
+ 1920 has many factors, though going up to 3840 gets a couple more.
*/
-const double BBT_Time::ticks_per_bar_division = 1920.0;
+const double BBT_Time::ticks_per_beat = 1920.0;
BBT_Time::BBT_Time (double dbeats)
{
@@ -49,5 +44,5 @@ BBT_Time::BBT_Time (double dbeats)
bars = 0;
beats = rint (floor (dbeats));
- ticks = rint (floor (BBT_Time::ticks_per_bar_division * fmod (dbeats, 1.0)));
+ ticks = rint (floor (BBT_Time::ticks_per_beat * fmod (dbeats, 1.0)));
}
diff --git a/libs/timecode/timecode/bbt_time.h b/libs/timecode/timecode/bbt_time.h
index 030ac18afc..50a67f3d79 100644
--- a/libs/timecode/timecode/bbt_time.h
+++ b/libs/timecode/timecode/bbt_time.h
@@ -27,7 +27,7 @@ namespace Timecode {
/** Bar, Beat, Tick Time (i.e. Tempo-Based Time) */
struct BBT_Time {
- static const double ticks_per_bar_division;
+ static const double ticks_per_beat;
uint32_t bars;
uint32_t beats;