summaryrefslogtreecommitdiff
path: root/gtk2_ardour
diff options
context:
space:
mode:
authornick_m <mainsbridge@gmail.com>2015-12-20 04:41:45 +1100
committernick_m <mainsbridge@gmail.com>2016-05-27 23:38:09 +1000
commit7fc3b0c34c552d7be862897bd0aaa542453e9973 (patch)
tree35898328a86aefec5ac18a00c56c8577f4779d1f /gtk2_ardour
parent94187e66a2ae2bc2ab082ef614c25b35ec0d5e24 (diff)
Initial stab at tempo ramps.
Replaces the list of points in TempoMap with TempoSection functions, which compute tempo-at or tick-at time relative to tempo section start. TempoMap consults them additively to determine things like bbt_time(), frame_time() get_grid() etc. This has a marked effect on scrolling speed along with the code simplification in the places it has been attempted. Several things are broken here. Currently every ramp except the last one is an exponential ramp. this may be simple to fix :). Mouse-over midi grid doesn't match mouse click grid. should also be simple. Many things seem to work, but their accuracy should be in question until each area has been addressed.
Diffstat (limited to 'gtk2_ardour')
-rw-r--r--gtk2_ardour/editor.cc32
-rw-r--r--gtk2_ardour/editor.h14
-rw-r--r--gtk2_ardour/editor_drag.cc6
-rw-r--r--gtk2_ardour/editor_ops.cc2
-rw-r--r--gtk2_ardour/editor_rulers.cc249
-rw-r--r--gtk2_ardour/editor_tempodisplay.cc41
-rw-r--r--gtk2_ardour/tempo_dialog.cc30
-rw-r--r--gtk2_ardour/tempo_dialog.h6
-rw-r--r--gtk2_ardour/tempo_lines.cc40
-rw-r--r--gtk2_ardour/tempo_lines.h9
10 files changed, 188 insertions, 241 deletions
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index 5129a1ffaa..7353b6ff38 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -2185,14 +2185,10 @@ Editor::set_snap_to (SnapType st)
case SnapToBeatDiv4:
case SnapToBeatDiv3:
case SnapToBeatDiv2: {
- ARDOUR::TempoMap::BBTPointList::const_iterator current_bbt_points_begin;
- ARDOUR::TempoMap::BBTPointList::const_iterator current_bbt_points_end;
-
- compute_current_bbt_points (leftmost_frame, leftmost_frame + current_page_samples(),
- current_bbt_points_begin, current_bbt_points_end);
- compute_bbt_ruler_scale (leftmost_frame, leftmost_frame + current_page_samples(),
- current_bbt_points_begin, current_bbt_points_end);
- update_tempo_based_rulers (current_bbt_points_begin, current_bbt_points_end);
+ std::vector<TempoMap::BBTPoint> grid;
+ compute_current_bbt_points (grid, leftmost_frame, leftmost_frame + current_page_samples());
+ compute_bbt_ruler_scale (grid, leftmost_frame, leftmost_frame + current_page_samples());
+ update_tempo_based_rulers (grid);
break;
}
@@ -3952,11 +3948,9 @@ Editor::set_show_measures (bool yn)
tempo_lines->show();
}
- ARDOUR::TempoMap::BBTPointList::const_iterator begin;
- ARDOUR::TempoMap::BBTPointList::const_iterator end;
-
- compute_current_bbt_points (leftmost_frame, leftmost_frame + current_page_samples(), begin, end);
- draw_measures (begin, end);
+ std::vector<TempoMap::BBTPoint> grid;
+ compute_current_bbt_points (grid, leftmost_frame, leftmost_frame + current_page_samples());
+ draw_measures (grid);
}
instant_save ();
@@ -4582,14 +4576,10 @@ Editor::visual_changer (const VisualChange& vc)
compute_fixed_ruler_scale ();
- ARDOUR::TempoMap::BBTPointList::const_iterator current_bbt_points_begin;
- ARDOUR::TempoMap::BBTPointList::const_iterator current_bbt_points_end;
-
- compute_current_bbt_points (vc.time_origin, pending_visual_change.time_origin + current_page_samples(),
- current_bbt_points_begin, current_bbt_points_end);
- compute_bbt_ruler_scale (vc.time_origin, pending_visual_change.time_origin + current_page_samples(),
- current_bbt_points_begin, current_bbt_points_end);
- update_tempo_based_rulers (current_bbt_points_begin, current_bbt_points_end);
+ std::vector<TempoMap::BBTPoint> grid;
+ compute_current_bbt_points (grid, vc.time_origin, pending_visual_change.time_origin + current_page_samples());
+ compute_bbt_ruler_scale (grid, vc.time_origin, pending_visual_change.time_origin + current_page_samples());
+ update_tempo_based_rulers (grid);
update_video_timeline();
}
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index 665e9cc54c..139e044eae 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -885,8 +885,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void update_just_timecode ();
void compute_fixed_ruler_scale (); //calculates the RulerScale of the fixed rulers
void update_fixed_rulers ();
- void update_tempo_based_rulers (ARDOUR::TempoMap::BBTPointList::const_iterator& begin,
- ARDOUR::TempoMap::BBTPointList::const_iterator& end);
+ void update_tempo_based_rulers (std::vector<ARDOUR::TempoMap::BBTPoint>& grid);
void popup_ruler_menu (framepos_t where = 0, ItemType type = RegionItem);
void update_ruler_visibility ();
void set_ruler_visible (RulerType, bool);
@@ -949,9 +948,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
gint bbt_nmarks;
uint32_t bbt_bar_helper_on;
uint32_t bbt_accent_modulo;
- void compute_bbt_ruler_scale (framepos_t lower, framepos_t upper,
- ARDOUR::TempoMap::BBTPointList::const_iterator current_bbt_points_begin,
- ARDOUR::TempoMap::BBTPointList::const_iterator current_bbt_points_end);
+ void compute_bbt_ruler_scale (std::vector<ARDOUR::TempoMap::BBTPoint>& grid, framepos_t lower, framepos_t upper);
ArdourCanvas::Ruler* timecode_ruler;
ArdourCanvas::Ruler* bbt_ruler;
@@ -1636,8 +1633,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
ArdourCanvas::Container* time_line_group;
void hide_measures ();
- void draw_measures (ARDOUR::TempoMap::BBTPointList::const_iterator& begin,
- ARDOUR::TempoMap::BBTPointList::const_iterator& end);
+ void draw_measures (std::vector<ARDOUR::TempoMap::BBTPoint>&);
void new_tempo_section ();
@@ -1698,9 +1694,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void remove_metric_marks ();
void draw_metric_marks (const ARDOUR::Metrics& metrics);
- void compute_current_bbt_points (framepos_t left, framepos_t right,
- ARDOUR::TempoMap::BBTPointList::const_iterator& begin,
- ARDOUR::TempoMap::BBTPointList::const_iterator& end);
+ void compute_current_bbt_points (std::vector<ARDOUR::TempoMap::BBTPoint>& grid, framepos_t left, framepos_t right);
void tempo_map_changed (const PBD::PropertyChange&);
void redisplay_tempo (bool immediate_redraw);
diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc
index d04b52c306..f6f7f2b67c 100644
--- a/gtk2_ardour/editor_drag.cc
+++ b/gtk2_ardour/editor_drag.cc
@@ -3344,14 +3344,14 @@ TempoMarkerDrag::finished (GdkEvent* event, bool movement_occurred)
if (_copy == true) {
_editor->begin_reversible_command (_("copy tempo mark"));
XMLNode &before = map.get_state();
- map.add_tempo (_marker->tempo(), when);
+ map.add_tempo (_marker->tempo(), when, _marker->tempo().type());
XMLNode &after = map.get_state();
_editor->session()->add_command (new MementoCommand<TempoMap>(map, &before, &after));
_editor->commit_reversible_command ();
} else {
/* we removed it before, so add it back now */
- map.add_tempo (_marker->tempo(), when);
+ map.add_tempo (_marker->tempo(), when, _marker->tempo().type());
XMLNode &after = map.get_state();
_editor->session()->add_command (new MementoCommand<TempoMap>(map, before_state, &after));
_editor->commit_reversible_command ();
@@ -3369,7 +3369,7 @@ TempoMarkerDrag::aborted (bool moved)
if (moved) {
TempoMap& map (_editor->session()->tempo_map());
/* we removed it before, so add it back now */
- map.add_tempo (_marker->tempo(), _marker->tempo().start());
+ map.add_tempo (_marker->tempo(), _marker->tempo().start(), _marker->tempo().type());
// delete the dummy marker we used for visual representation while moving.
// a new visual marker will show up automatically.
delete _marker;
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index 66ef92baa7..8302f1b778 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -6552,7 +6552,7 @@ Editor::define_one_bar (framepos_t start, framepos_t end)
} else {
Timecode::BBT_Time bbt;
_session->tempo_map().bbt_time (start, bbt);
- _session->tempo_map().add_tempo (Tempo (beats_per_minute, t.note_type()), bbt);
+ _session->tempo_map().add_tempo (Tempo (beats_per_minute, t.note_type()), bbt, TempoSection::TempoSectionType::Ramp);
}
XMLNode& after (_session->tempo_map().get_state());
diff --git a/gtk2_ardour/editor_rulers.cc b/gtk2_ardour/editor_rulers.cc
index bb45e97bb3..ca450594e6 100644
--- a/gtk2_ardour/editor_rulers.cc
+++ b/gtk2_ardour/editor_rulers.cc
@@ -710,15 +710,13 @@ Editor::update_fixed_rulers ()
}
void
-Editor::update_tempo_based_rulers (ARDOUR::TempoMap::BBTPointList::const_iterator& begin,
- ARDOUR::TempoMap::BBTPointList::const_iterator& end)
+Editor::update_tempo_based_rulers (std::vector<TempoMap::BBTPoint>& grid)
{
if (_session == 0) {
return;
}
- compute_bbt_ruler_scale (leftmost_frame, leftmost_frame+current_page_samples(),
- begin, end);
+ compute_bbt_ruler_scale (grid, leftmost_frame, leftmost_frame+current_page_samples());
_bbt_metric->units_per_pixel = samples_per_pixel;
@@ -1011,19 +1009,19 @@ Editor::metric_get_timecode (std::vector<ArdourCanvas::Ruler::Mark>& marks, gdou
}
void
-Editor::compute_bbt_ruler_scale (framepos_t lower, framepos_t upper,
- ARDOUR::TempoMap::BBTPointList::const_iterator begin,
- ARDOUR::TempoMap::BBTPointList::const_iterator end)
+Editor::compute_bbt_ruler_scale (std::vector<ARDOUR::TempoMap::BBTPoint>& grid, framepos_t lower, framepos_t upper)
{
if (_session == 0) {
return;
}
- TempoMap::BBTPointList::const_iterator i;
+ std::vector<TempoMap::BBTPoint>::const_iterator i;
Timecode::BBT_Time lower_beat, upper_beat; // the beats at each end of the ruler
+ framecnt_t beat_before_lower_pos = _session->tempo_map().frame_at_beat (floor(_session->tempo_map().beat_at_frame (lower)));
+ framecnt_t beat_after_upper_pos = _session->tempo_map().frame_at_beat (floor (_session->tempo_map().beat_at_frame (upper)) + 1.0);
- _session->bbt_time (lower, lower_beat);
- _session->bbt_time (upper, upper_beat);
+ _session->bbt_time (beat_before_lower_pos, lower_beat);
+ _session->bbt_time (beat_after_upper_pos, upper_beat);
uint32_t beats = 0;
bbt_accent_modulo = 1;
@@ -1103,19 +1101,21 @@ Editor::compute_bbt_ruler_scale (framepos_t lower, framepos_t upper,
bbt_beat_subdivision = 4;
break;
}
-
- if (distance (begin, end) == 0) {
+ if (distance (grid.begin(), grid.end()) == 0) {
return;
}
- i = end;
+ i = grid.end();
i--;
- if ((*i).beat >= (*begin).beat) {
- bbt_bars = (*i).bar - (*begin).bar;
+
+ /* XX ?? */
+ if ((*i).beat >= (*grid.begin()).beat) {
+ bbt_bars = (*i).bar - (*grid.begin()).bar;
} else {
- bbt_bars = (*i).bar - (*begin).bar - 1;
+ bbt_bars = (*i).bar - (*grid.begin()).bar;
}
- beats = distance (begin, end) - bbt_bars;
+
+ beats = distance (grid.begin(), grid.end()) - bbt_bars;
/* Only show the bar helper if there aren't many bars on the screen */
if ((bbt_bars < 2) || (beats < 5)) {
@@ -1140,7 +1140,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_beat / 4)) {
+ if ((bbt_ruler_scale == bbt_show_ticks_detail) && beats < 3) {
bbt_ruler_scale = bbt_show_ticks_super_detail;
}
}
@@ -1161,38 +1161,34 @@ Editor::metric_get_bbt (std::vector<ArdourCanvas::Ruler::Mark>& marks, gdouble l
return;
}
- TempoMap::BBTPointList::const_iterator i;
+ std::vector<TempoMap::BBTPoint>::const_iterator i;
char buf[64];
gint n = 0;
framepos_t pos;
Timecode::BBT_Time next_beat;
- framepos_t next_beat_pos;
uint32_t beats = 0;
uint32_t tick = 0;
uint32_t skip;
uint32_t t;
- framepos_t frame_skip;
- double frame_skip_error;
double bbt_position_of_helper;
- double accumulated_error;
bool i_am_accented = false;
bool helper_active = false;
ArdourCanvas::Ruler::Mark mark;
- ARDOUR::TempoMap::BBTPointList::const_iterator begin;
- ARDOUR::TempoMap::BBTPointList::const_iterator end;
+ std::vector<TempoMap::BBTPoint> grid;
- compute_current_bbt_points (lower, upper, begin, end);
+ compute_current_bbt_points (grid, lower, upper);
- if (distance (begin, end) == 0) {
+ if (distance (grid.begin(), grid.end()) == 0) {
return;
}
switch (bbt_ruler_scale) {
case bbt_show_beats:
- beats = distance (begin, end);
+
+ beats = distance (grid.begin(), grid.end());
bbt_nmarks = beats + 2;
mark.label = "";
@@ -1200,7 +1196,7 @@ Editor::metric_get_bbt (std::vector<ArdourCanvas::Ruler::Mark>& marks, gdouble l
mark.style = ArdourCanvas::Ruler::Mark::Micro;
marks.push_back (mark);
- for (n = 1, i = begin; n < bbt_nmarks && i != end; ++i) {
+ for (n = 1, i = grid.begin(); n < bbt_nmarks && i != grid.end(); ++i) {
if ((*i).frame < lower && (bbt_bar_helper_on)) {
snprintf (buf, sizeof(buf), "<%" PRIu32 "|%" PRIu32, (*i).bar, (*i).beat);
@@ -1228,7 +1224,7 @@ Editor::metric_get_bbt (std::vector<ArdourCanvas::Ruler::Mark>& marks, gdouble l
case bbt_show_ticks:
- beats = distance (begin, end);
+ beats = distance (grid.begin(), grid.end());
bbt_nmarks = (beats + 2) * bbt_beat_subdivision;
bbt_position_of_helper = lower + (30 * Editor::get_current_zoom ());
@@ -1240,7 +1236,7 @@ Editor::metric_get_bbt (std::vector<ArdourCanvas::Ruler::Mark>& marks, gdouble l
mark.style = ArdourCanvas::Ruler::Mark::Micro;
marks.push_back (mark);
- for (n = 1, i = begin; n < bbt_nmarks && i != end; ++i) {
+ for (n = 1, i = grid.begin(); n < bbt_nmarks && i != grid.end(); ++i) {
if ((*i).frame < lower && (bbt_bar_helper_on)) {
snprintf (buf, sizeof(buf), "<%" PRIu32 "|%" PRIu32, (*i).bar, (*i).beat);
@@ -1265,45 +1261,20 @@ Editor::metric_get_bbt (std::vector<ArdourCanvas::Ruler::Mark>& marks, gdouble l
}
/* Add the tick marks */
+ skip = Timecode::BBT_Time::ticks_per_beat / bbt_beat_subdivision;
+ tick = skip; // the first non-beat tick
+ t = 0;
+ while (tick < Timecode::BBT_Time::ticks_per_beat && (n < bbt_nmarks)) {
- /* Find the next beat */
- next_beat.beats = (*i).beat;
- next_beat.bars = (*i).bar;
- next_beat.ticks = 0;
-
- if ((*i).meter->divisions_per_bar() > (next_beat.beats + 1)) {
- next_beat.beats += 1;
- } else {
- next_beat.bars += 1;
- next_beat.beats = 1;
- }
-
- next_beat_pos = _session->tempo_map().frame_time(next_beat);
+ next_beat.beats = (*i).beat;
+ next_beat.bars = (*i).bar;
+ next_beat.ticks = tick;
+ pos = _session->tempo_map().frame_time (next_beat);
- 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_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_beat) && (n < bbt_nmarks) && (pos < next_beat_pos) ; pos += frame_skip, tick += skip, ++t) {
-
- if (t % bbt_accent_modulo == (bbt_accent_modulo - 1)) {
+ if (t % bbt_accent_modulo == (bbt_accent_modulo - 1)) {
i_am_accented = true;
}
-
mark.label = "";
-
- /* Error compensation for float to framepos_t*/
- accumulated_error += frame_skip_error;
- if (accumulated_error > 1) {
- pos += 1;
- accumulated_error -= 1.0f;
- }
-
mark.position = pos;
if ((bbt_beat_subdivision > 4) && i_am_accented) {
@@ -1313,7 +1284,10 @@ Editor::metric_get_bbt (std::vector<ArdourCanvas::Ruler::Mark>& marks, gdouble l
}
i_am_accented = false;
marks.push_back (mark);
- n++;
+
+ tick += skip;
+ ++t;
+ ++n;
}
}
@@ -1321,17 +1295,17 @@ Editor::metric_get_bbt (std::vector<ArdourCanvas::Ruler::Mark>& marks, gdouble l
case bbt_show_ticks_detail:
- beats = distance (begin, end);
+ beats = distance (grid.begin(), grid.end());
bbt_nmarks = (beats + 2) * bbt_beat_subdivision;
- bbt_position_of_helper = lower + (30 * Editor::get_current_zoom ());
+ bbt_position_of_helper = lower + (3 * Editor::get_current_zoom ());
mark.label = "";
mark.position = lower;
mark.style = ArdourCanvas::Ruler::Mark::Micro;
marks.push_back (mark);
- for (n = 1, i = begin; n < bbt_nmarks && i != end; ++i) {
+ for (n = 1, i = grid.begin(); n < bbt_nmarks && i != grid.end(); ++i) {
if ((*i).frame < lower && (bbt_bar_helper_on)) {
snprintf (buf, sizeof(buf), "<%" PRIu32 "|%" PRIu32, (*i).bar, (*i).beat);
@@ -1356,36 +1330,20 @@ Editor::metric_get_bbt (std::vector<ArdourCanvas::Ruler::Mark>& marks, gdouble l
}
/* Add the tick marks */
+ skip = Timecode::BBT_Time::ticks_per_beat / bbt_beat_subdivision;
+ tick = skip; // the first non-beat tick
- /* Find the next beat */
-
- next_beat.beats = (*i).beat;
- next_beat.bars = (*i).bar;
-
- if ((*i).meter->divisions_per_bar() > (next_beat.beats + 1)) {
- next_beat.beats += 1;
- } else {
- next_beat.bars += 1;
- next_beat.beats = 1;
- }
-
- next_beat_pos = _session->tempo_map().frame_time(next_beat);
-
- 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_beat / bbt_beat_subdivision);
+ t = 0;
+ while (tick < Timecode::BBT_Time::ticks_per_beat && (n < bbt_nmarks)) {
- pos = (*i).frame + frame_skip;
- accumulated_error = frame_skip_error;
+ next_beat.beats = (*i).beat;
+ next_beat.bars = (*i).bar;
+ next_beat.ticks = tick;
+ pos = _session->tempo_map().frame_time (next_beat);
- tick = skip;
-
- 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;
+ if (t % bbt_accent_modulo == (bbt_accent_modulo - 1)) {
+ i_am_accented = true;
}
-
if (i_am_accented && (pos > bbt_position_of_helper)){
snprintf (buf, sizeof(buf), "%" PRIu32, tick);
} else {
@@ -1393,14 +1351,6 @@ Editor::metric_get_bbt (std::vector<ArdourCanvas::Ruler::Mark>& marks, gdouble l
}
mark.label = buf;
-
- /* Error compensation for float to framepos_t*/
- accumulated_error += frame_skip_error;
- if (accumulated_error > 1) {
- pos += 1;
- accumulated_error -= 1.0f;
- }
-
mark.position = pos;
if ((bbt_beat_subdivision > 4) && i_am_accented) {
@@ -1409,7 +1359,11 @@ Editor::metric_get_bbt (std::vector<ArdourCanvas::Ruler::Mark>& marks, gdouble l
mark.style = ArdourCanvas::Ruler::Mark::Micro;
}
i_am_accented = false;
- n++;
+ marks.push_back (mark);
+
+ tick += skip;
+ ++t;
+ ++n;
}
}
@@ -1417,17 +1371,17 @@ Editor::metric_get_bbt (std::vector<ArdourCanvas::Ruler::Mark>& marks, gdouble l
case bbt_show_ticks_super_detail:
- beats = distance (begin, end);
+ beats = distance (grid.begin(), grid.end());
bbt_nmarks = (beats + 2) * bbt_beat_subdivision;
- bbt_position_of_helper = lower + (30 * Editor::get_current_zoom ());
+ bbt_position_of_helper = lower + (3 * Editor::get_current_zoom ());
mark.label = "";
mark.position = lower;
mark.style = ArdourCanvas::Ruler::Mark::Micro;
marks.push_back (mark);
- for (n = 1, i = begin; n < bbt_nmarks && i != end; ++i) {
+ for (n = 1, i = grid.begin(); n < bbt_nmarks && i != grid.end(); ++i) {
if ((*i).frame < lower && (bbt_bar_helper_on)) {
snprintf (buf, sizeof(buf), "<%" PRIu32 "|%" PRIu32, (*i).bar, (*i).beat);
@@ -1452,61 +1406,40 @@ Editor::metric_get_bbt (std::vector<ArdourCanvas::Ruler::Mark>& marks, gdouble l
}
/* Add the tick marks */
-
- /* Find the next beat */
+ skip = Timecode::BBT_Time::ticks_per_beat / bbt_beat_subdivision;
next_beat.beats = (*i).beat;
next_beat.bars = (*i).bar;
+ tick = skip; // the first non-beat tick
+ t = 0;
+ while (tick < Timecode::BBT_Time::ticks_per_beat && (n < bbt_nmarks)) {
- if ((*i).meter->divisions_per_bar() > (next_beat.beats + 1)) {
- next_beat.beats += 1;
- } else {
- next_beat.bars += 1;
- next_beat.beats = 1;
- }
-
- next_beat_pos = _session->tempo_map().frame_time(next_beat);
-
- 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_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_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;
- }
-
- if (pos > bbt_position_of_helper) {
- snprintf (buf, sizeof(buf), "%" PRIu32, tick);
- } else {
- buf[0] = '\0';
- }
+ next_beat.ticks = tick;
+ pos = _session->tempo_map().frame_time (next_beat);
+ if (t % bbt_accent_modulo == (bbt_accent_modulo - 1)) {
+ i_am_accented = true;
+ }
- mark.label = buf;
+ if (pos > bbt_position_of_helper) {
+ snprintf (buf, sizeof(buf), "%" PRIu32, tick);
+ } else {
+ buf[0] = '\0';
+ }
- /* Error compensation for float to framepos_t*/
- accumulated_error += frame_skip_error;
- if (accumulated_error > 1) {
- pos += 1;
- accumulated_error -= 1.0f;
- }
+ mark.label = buf;
+ mark.position = pos;
- mark.position = pos;
+ if ((bbt_beat_subdivision > 4) && i_am_accented) {
+ mark.style = ArdourCanvas::Ruler::Mark::Minor;
+ } else {
+ mark.style = ArdourCanvas::Ruler::Mark::Micro;
+ }
+ i_am_accented = false;
+ marks.push_back (mark);
- if ((bbt_beat_subdivision > 4) && i_am_accented) {
- mark.style = ArdourCanvas::Ruler::Mark::Minor;
- } else {
- mark.style = ArdourCanvas::Ruler::Mark::Micro;
- }
- i_am_accented = false;
- marks.push_back (mark);
- n++;
+ tick += skip;
+ ++t;
+ ++n;
}
}
@@ -1523,7 +1456,7 @@ Editor::metric_get_bbt (std::vector<ArdourCanvas::Ruler::Mark>& marks, gdouble l
case bbt_show_64:
bbt_nmarks = (gint) (bbt_bars / 64) + 1;
- for (n = 0, i = begin; i != end && n < bbt_nmarks; i++) {
+ for (n = 0, i = grid.begin(); i != grid.end() && n < bbt_nmarks; i++) {
if ((*i).is_bar()) {
if ((*i).bar % 64 == 1) {
if ((*i).bar % 256 == 1) {
@@ -1548,7 +1481,7 @@ Editor::metric_get_bbt (std::vector<ArdourCanvas::Ruler::Mark>& marks, gdouble l
case bbt_show_16:
bbt_nmarks = (bbt_bars / 16) + 1;
- for (n = 0, i = begin; i != end && n < bbt_nmarks; i++) {
+ for (n = 0, i = grid.begin(); i != grid.end() && n < bbt_nmarks; i++) {
if ((*i).is_bar()) {
if ((*i).bar % 16 == 1) {
if ((*i).bar % 64 == 1) {
@@ -1573,7 +1506,7 @@ Editor::metric_get_bbt (std::vector<ArdourCanvas::Ruler::Mark>& marks, gdouble l
case bbt_show_4:
bbt_nmarks = (bbt_bars / 4) + 1;
- for (n = 0, i = begin; i != end && n < bbt_nmarks; ++i) {
+ for (n = 0, i = grid.begin(); i != grid.end() && n < bbt_nmarks; ++i) {
if ((*i).is_bar()) {
if ((*i).bar % 4 == 1) {
if ((*i).bar % 16 == 1) {
@@ -1599,7 +1532,7 @@ Editor::metric_get_bbt (std::vector<ArdourCanvas::Ruler::Mark>& marks, gdouble l
case bbt_show_1:
// default:
bbt_nmarks = bbt_bars + 2;
- for (n = 0, i = begin; i != end && n < bbt_nmarks; ++i) {
+ for (n = 0, i = grid.begin(); i != grid.end() && n < bbt_nmarks; ++i) {
if ((*i).is_bar()) {
if ((*i).bar % 4 == 1) {
snprintf (buf, sizeof(buf), "%" PRIu32, (*i).bar);
diff --git a/gtk2_ardour/editor_tempodisplay.cc b/gtk2_ardour/editor_tempodisplay.cc
index 38685e5dd6..2d5a3e47d5 100644
--- a/gtk2_ardour/editor_tempodisplay.cc
+++ b/gtk2_ardour/editor_tempodisplay.cc
@@ -114,13 +114,12 @@ Editor::tempo_map_changed (const PropertyChange& /*ignored*/)
tempo_lines->tempo_map_changed();
}
- ARDOUR::TempoMap::BBTPointList::const_iterator begin;
- ARDOUR::TempoMap::BBTPointList::const_iterator end;
+ std::vector<TempoMap::BBTPoint> grid;
- compute_current_bbt_points (leftmost_frame, leftmost_frame + current_page_samples(), begin, end);
+ compute_current_bbt_points (grid, leftmost_frame, leftmost_frame + current_page_samples());
_session->tempo_map().apply_with_metrics (*this, &Editor::draw_metric_marks); // redraw metric markers
- draw_measures (begin, end);
- update_tempo_based_rulers (begin, end);
+ draw_measures (grid);
+ update_tempo_based_rulers (grid);
}
void
@@ -131,32 +130,31 @@ Editor::redisplay_tempo (bool immediate_redraw)
}
if (immediate_redraw) {
- ARDOUR::TempoMap::BBTPointList::const_iterator current_bbt_points_begin;
- ARDOUR::TempoMap::BBTPointList::const_iterator current_bbt_points_end;
+ std::vector<TempoMap::BBTPoint> grid;
- compute_current_bbt_points (leftmost_frame, leftmost_frame + current_page_samples(),
- current_bbt_points_begin, current_bbt_points_end);
- draw_measures (current_bbt_points_begin, current_bbt_points_end);
- update_tempo_based_rulers (current_bbt_points_begin, current_bbt_points_end); // redraw rulers and measures
+ compute_current_bbt_points (grid, leftmost_frame, leftmost_frame + current_page_samples());
+ draw_measures (grid);
+ update_tempo_based_rulers (grid); // redraw rulers and measure lines
} else {
Glib::signal_idle().connect (sigc::bind_return (sigc::bind (sigc::mem_fun (*this, &Editor::redisplay_tempo), true), false));
}
}
+/* computes a grid starting a beat before and ending a beat after leftmost and rightmost respectively */
void
-Editor::compute_current_bbt_points (framepos_t leftmost, framepos_t rightmost,
- ARDOUR::TempoMap::BBTPointList::const_iterator& begin,
- ARDOUR::TempoMap::BBTPointList::const_iterator& end)
+Editor::compute_current_bbt_points (std::vector<TempoMap::BBTPoint>& grid, framepos_t leftmost, framepos_t rightmost)
{
if (!_session) {
return;
}
+ framecnt_t beat_before_lower_pos = _session->tempo_map().frame_at_beat (floor(_session->tempo_map().beat_at_frame (leftmost)));
+ framecnt_t beat_after_upper_pos = _session->tempo_map().frame_at_beat (floor (_session->tempo_map().beat_at_frame (rightmost)) + 1.0);
+
/* prevent negative values of leftmost from creeping into tempomap
*/
-
- _session->tempo_map().get_grid (begin, end, max (leftmost, (framepos_t) 0), rightmost);
+ _session->tempo_map().get_grid (grid, max (beat_before_lower_pos, (framepos_t) 0), beat_after_upper_pos);
}
void
@@ -168,10 +166,9 @@ Editor::hide_measures ()
}
void
-Editor::draw_measures (ARDOUR::TempoMap::BBTPointList::const_iterator& begin,
- ARDOUR::TempoMap::BBTPointList::const_iterator& end)
+Editor::draw_measures (std::vector<ARDOUR::TempoMap::BBTPoint>& grid)
{
- if (_session == 0 || _show_measures == false || distance (begin, end) == 0) {
+ if (_session == 0 || _show_measures == false || distance (grid.begin(), grid.end()) == 0) {
return;
}
@@ -180,7 +177,7 @@ Editor::draw_measures (ARDOUR::TempoMap::BBTPointList::const_iterator& begin,
}
const unsigned divisions = get_grid_beat_divisions(leftmost_frame);
- tempo_lines->draw (begin, end, divisions, leftmost_frame, _session->frame_rate());
+ tempo_lines->draw (grid, divisions, leftmost_frame, _session->frame_rate());
}
void
@@ -214,7 +211,7 @@ Editor::mouse_add_new_tempo_event (framepos_t frame)
begin_reversible_command (_("add tempo mark"));
XMLNode &before = map.get_state();
- map.add_tempo (Tempo (bpm,nt), requested);
+ map.add_tempo (Tempo (bpm,nt), requested, tempo_dialog.get_tempo_type());
XMLNode &after = map.get_state();
_session->add_command(new MementoCommand<TempoMap>(map, &before, &after));
commit_reversible_command ();
@@ -329,7 +326,7 @@ Editor::edit_tempo_section (TempoSection* section)
begin_reversible_command (_("replace tempo mark"));
XMLNode &before = _session->tempo_map().get_state();
- _session->tempo_map().replace_tempo (*section, Tempo (bpm, nt), when);
+ _session->tempo_map().replace_tempo (*section, Tempo (bpm, nt), when, tempo_dialog.get_tempo_type());
XMLNode &after = _session->tempo_map().get_state();
_session->add_command (new MementoCommand<TempoMap>(_session->tempo_map(), &before, &after));
commit_reversible_command ();
diff --git a/gtk2_ardour/tempo_dialog.cc b/gtk2_ardour/tempo_dialog.cc
index a7a6f4ae75..0d6a6cc75e 100644
--- a/gtk2_ardour/tempo_dialog.cc
+++ b/gtk2_ardour/tempo_dialog.cc
@@ -106,12 +106,21 @@ TempoDialog::init (const Timecode::BBT_Time& when, double bpm, double note_type,
pulse_selector.set_active_text (strings[3]); // "quarter"
}
+ strings.clear();
+
+ tempo_types.insert (make_pair (_("ramped"), TempoSection::TempoSectionType::Ramp));
+ strings.push_back (_("ramped"));
+ tempo_types.insert (make_pair (_("constant"), TempoSection::TempoSectionType::Constant));
+ strings.push_back (_("constant"));
+ set_popdown_strings (tempo_type, strings);
+ tempo_type.set_active_text (strings[0]); // "ramped"
+
Table* table;
if (UIConfiguration::instance().get_allow_non_quarter_pulse()) {
- table = manage (new Table (5, 5));
+ table = manage (new Table (5, 6));
} else {
- table = manage (new Table (5, 4));
+ table = manage (new Table (5, 5));
}
table->set_spacings (6);
@@ -156,8 +165,12 @@ TempoDialog::init (const Timecode::BBT_Time& when, double bpm, double note_type,
table->attach (*when_label, 0, 1, row, row+1);
}
+ Label* tempo_type_label = manage (new Label(_("Tempo Type:"), ALIGN_LEFT, ALIGN_CENTER));
+ table->attach (*tempo_type_label, 0, 1, row+1, row+2);
+ table->attach (tempo_type, 1, 2, row+1, row + 2);
get_vbox()->set_border_width (12);
get_vbox()->pack_end (*table);
+
table->show_all ();
add_button (Stock::CANCEL, RESPONSE_CANCEL);
@@ -258,6 +271,19 @@ TempoDialog::get_note_type ()
return x->second;
}
+TempoSection::TempoSectionType
+TempoDialog::get_tempo_type ()
+{
+ TempoTypes::iterator x = tempo_types.find (tempo_type.get_active_text());
+
+ if (x == tempo_types.end()) {
+ error << string_compose(_("incomprehensible pulse note type (%1)"), tempo_type.get_active_text()) << endmsg;
+ return TempoSection::TempoSectionType::Constant;
+ }
+
+ return x->second;
+}
+
void
TempoDialog::pulse_change ()
{
diff --git a/gtk2_ardour/tempo_dialog.h b/gtk2_ardour/tempo_dialog.h
index 06c5db196d..f04a5417f7 100644
--- a/gtk2_ardour/tempo_dialog.h
+++ b/gtk2_ardour/tempo_dialog.h
@@ -44,6 +44,7 @@ public:
double get_bpm ();
double get_note_type ();
bool get_bbt_time (Timecode::BBT_Time&);
+ ARDOUR::TempoSection::TempoSectionType get_tempo_type ();
private:
void init (const Timecode::BBT_Time& start, double, double, bool);
@@ -59,6 +60,9 @@ private:
typedef std::map<std::string,float> NoteTypes;
NoteTypes note_types;
+ typedef std::map<std::string, ARDOUR::TempoSection::TempoSectionType> TempoTypes;
+ TempoTypes tempo_types;
+
bool tapped; // whether the tap-tempo button has been clicked
double sum_x, sum_xx, sum_xy, sum_y;
double tap_count;
@@ -74,6 +78,8 @@ private:
Gtk::Label when_beat_label;
Gtk::Label pulse_selector_label;
Gtk::Button tap_tempo_button;
+ Gtk::ComboBoxText tempo_type;
+
};
class MeterDialog : public ArdourDialog
diff --git a/gtk2_ardour/tempo_lines.cc b/gtk2_ardour/tempo_lines.cc
index bb86011458..c320486108 100644
--- a/gtk2_ardour/tempo_lines.cc
+++ b/gtk2_ardour/tempo_lines.cc
@@ -54,12 +54,12 @@ TempoLines::hide ()
}
void
-TempoLines::draw_ticks (const ARDOUR::TempoMap::BBTPointList::const_iterator& b,
- unsigned divisions,
+TempoLines::draw_ticks (std::vector<ARDOUR::TempoMap::BBTPoint>& grid,
+ unsigned divisions,
framecnt_t leftmost_frame,
framecnt_t frame_rate)
{
- const double fpb = b->tempo->frames_per_beat(frame_rate);
+ const double fpb = grid.begin()->tempo->frames_per_beat(frame_rate);
const uint32_t base = UIConfiguration::instance().color_mod("measure line beat", "measure line beat");
for (unsigned l = 1; l < divisions; ++l) {
@@ -74,7 +74,8 @@ TempoLines::draw_ticks (const ARDOUR::TempoMap::BBTPointList::const_iterator& b,
/* draw line with alpha corresponding to coarsest level */
const uint8_t a = max(8, (int)rint(UINT_RGBA_A(base) / (0.8 * log2(level))));
const uint32_t c = UINT_RGBA_CHANGE_A(base, a);
- const framepos_t f = b->frame + (l * (fpb / (double)divisions));
+ const framepos_t f = grid.begin()->frame + (l * (fpb / (double)divisions));
+ //const framepos_t f = frame_at_tick (last_beat_in_ticks + (l * (BBT_Time::ticks_per_beat / (double)divisions)));
if (f > leftmost_frame) {
lines.add (PublicEditor::instance().sample_to_pixel_unrounded (f), 1.0, c);
}
@@ -82,13 +83,12 @@ TempoLines::draw_ticks (const ARDOUR::TempoMap::BBTPointList::const_iterator& b,
}
void
-TempoLines::draw (const ARDOUR::TempoMap::BBTPointList::const_iterator& begin,
- const ARDOUR::TempoMap::BBTPointList::const_iterator& end,
- unsigned divisions,
+TempoLines::draw (std::vector<ARDOUR::TempoMap::BBTPoint>& grid,
+ unsigned divisions,
framecnt_t leftmost_frame,
framecnt_t frame_rate)
{
- ARDOUR::TempoMap::BBTPointList::const_iterator i;
+ std::vector<ARDOUR::TempoMap::BBTPoint>::const_iterator i;
double beat_density;
uint32_t beats = 0;
@@ -97,10 +97,10 @@ TempoLines::draw (const ARDOUR::TempoMap::BBTPointList::const_iterator& begin,
/* get the first bar spacing */
- i = end;
+ i = grid.end();
i--;
- bars = (*i).bar - (*begin).bar;
- beats = distance (begin, end) - bars;
+ bars = (*i).bar - (*grid.begin()).bar;
+ beats = distance (grid.begin(), grid.end()) - bars;
beat_density = (beats * 10.0f) / lines.canvas()->width();
@@ -116,15 +116,14 @@ TempoLines::draw (const ARDOUR::TempoMap::BBTPointList::const_iterator& begin,
}
lines.clear ();
-
- if (beat_density <= 0.12 && begin != end && begin->frame > 0) {
- /* draw subdivisions of the beat before the first visible beat line */
- ARDOUR::TempoMap::BBTPointList::const_iterator prev = begin;
- --prev;
- draw_ticks(prev, divisions, leftmost_frame, frame_rate);
+ if (beat_density <= 0.12 && grid.begin() != grid.end() && grid.begin()->frame > 0) {
+ /* draw subdivisions of the beat before the first visible beat line XX this shouldn't happen now */
+ std::vector<ARDOUR::TempoMap::BBTPoint> vec;
+ vec.push_back (*i);
+ draw_ticks (vec, divisions, leftmost_frame, frame_rate);
}
- for (i = begin; i != end; ++i) {
+ for (i = grid.begin(); i != grid.end(); ++i) {
if ((*i).is_bar()) {
color = UIConfiguration::instance().color ("measure line bar");
@@ -141,7 +140,10 @@ TempoLines::draw (const ARDOUR::TempoMap::BBTPointList::const_iterator& begin,
if (beat_density <= 0.12) {
/* draw subdivisions of this beat */
- draw_ticks(i, divisions, leftmost_frame, frame_rate);
+ std::vector<ARDOUR::TempoMap::BBTPoint> vec;
+ vec.push_back (*i);
+
+ draw_ticks(vec, divisions, leftmost_frame, frame_rate);
}
}
}
diff --git a/gtk2_ardour/tempo_lines.h b/gtk2_ardour/tempo_lines.h
index 6d40a2d1a7..7096028981 100644
--- a/gtk2_ardour/tempo_lines.h
+++ b/gtk2_ardour/tempo_lines.h
@@ -29,9 +29,8 @@ public:
void tempo_map_changed();
- void draw (const ARDOUR::TempoMap::BBTPointList::const_iterator& begin,
- const ARDOUR::TempoMap::BBTPointList::const_iterator& end,
- unsigned divisions,
+ void draw (std::vector<ARDOUR::TempoMap::BBTPoint>& grid,
+ unsigned divisions,
ARDOUR::framecnt_t leftmost_frame,
ARDOUR::framecnt_t frame_rate);
@@ -39,8 +38,8 @@ public:
void hide();
private:
- void draw_ticks (const ARDOUR::TempoMap::BBTPointList::const_iterator& b,
- unsigned divisions,
+ void draw_ticks (std::vector<ARDOUR::TempoMap::BBTPoint>& grid,
+ unsigned divisions,
ARDOUR::framecnt_t leftmost_frame,
ARDOUR::framecnt_t frame_rate);