#include "time_axis_view.h"
#include "editor_drag.h"
#include "editor_cursors.h"
+#include "ui_config.h"
-#include "i18n.h"
+#include "pbd/i18n.h"
using namespace ARDOUR;
using namespace PBD;
Editor::initialize_rulers ()
{
ruler_grabbed_widget = 0;
- /* Not really sure why we can't get this right in a cross-platform way,
- but it seems hard.
- */
-#ifdef __APPLE__
- Pango::FontDescription font (ARDOUR_UI::config()->get_SmallerFont());
-#else
- Pango::FontDescription font (ARDOUR_UI::config()->get_SmallFont());
-#endif
+
+ Pango::FontDescription font (UIConfiguration::instance().get_SmallerFont());
+
_timecode_metric = new TimecodeMetric (this);
_bbt_metric = new BBTMetric (this);
_minsec_metric = new MinsecMetric (this);
_samples_metric = new SamplesMetric (this);
-
+
timecode_ruler = new ArdourCanvas::Ruler (_time_markers_group, *_timecode_metric,
ArdourCanvas::Rect (0, 0, ArdourCanvas::COORD_MAX, timebar_height));
timecode_ruler->set_font_description (font);
minsec_ruler->Event.connect (sigc::bind (sigc::mem_fun (*this, &Editor::canvas_ruler_event), minsec_ruler, MinsecRulerItem));
bbt_ruler->Event.connect (sigc::bind (sigc::mem_fun (*this, &Editor::canvas_ruler_event), bbt_ruler, BBTRulerItem));
samples_ruler->Event.connect (sigc::bind (sigc::mem_fun (*this, &Editor::canvas_ruler_event), samples_ruler, SamplesRulerItem));
-
+
visible_timebars = 0; /*this will be changed below */
}
switch (t) {
case MarkerBarItem:
- ruler_items.push_back (MenuElem (_("New location marker"), sigc::bind ( sigc::mem_fun(*this, &Editor::mouse_add_new_marker), where, false, false)));
+ ruler_items.push_back (MenuElem (_("New location marker"), sigc::bind ( sigc::mem_fun(*this, &Editor::mouse_add_new_marker), where, false)));
ruler_items.push_back (MenuElem (_("Clear all locations"), sigc::mem_fun(*this, &Editor::clear_markers)));
ruler_items.push_back (MenuElem (_("Unhide locations"), sigc::mem_fun(*this, &Editor::unhide_markers)));
- ruler_items.push_back (SeparatorElem ());
break;
+
case RangeMarkerBarItem:
ruler_items.push_back (MenuElem (_("New range"), sigc::bind (sigc::mem_fun (*this, &Editor::mouse_add_new_range), where)));
ruler_items.push_back (MenuElem (_("Clear all ranges"), sigc::mem_fun(*this, &Editor::clear_ranges)));
ruler_items.push_back (MenuElem (_("Unhide ranges"), sigc::mem_fun(*this, &Editor::unhide_ranges)));
- ruler_items.push_back (SeparatorElem ());
-
break;
- case TransportMarkerBarItem:
+ case TransportMarkerBarItem:
+ ruler_items.push_back (MenuElem (_("New Loop range"), sigc::bind (sigc::mem_fun (*this, &Editor::mouse_add_new_loop), where)));
+ ruler_items.push_back (MenuElem (_("New Punch range"), sigc::bind (sigc::mem_fun (*this, &Editor::mouse_add_new_punch), where)));
break;
case CdMarkerBarItem:
// TODO
- ruler_items.push_back (MenuElem (_("New CD track marker"), sigc::bind ( sigc::mem_fun(*this, &Editor::mouse_add_new_marker), where, true, false)));
+ ruler_items.push_back (MenuElem (_("New CD track marker"), sigc::bind ( sigc::mem_fun(*this, &Editor::mouse_add_new_marker), where, true)));
break;
-
case TempoBarItem:
ruler_items.push_back (MenuElem (_("New Tempo"), sigc::bind ( sigc::mem_fun(*this, &Editor::mouse_add_new_tempo_event), where)));
break;
break;
case VideoBarItem:
- ruler_items.push_back (MenuElem (_("Timeline height")));
- static_cast<MenuItem*>(&ruler_items.back())->set_sensitive(false);
+ /* proper headings would be nice
+ * but AFAICT the only way to get them will be to define a
+ * special GTK style for insensitive Elements or subclass MenuItem
+ */
+ //ruler_items.push_back (MenuElem (_("Timeline height"))); // heading
+ //static_cast<MenuItem*>(&ruler_items.back())->set_sensitive(false);
ruler_items.push_back (CheckMenuElem (_("Large"), sigc::bind ( sigc::mem_fun(*this, &Editor::set_video_timeline_height), 6)));
if (videotl_bar_height == 6) { static_cast<Gtk::CheckMenuItem*>(&ruler_items.back())->set_active(true);}
ruler_items.push_back (CheckMenuElem (_("Normal"), sigc::bind ( sigc::mem_fun(*this, &Editor::set_video_timeline_height), 4)));
if (videotl_bar_height == 4) { static_cast<Gtk::CheckMenuItem*>(&ruler_items.back())->set_active(true);}
ruler_items.push_back (CheckMenuElem (_("Small"), sigc::bind ( sigc::mem_fun(*this, &Editor::set_video_timeline_height), 3)));
if (videotl_bar_height == 3) { static_cast<Gtk::CheckMenuItem*>(&ruler_items.back())->set_active(true);}
- ruler_items.push_back (SeparatorElem ());
- ruler_items.push_back (MenuElem (_("Align Video Track")));
- static_cast<MenuItem*>(&ruler_items.back())->set_sensitive(false);
+ ruler_items.push_back (SeparatorElem ());
+ //ruler_items.push_back (MenuElem (_("Align Video Track"))); // heading
+ //static_cast<MenuItem*>(&ruler_items.back())->set_sensitive(false);
ruler_items.push_back (CheckMenuElem (_("Lock")));
{
Gtk::CheckMenuItem* vtl_lock = static_cast<Gtk::CheckMenuItem*>(&ruler_items.back());
vtl_lock->set_active(is_video_timeline_locked());
vtl_lock->signal_activate().connect (sigc::mem_fun(*this, &Editor::toggle_video_timeline_locked));
}
+
+ ruler_items.push_back (SeparatorElem ());
+
+ //ruler_items.push_back (MenuElem (_("Video Monitor"))); // heading
+ //static_cast<MenuItem*>(&ruler_items.back())->set_sensitive(false);
+ ruler_items.push_back (CheckMenuElem (_("Video Monitor")));
+ {
+ Gtk::CheckMenuItem* xjadeo_toggle = static_cast<Gtk::CheckMenuItem*>(&ruler_items.back());
+ if (!ARDOUR_UI::instance()->video_timeline->found_xjadeo()) {
+ xjadeo_toggle->set_sensitive(false);
+ }
+ xjadeo_toggle->set_active(xjadeo_proc_action->get_active());
+ xjadeo_toggle->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &Editor::toggle_xjadeo_proc), -1));
+ }
break;
default:
void
Editor::restore_ruler_visibility ()
{
- XMLProperty* prop;
+ XMLProperty const * prop;
XMLNode * node = _session->extra_xml (X_("RulerVisibility"));
no_ruler_shown_update = true;
double tbgpos = 0.0;
double old_unit_pos;
-#ifdef GTKOSX
+#ifdef __APPLE__
/* gtk update probs require this (damn) */
meter_label.hide();
tempo_label.hide();
tempo_label.hide();
}
- if (!Profile->get_sae() && ruler_range_action->get_active()) {
+ if (ruler_range_action->get_active()) {
old_unit_pos = range_marker_group->position().y;
if (tbpos != old_unit_pos) {
range_marker_group->move (ArdourCanvas::Duple (0.0, tbpos - old_unit_pos));
}
void
-Editor::update_tempo_based_rulers (ARDOUR::TempoMap::BBTPointList::const_iterator& begin,
- ARDOUR::TempoMap::BBTPointList::const_iterator& end)
+Editor::update_tempo_based_rulers ()
{
if (_session == 0) {
return;
}
- compute_bbt_ruler_scale (leftmost_frame, leftmost_frame+current_page_samples(),
- begin, end);
-
_bbt_metric->units_per_pixel = samples_per_pixel;
if (ruler_bbt_action->get_active()) {
return;
}
- fr = _session->frame_rate();
+ fr = _session->frame_rate();
if (lower > (spacer = (framepos_t) (128 * Editor::get_current_zoom ()))) {
lower = lower - spacer;
} else if (range <= 8 * 60 * 60 * fr) { /* 4 - 8 hrs*/
timecode_ruler_scale = timecode_show_hours;
timecode_mark_modulo = 1;
- timecode_nmarks = 2 + 8;
+ timecode_nmarks = 2 + 8;
} else if (range <= 16 * 60 * 60 * fr) { /* 16-24 hrs*/
timecode_ruler_scale = timecode_show_hours;
timecode_mark_modulo = 1;
} else {
const framecnt_t hours_in_range = range / (60 * 60 * fr);
- const int text_width_rough_guess = 70; /* pixels, very very approximate guess at how wide the tick mark text is */
+ const int text_width_rough_guess = 120; /* pixels, very very approximate guess at how wide the tick mark text is */
/* Normally we do not need to know anything about the width of the canvas
to set the ruler scale, because the caller has already determined
But in this case, where the range defined by lower and uppper can vary
substantially (basically anything from 24hrs+ to several billion years)
- trying to decide which tick marks to show does require us to know
+ trying to decide which tick marks to show does require us to know
about the available width.
*/
switch (timecode_ruler_scale) {
case timecode_show_bits:
-
// Find timecode time of this sample (pos) with subframe accuracy
_session->sample_to_timecode(pos, timecode, true /* use_offset */, true /* use_subframes */ );
-
for (n = 0; n < timecode_nmarks; n++) {
_session->timecode_to_sample(timecode, pos, true /* use_offset */, true /* use_subframes */ );
if ((timecode.subframes % timecode_mark_modulo) == 0) {
if (timecode.subframes == 0) {
mark.style = ArdourCanvas::Ruler::Mark::Major;
- if (timecode.hours) {
- snprintf (buf, sizeof(buf), "%s%u:%02u:%02u", timecode.negative ? "-" : "", timecode.hours, timecode.minutes, timecode.seconds);
- } else {
- snprintf (buf, sizeof(buf), "%s%u:%02u", timecode.negative ? "-" : "", timecode.minutes, timecode.seconds);
- }
-
+ snprintf (buf, sizeof(buf), "%s%02u:%02u:%02u:%02u", timecode.negative ? "-" : "", timecode.hours, timecode.minutes, timecode.seconds, timecode.frames);
} else {
mark.style = ArdourCanvas::Ruler::Mark::Minor;
snprintf (buf, sizeof(buf), ".%02u", timecode.subframes);
} else {
snprintf (buf, sizeof(buf)," ");
mark.style = ArdourCanvas::Ruler::Mark::Micro;
-
}
mark.label = buf;
mark.position = pos;
-
marks.push_back (mark);
-
// Increment subframes by one
Timecode::increment_subframes( timecode, _session->config.get_subframes_per_frame() );
}
- break;
+ break;
+
+ case timecode_show_frames:
+ // Find timecode time of this sample (pos)
+ _session->sample_to_timecode(pos, timecode, true /* use_offset */, false /* use_subframes */ );
+ // Go to next whole frame down
+ Timecode::frames_floor( timecode );
+ for (n = 0; n < timecode_nmarks; n++) {
+ _session->timecode_to_sample(timecode, pos, true /* use_offset */, false /* use_subframes */ );
+ if ((timecode.frames % timecode_mark_modulo) == 0) {
+ if (timecode.frames == 0) {
+ mark.style = ArdourCanvas::Ruler::Mark::Major;
+ } else {
+ mark.style = ArdourCanvas::Ruler::Mark::Minor;
+ }
+ mark.position = pos;
+ snprintf (buf, sizeof(buf), "%s%02u:%02u:%02u:%02u", timecode.negative ? "-" : "", timecode.hours, timecode.minutes, timecode.seconds, timecode.frames);
+ } else {
+ snprintf (buf, sizeof(buf)," ");
+ mark.style = ArdourCanvas::Ruler::Mark::Micro;
+ mark.position = pos;
+ }
+ mark.label = buf;
+ marks.push_back (mark);
+ Timecode::increment( timecode, _session->config.get_subframes_per_frame() );
+ }
+ break;
+
case timecode_show_seconds:
// Find timecode time of this sample (pos)
_session->sample_to_timecode(pos, timecode, true /* use_offset */, false /* use_subframes */ );
// Go to next whole second down
Timecode::seconds_floor( timecode );
-
for (n = 0; n < timecode_nmarks; n++) {
_session->timecode_to_sample(timecode, pos, true /* use_offset */, false /* use_subframes */ );
if ((timecode.seconds % timecode_mark_modulo) == 0) {
mark.style = ArdourCanvas::Ruler::Mark::Minor;
mark.position = pos;
}
- if (timecode.hours) {
- snprintf (buf, sizeof(buf), "%s%u:%02u:%02u", timecode.negative ? "-" : "", timecode.hours, timecode.minutes, timecode.seconds);
- } else {
- snprintf (buf, sizeof(buf), "%s%u:%02u", timecode.negative ? "-" : "", timecode.minutes, timecode.seconds);
- }
+ snprintf (buf, sizeof(buf), "%s%02u:%02u:%02u:%02u", timecode.negative ? "-" : "", timecode.hours, timecode.minutes, timecode.seconds, timecode.frames);
} else {
snprintf (buf, sizeof(buf)," ");
mark.style = ArdourCanvas::Ruler::Mark::Micro;
mark.position = pos;
-
}
mark.label = buf;
marks.push_back (mark);
-
Timecode::increment_seconds( timecode, _session->config.get_subframes_per_frame() );
}
- break;
+ break;
+
case timecode_show_minutes:
- // Find timecode time of this sample (pos)
+ //Find timecode time of this sample (pos)
_session->sample_to_timecode(pos, timecode, true /* use_offset */, false /* use_subframes */ );
// Go to next whole minute down
Timecode::minutes_floor( timecode );
-
for (n = 0; n < timecode_nmarks; n++) {
_session->timecode_to_sample(timecode, pos, true /* use_offset */, false /* use_subframes */ );
if ((timecode.minutes % timecode_mark_modulo) == 0) {
} else {
mark.style = ArdourCanvas::Ruler::Mark::Minor;
}
- if (timecode.hours) {
- snprintf (buf, sizeof(buf), "%s%u:%02u:%02u", timecode.negative ? "-" : "", timecode.hours, timecode.minutes, timecode.seconds);
- } else {
- snprintf (buf, sizeof(buf), "%s%u:%02u", timecode.negative ? "-" : "", timecode.minutes, timecode.seconds);
- }
+ snprintf (buf, sizeof(buf), "%s%02u:%02u:%02u:%02u", timecode.negative ? "-" : "", timecode.hours, timecode.minutes, timecode.seconds, timecode.frames);
} else {
snprintf (buf, sizeof(buf)," ");
mark.style = ArdourCanvas::Ruler::Mark::Micro;
-
}
mark.label = buf;
mark.position = pos;
marks.push_back (mark);
Timecode::increment_minutes( timecode, _session->config.get_subframes_per_frame() );
}
-
- break;
+ break;
case timecode_show_hours:
// Find timecode time of this sample (pos)
_session->sample_to_timecode(pos, timecode, true /* use_offset */, false /* use_subframes */ );
// Go to next whole hour down
Timecode::hours_floor( timecode );
-
for (n = 0; n < timecode_nmarks; n++) {
_session->timecode_to_sample(timecode, pos, true /* use_offset */, false /* use_subframes */ );
if ((timecode.hours % timecode_mark_modulo) == 0) {
mark.style = ArdourCanvas::Ruler::Mark::Major;
- if (timecode.hours) {
- snprintf (buf, sizeof(buf), "%s%u:%02u:%02u", timecode.negative ? "-" : "", timecode.hours, timecode.minutes, timecode.seconds);
- } else {
- snprintf (buf, sizeof(buf), "%s%u:%02u", timecode.negative ? "-" : "", timecode.minutes, timecode.seconds);
- }
+ snprintf (buf, sizeof(buf), "%s%02u:%02u:%02u:%02u", timecode.negative ? "-" : "", timecode.hours, timecode.minutes, timecode.seconds, timecode.frames);
} else {
snprintf (buf, sizeof(buf)," ");
mark.style = ArdourCanvas::Ruler::Mark::Micro;
-
}
mark.label = buf;
mark.position = pos;
marks.push_back (mark);
- /* Move to next hour */
- Timecode::increment_hours( timecode, _session->config.get_subframes_per_frame() );
+ Timecode::increment_hours( timecode, _session->config.get_subframes_per_frame() );
}
- break;
-
+ break;
case timecode_show_many_hours:
// Find timecode time of this sample (pos)
_session->sample_to_timecode(pos, timecode, true /* use_offset */, false /* use_subframes */ );
_session->timecode_to_sample(timecode, pos, true /* use_offset */, false /* use_subframes */ );
if ((timecode.hours % timecode_mark_modulo) == 0) {
mark.style = ArdourCanvas::Ruler::Mark::Major;
- if (timecode.hours) {
- snprintf (buf, sizeof(buf), "%s%u:%02u:%02u", timecode.negative ? "-" : "", timecode.hours, timecode.minutes, timecode.seconds);
- } else {
- snprintf (buf, sizeof(buf), "%s%u:%02u", timecode.negative ? "-" : "", timecode.minutes, timecode.seconds);
- }
+ snprintf (buf, sizeof(buf), "%s%02u:%02u:%02u:%02u", timecode.negative ? "-" : "", timecode.hours, timecode.minutes, timecode.seconds, timecode.frames);
mark.label = buf;
mark.position = pos;
marks.push_back (mark);
++n;
- }
- /* can't use Timecode::increment_hours() here because we may be traversing thousands of hours
- and doing it 1 hour at a time is just stupid (and slow).
- */
- timecode.hours += timecode_mark_modulo;
- }
- break;
-
- case timecode_show_frames:
- // Find timecode time of this sample (pos)
- _session->sample_to_timecode(pos, timecode, true /* use_offset */, false /* use_subframes */ );
- // Go to next whole frame down
- Timecode::frames_floor( timecode );
-
- for (n = 0; n < timecode_nmarks; n++) {
- _session->timecode_to_sample(timecode, pos, true /* use_offset */, false /* use_subframes */ );
- if ((timecode.frames % timecode_mark_modulo) == 0) {
- if (timecode.frames == 0) {
- mark.style = ArdourCanvas::Ruler::Mark::Major;
- } else {
- mark.style = ArdourCanvas::Ruler::Mark::Minor;
- }
- mark.position = pos;
- if (timecode.hours) {
- snprintf (buf, sizeof(buf), "%s%u:%02u:%02u", timecode.negative ? "-" : "", timecode.hours, timecode.minutes, timecode.seconds);
- } else {
- snprintf (buf, sizeof(buf), "%s%u:%02u", timecode.negative ? "-" : "", timecode.minutes, timecode.seconds);
- }
- } else {
- snprintf (buf, sizeof(buf)," ");
- mark.style = ArdourCanvas::Ruler::Mark::Micro;
- mark.position = pos;
-
}
- mark.label = buf;
- marks.push_back (mark);
- Timecode::increment( timecode, _session->config.get_subframes_per_frame() );
+ /* can't use Timecode::increment_hours() here because we may be traversing thousands of hours
+ * and doing it 1 hour at a time is just stupid (and slow).
+ */
+ timecode.hours += timecode_mark_modulo - (timecode.hours % timecode_mark_modulo);
}
-
- break;
+ break;
}
}
-
-
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 (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
+ double floor_lower_beat = floor(max (0.0, _session->tempo_map().beat_at_frame (lower)));
+
+ if (floor_lower_beat < 0.0) {
+ floor_lower_beat = 0.0;
+ }
+
+ const framecnt_t beat_before_lower_pos = _session->tempo_map().frame_at_beat (floor_lower_beat);
+ const framecnt_t beat_after_upper_pos = _session->tempo_map().frame_at_beat (floor (max (0.0, _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;
break;
}
- if (distance (begin, end) == 0) {
+ const double ceil_upper_beat = floor (max (0.0, _session->tempo_map().beat_at_frame (upper))) + 1.0;
+ if (ceil_upper_beat == floor_lower_beat) {
return;
}
- i = end;
- i--;
- if ((*i).beat >= (*begin).beat) {
- bbt_bars = (*i).bar - (*begin).bar;
- } else {
- bbt_bars = (*i).bar - (*begin).bar - 1;
- }
- beats = distance (begin, end) - bbt_bars;
+ bbt_bars = _session->tempo_map().bbt_at_beat (ceil_upper_beat).bars - _session->tempo_map().bbt_at_beat (floor_lower_beat).bars;
+
+ beats = (ceil_upper_beat - floor_lower_beat) - bbt_bars;
+ double beat_density = ((beats + 1) * ((double) (upper - lower) / (double) (1 + beat_after_upper_pos - beat_before_lower_pos))) / 5.0;
/* Only show the bar helper if there aren't many bars on the screen */
if ((bbt_bars < 2) || (beats < 5)) {
bbt_bar_helper_on = true;
}
- if (bbt_bars > 8192) {
- bbt_ruler_scale = bbt_show_many;
- } else if (bbt_bars > 1024) {
+ if (beat_density > 8192) {
+ bbt_ruler_scale = bbt_show_many;
+ } else if (beat_density > 1024) {
bbt_ruler_scale = bbt_show_64;
- } else if (bbt_bars > 256) {
+ } else if (beat_density > 512) {
bbt_ruler_scale = bbt_show_16;
- } else if (bbt_bars > 64) {
+ } else if (beat_density > 128) {
bbt_ruler_scale = bbt_show_4;
- } else if (bbt_bars > 10) {
+ } else if (beat_density > 16) {
bbt_ruler_scale = bbt_show_1;
- } else if (bbt_bars > 2) {
+ } else if (beat_density > 2) {
bbt_ruler_scale = bbt_show_beats;
- } else if (bbt_bars > 0) {
+ } else if (beat_density > 0.5) {
bbt_ruler_scale = bbt_show_ticks;
} else {
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;
}
}
-static void
+static void
edit_last_mark_label (std::vector<ArdourCanvas::Ruler::Mark>& marks, const std::string& newlabel)
{
ArdourCanvas::Ruler::Mark copy = marks.back();
copy.label = newlabel;
marks.pop_back ();
marks.push_back (copy);
-}
+}
void
Editor::metric_get_bbt (std::vector<ArdourCanvas::Ruler::Mark>& marks, gdouble lower, gdouble upper, gint /*maxchars*/)
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 = "";
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);
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 ());
-
+
// could do marks.assign() here to preallocate
mark.label = "";
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);
}
/* 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;
+ next_beat.beats = (*i).beat;
+ next_beat.bars = (*i).bar;
+ next_beat.ticks = tick;
+ pos = _session->tempo_map().frame_at_bbt (next_beat);
- 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)) {
+ 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) {
}
i_am_accented = false;
marks.push_back (mark);
- n++;
+
+ tick += skip;
+ ++t;
+ ++n;
}
}
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);
}
/* 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);
-
- pos = (*i).frame + frame_skip;
- accumulated_error = frame_skip_error;
-
- tick = skip;
+ t = 0;
+ while (tick < Timecode::BBT_Time::ticks_per_beat && (n < bbt_nmarks)) {
- for (t = 0; (tick < Timecode::BBT_Time::ticks_per_beat) && (n < bbt_nmarks) && (pos < next_beat_pos) ; pos += frame_skip, tick += skip, ++t) {
+ next_beat.beats = (*i).beat;
+ next_beat.bars = (*i).bar;
+ next_beat.ticks = tick;
+ pos = _session->tempo_map().frame_at_bbt (next_beat);
- 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 {
}
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) {
mark.style = ArdourCanvas::Ruler::Mark::Micro;
}
i_am_accented = false;
- n++;
+ marks.push_back (mark);
+
+ tick += skip;
+ ++t;
+ ++n;
}
}
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);
}
/* 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_at_bbt (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;
}
}
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) {
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) {
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) {
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);
But in this case, where the range defined by lower and uppper can vary
substantially (anything from 24hrs+ to several billion years)
- trying to decide which tick marks to show does require us to know
+ trying to decide which tick marks to show does require us to know
about the available width.
*/
marks.push_back (mark);
}
break;
-
+
case minsec_show_seconds:
for (n = 0; n < minsec_nmarks; pos += minsec_mark_interval, ++n) {
sample_to_clock_parts (pos, _session->frame_rate(), &hrs, &mins, &secs, &millisecs);
marks.push_back (mark);
}
break;
-
+
case minsec_show_many_hours:
for (n = 0; n < minsec_nmarks; ) {
sample_to_clock_parts (pos, _session->frame_rate(), &hrs, &mins, &secs, &millisecs);