diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2012-01-02 04:04:14 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2012-01-02 04:04:14 +0000 |
commit | 69c7dac1a1ee70c5a4053acdc9dd139c986698a2 (patch) | |
tree | a5a13945a48d27e7ff4adf0ca916ffcab2bb0ef7 /gtk2_ardour | |
parent | 084fc8b3273d6daeb299773811c7d2bd0e1d5598 (diff) |
new approach to tempo/meter: compute and store the entire map (every bar|beat point), thus enabling us to use the same computation to set the BBT points AND the metric markers (tempo + meter) on the audio timeline. It is known that snapping to the BBT grid doesn't work correctly right now, but this probably caused by the separate code in TempoMap::round_to_type() and i'll dig into that tomorrow. Note that the Bar|beat point list is evaluated "lazily" - we'll never store more than anyone actually needs to display or know, other than 1 minute's worth starting from frame zero
git-svn-id: svn://localhost/ardour2/branches/3.0@11129 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'gtk2_ardour')
-rw-r--r-- | gtk2_ardour/editor.cc | 4 | ||||
-rw-r--r-- | gtk2_ardour/editor.h | 2 | ||||
-rw-r--r-- | gtk2_ardour/editor_rulers.cc | 54 | ||||
-rw-r--r-- | gtk2_ardour/editor_tempodisplay.cc | 13 | ||||
-rw-r--r-- | gtk2_ardour/tempo_lines.cc | 202 |
5 files changed, 127 insertions, 148 deletions
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 7a74312119..6e2c311704 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -305,7 +305,6 @@ Editor::Editor () pre_press_cursor = 0; _drags = new DragManager (this); current_mixer_strip = 0; - current_bbt_points = 0; tempo_lines = 0; snap_type_strings = I18N (_snap_type_strings); @@ -5335,8 +5334,7 @@ Editor::session_going_away () hide_measures (); clear_marker_display (); - delete current_bbt_points; - current_bbt_points = 0; + current_bbt_points.clear (); /* get rid of any existing editor mixer strip */ diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index b1162287a9..6c099899d8 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -1451,7 +1451,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD /// true if we scroll the tracks rather than the playhead bool _stationary_playhead; - ARDOUR::TempoMap::BBTPointList *current_bbt_points; + ARDOUR::TempoMap::BBTPointList current_bbt_points; TempoLines* tempo_lines; diff --git a/gtk2_ardour/editor_rulers.cc b/gtk2_ardour/editor_rulers.cc index f4bdd9291d..36eb84797f 100644 --- a/gtk2_ardour/editor_rulers.cc +++ b/gtk2_ardour/editor_rulers.cc @@ -1224,18 +1224,18 @@ Editor::compute_bbt_ruler_scale (framepos_t lower, framepos_t upper) break; } - if (current_bbt_points == 0 || current_bbt_points->empty()) { + if (current_bbt_points.empty()) { return; } - i = current_bbt_points->end(); + i = current_bbt_points.end(); i--; - if ((*i).beat >= (*current_bbt_points->begin()).beat) { - bbt_bars = (*i).bar - (*current_bbt_points->begin()).bar; + if ((*i).beat >= (*current_bbt_points.begin()).beat) { + bbt_bars = (*i).bar - (*current_bbt_points.begin()).bar; } else { - bbt_bars = (*i).bar - (*current_bbt_points->begin()).bar - 1; + bbt_bars = (*i).bar - (*current_bbt_points.begin()).bar - 1; } - beats = current_bbt_points->size() - bbt_bars; + beats = current_bbt_points.size() - bbt_bars; /* Only show the bar helper if there aren't many bars on the screen */ if ((bbt_bars < 2) || (beats < 5)) { @@ -1291,14 +1291,14 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble /*upp bool i_am_accented = false; bool helper_active = false; - if (current_bbt_points == 0 || current_bbt_points->empty()) { + if (current_bbt_points.empty()) { return 0; } switch (bbt_ruler_scale) { case bbt_show_beats: - beats = current_bbt_points->size(); + beats = current_bbt_points.size(); bbt_nmarks = beats + 2; *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * bbt_nmarks); @@ -1307,10 +1307,8 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble /*upp (*marks)[0].position = lower; (*marks)[0].style = GtkCustomRulerMarkMicro; - for (n = 1, i = current_bbt_points->begin(); n < bbt_nmarks && i != current_bbt_points->end(); ++i) { - if ((*i).type != TempoMap::Beat) { - continue; - } + for (n = 1, i = current_bbt_points.begin(); n < bbt_nmarks && i != current_bbt_points.end(); ++i) { + if ((*i).frame < lower && (bbt_bar_helper_on)) { snprintf (buf, sizeof(buf), "<%" PRIu32 "|%" PRIu32, (*i).bar, (*i).beat); (*marks)[0].label = g_strdup (buf); @@ -1336,7 +1334,7 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble /*upp case bbt_show_ticks: - beats = current_bbt_points->size(); + beats = current_bbt_points.size(); bbt_nmarks = (beats + 2) * bbt_beat_subdivision; bbt_position_of_helper = lower + (30 * Editor::get_current_zoom ()); @@ -1346,10 +1344,8 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble /*upp (*marks)[0].position = lower; (*marks)[0].style = GtkCustomRulerMarkMicro; - for (n = 1, i = current_bbt_points->begin(); n < bbt_nmarks && i != current_bbt_points->end(); ++i) { - if ((*i).type != TempoMap::Beat) { - continue; - } + for (n = 1, i = current_bbt_points.begin(); n < bbt_nmarks && i != current_bbt_points.end(); ++i) { + if ((*i).frame < lower && (bbt_bar_helper_on)) { snprintf (buf, sizeof(buf), "<%" PRIu32 "|%" PRIu32, (*i).bar, (*i).beat); (*marks)[0].label = g_strdup (buf); @@ -1428,7 +1424,7 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble /*upp case bbt_show_ticks_detail: - beats = current_bbt_points->size(); + beats = current_bbt_points.size(); bbt_nmarks = (beats + 2) * bbt_beat_subdivision; bbt_position_of_helper = lower + (30 * Editor::get_current_zoom ()); @@ -1438,10 +1434,8 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble /*upp (*marks)[0].position = lower; (*marks)[0].style = GtkCustomRulerMarkMicro; - for (n = 1, i = current_bbt_points->begin(); n < bbt_nmarks && i != current_bbt_points->end(); ++i) { - if ((*i).type != TempoMap::Beat) { - continue; - } + for (n = 1, i = current_bbt_points.begin(); n < bbt_nmarks && i != current_bbt_points.end(); ++i) { + if ((*i).frame < lower && (bbt_bar_helper_on)) { snprintf (buf, sizeof(buf), "<%" PRIu32 "|%" PRIu32, (*i).bar, (*i).beat); (*marks)[0].label = g_strdup (buf); @@ -1525,7 +1519,7 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble /*upp case bbt_show_ticks_super_detail: - beats = current_bbt_points->size(); + beats = current_bbt_points.size(); bbt_nmarks = (beats + 2) * bbt_beat_subdivision; bbt_position_of_helper = lower + (30 * Editor::get_current_zoom ()); @@ -1535,10 +1529,8 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble /*upp (*marks)[0].position = lower; (*marks)[0].style = GtkCustomRulerMarkMicro; - for (n = 1, i = current_bbt_points->begin(); n < bbt_nmarks && i != current_bbt_points->end(); ++i) { - if ((*i).type != TempoMap::Beat) { - continue; - } + for (n = 1, i = current_bbt_points.begin(); n < bbt_nmarks && i != current_bbt_points.end(); ++i) { + if ((*i).frame < lower && (bbt_bar_helper_on)) { snprintf (buf, sizeof(buf), "<%" PRIu32 "|%" PRIu32, (*i).bar, (*i).beat); (*marks)[0].label = g_strdup (buf); @@ -1634,7 +1626,7 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble /*upp case bbt_show_64: bbt_nmarks = (gint) (bbt_bars / 64) + 1; *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * bbt_nmarks); - for (n = 0, i = current_bbt_points->begin(); i != current_bbt_points->end() && n < bbt_nmarks; i++) { + for (n = 0, i = current_bbt_points.begin(); i != current_bbt_points.end() && n < bbt_nmarks; i++) { if ((*i).type == TempoMap::Bar) { if ((*i).bar % 64 == 1) { if ((*i).bar % 256 == 1) { @@ -1659,7 +1651,7 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble /*upp case bbt_show_16: bbt_nmarks = (bbt_bars / 16) + 1; *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * bbt_nmarks); - for (n = 0, i = current_bbt_points->begin(); i != current_bbt_points->end() && n < bbt_nmarks; i++) { + for (n = 0, i = current_bbt_points.begin(); i != current_bbt_points.end() && n < bbt_nmarks; i++) { if ((*i).type == TempoMap::Bar) { if ((*i).bar % 16 == 1) { if ((*i).bar % 64 == 1) { @@ -1684,7 +1676,7 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble /*upp case bbt_show_4: bbt_nmarks = (bbt_bars / 4) + 1; *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * bbt_nmarks); - for (n = 0, i = current_bbt_points->begin(); i != current_bbt_points->end() && n < bbt_nmarks; ++i) { + for (n = 0, i = current_bbt_points.begin(); i != current_bbt_points.end() && n < bbt_nmarks; ++i) { if ((*i).type == TempoMap::Bar) { if ((*i).bar % 4 == 1) { if ((*i).bar % 16 == 1) { @@ -1710,7 +1702,7 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble /*upp // default: bbt_nmarks = bbt_bars + 2; *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * bbt_nmarks ); - for (n = 0, i = current_bbt_points->begin(); i != current_bbt_points->end() && n < bbt_nmarks; i++) { + for (n = 0, i = current_bbt_points.begin(); i != current_bbt_points.end() && n < bbt_nmarks; i++) { if ((*i).type == TempoMap::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 89832c5d13..79f5caf82b 100644 --- a/gtk2_ardour/editor_tempodisplay.cc +++ b/gtk2_ardour/editor_tempodisplay.cc @@ -114,7 +114,7 @@ Editor::tempo_map_changed (const PropertyChange& /*ignored*/) tempo_lines->tempo_map_changed(); } - compute_current_bbt_points(leftmost_frame, leftmost_frame + current_page_frames()); + compute_current_bbt_points (leftmost_frame, leftmost_frame + current_page_frames()); _session->tempo_map().apply_with_metrics (*this, &Editor::draw_metric_marks); // redraw metric markers redraw_measures (); update_tempo_based_rulers (); @@ -169,10 +169,8 @@ Editor::compute_current_bbt_points (framepos_t leftmost, framepos_t rightmost) } next_beat.ticks = 0; - delete current_bbt_points; - current_bbt_points = 0; - - current_bbt_points = _session->tempo_map().get_points (_session->tempo_map().frame_time (previous_beat), _session->tempo_map().frame_time (next_beat) + 1); + current_bbt_points.clear(); + _session->tempo_map().map (current_bbt_points, _session->tempo_map().frame_time (previous_beat), _session->tempo_map().frame_time (next_beat) + 1); } void @@ -192,8 +190,7 @@ Editor::redraw_measures () void Editor::draw_measures () { - if (_session == 0 || _show_measures == false || - !current_bbt_points || current_bbt_points->empty()) { + if (_session == 0 || _show_measures == false || current_bbt_points.empty()) { return; } @@ -201,7 +198,7 @@ Editor::draw_measures () tempo_lines = new TempoLines(*track_canvas, time_line_group, physical_screen_height(get_window())); } - tempo_lines->draw(*current_bbt_points, frames_per_unit); + tempo_lines->draw (current_bbt_points, frames_per_unit); } void diff --git a/gtk2_ardour/tempo_lines.cc b/gtk2_ardour/tempo_lines.cc index 8fe877a27c..cab185026f 100644 --- a/gtk2_ardour/tempo_lines.cc +++ b/gtk2_ardour/tempo_lines.cc @@ -131,122 +131,114 @@ TempoLines::draw (ARDOUR::TempoMap::BBTPointList& points, double frames_per_unit for (i = points.begin(); i != points.end(); ++i) { - switch ((*i).type) { - case ARDOUR::TempoMap::Bar: - break; - - case ARDOUR::TempoMap::Beat: - if ((*i).beat == 1) { - color = ARDOUR_UI::config()->canvasvar_MeasureLineBar.get(); - } else { - color = ARDOUR_UI::config()->canvasvar_MeasureLineBeat.get(); - if (beat_density > 2.0) { - break; /* only draw beat lines if the gaps between beats are large. */ - } - } - - xpos = rint(((framepos_t)(*i).frame) / (double)frames_per_unit); - - if (inserted_last_time && !_lines.empty()) { - li = _lines.lower_bound(xpos); // first line >= xpos + if ((*i).type == ARDOUR::TempoMap::Bar) { + color = ARDOUR_UI::config()->canvasvar_MeasureLineBar.get(); + } else { + if (beat_density > 2.0) { + continue; /* only draw beat lines if the gaps between beats are large. */ } + color = ARDOUR_UI::config()->canvasvar_MeasureLineBeat.get(); + } - line = (li != _lines.end()) ? li->second : NULL; - assert(!line || line->property_x1() == li->first); - - Lines::iterator next = li; - if (next != _lines.end()) - ++next; - - exhausted = (next == _lines.end()); - - // Hooray, line is perfect - if (line && line->property_x1() == xpos) { - if (li != _lines.end()) - ++li; - - line->property_color_rgba() = color; - inserted_last_time = false; // don't search next time - + xpos = rint(((framepos_t)(*i).frame) / (double)frames_per_unit); + + if (inserted_last_time && !_lines.empty()) { + li = _lines.lower_bound(xpos); // first line >= xpos + } + + line = (li != _lines.end()) ? li->second : NULL; + assert(!line || line->property_x1() == li->first); + + Lines::iterator next = li; + if (next != _lines.end()) + ++next; + + exhausted = (next == _lines.end()); + + // Hooray, line is perfect + if (line && line->property_x1() == xpos) { + if (li != _lines.end()) + ++li; + + line->property_color_rgba() = color; + inserted_last_time = false; // don't search next time + // Use existing line, moving if necessary - } else if (!exhausted) { - Lines::iterator steal = _lines.end(); - --steal; - - // Steal from the right - if (left->first > needed_left && li != steal && steal->first > needed_right) { - //cout << "*** STEALING FROM RIGHT" << endl; - line = steal->second; - _lines.erase(steal); - line->property_x1() = xpos; - line->property_x2() = xpos; - line->property_color_rgba() = color; - _lines.insert(make_pair(xpos, line)); - inserted_last_time = true; // search next time - invalidated = true; - - // Shift clean range left - _clean_left = min(_clean_left, xpos); - _clean_right = min(_clean_right, steal->first); - - // Move this line to where we need it - } else { - Lines::iterator existing = _lines.find(xpos); - if (existing != _lines.end()) { - //cout << "*** EXISTING LINE" << endl; - li = existing; - li->second->property_color_rgba() = color; - inserted_last_time = false; // don't search next time - } else { - //cout << "*** MOVING LINE" << endl; - const double x1 = line->property_x1(); - const bool was_clean = x1 >= _clean_left && x1 <= _clean_right; - invalidated = invalidated || was_clean; - // Invalidate clean portion (XXX: too harsh?) - _clean_left = needed_left; - _clean_right = needed_right; - _lines.erase(li); - line->property_color_rgba() = color; - line->property_x1() = xpos; - line->property_x2() = xpos; - _lines.insert(make_pair(xpos, line)); - inserted_last_time = true; // search next time - } - } - - // Create a new line - } else if (_lines.size() < needed || _lines.size() < MAX_CACHED_LINES) { - //cout << "*** CREATING LINE" << endl; - assert(_lines.find(xpos) == _lines.end()); - line = new ArdourCanvas::SimpleLine (*_group); - line->property_x1() = xpos; - line->property_x2() = xpos; - line->property_y1() = 0.0; - line->property_y2() = _height; - line->property_color_rgba() = color; - _lines.insert(make_pair(xpos, line)); - inserted_last_time = true; - - // Steal from the left - } else { - //cout << "*** STEALING FROM LEFT" << endl; - assert(_lines.find(xpos) == _lines.end()); - Lines::iterator steal = _lines.begin(); + } else if (!exhausted) { + Lines::iterator steal = _lines.end(); + --steal; + + // Steal from the right + if (left->first > needed_left && li != steal && steal->first > needed_right) { + //cout << "*** STEALING FROM RIGHT" << endl; line = steal->second; _lines.erase(steal); - line->property_color_rgba() = color; line->property_x1() = xpos; line->property_x2() = xpos; + line->property_color_rgba() = color; _lines.insert(make_pair(xpos, line)); inserted_last_time = true; // search next time invalidated = true; - - // Shift clean range right - _clean_left = max(_clean_left, steal->first); - _clean_right = max(_clean_right, xpos); + + // Shift clean range left + _clean_left = min(_clean_left, xpos); + _clean_right = min(_clean_right, steal->first); + + // Move this line to where we need it + } else { + Lines::iterator existing = _lines.find(xpos); + if (existing != _lines.end()) { + //cout << "*** EXISTING LINE" << endl; + li = existing; + li->second->property_color_rgba() = color; + inserted_last_time = false; // don't search next time + } else { + //cout << "*** MOVING LINE" << endl; + const double x1 = line->property_x1(); + const bool was_clean = x1 >= _clean_left && x1 <= _clean_right; + invalidated = invalidated || was_clean; + // Invalidate clean portion (XXX: too harsh?) + _clean_left = needed_left; + _clean_right = needed_right; + _lines.erase(li); + line->property_color_rgba() = color; + line->property_x1() = xpos; + line->property_x2() = xpos; + _lines.insert(make_pair(xpos, line)); + inserted_last_time = true; // search next time + } } - - break; + + // Create a new line + } else if (_lines.size() < needed || _lines.size() < MAX_CACHED_LINES) { + //cout << "*** CREATING LINE" << endl; + assert(_lines.find(xpos) == _lines.end()); + line = new ArdourCanvas::SimpleLine (*_group); + line->property_x1() = xpos; + line->property_x2() = xpos; + line->property_y1() = 0.0; + line->property_y2() = _height; + line->property_color_rgba() = color; + _lines.insert(make_pair(xpos, line)); + inserted_last_time = true; + + // Steal from the left + } else { + //cout << "*** STEALING FROM LEFT" << endl; + assert(_lines.find(xpos) == _lines.end()); + Lines::iterator steal = _lines.begin(); + line = steal->second; + _lines.erase(steal); + line->property_color_rgba() = color; + line->property_x1() = xpos; + line->property_x2() = xpos; + _lines.insert(make_pair(xpos, line)); + inserted_last_time = true; // search next time + invalidated = true; + + // Shift clean range right + _clean_left = max(_clean_left, steal->first); + _clean_right = max(_clean_right, xpos); } } |