Merge branch 'master' into scroll

This commit is contained in:
ferprojo 2025-08-09 12:01:35 -06:00 committed by GitHub
commit cfa19d9136
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
39 changed files with 1123 additions and 322 deletions

View file

@ -91,7 +91,7 @@ A few specific libraries are compiled statically (e.g. fluidsynth for use in plu
Mini Ardour inside Ardour to export audio-files from sessions. Mini Ardour inside Ardour to export audio-files from sessions.
It is a combination of AudioGrapher::Source and AudioGrapher::Sink classes that are chained together by ARDOUR::ExportGraphBuilder as shown in the ASCII art It is a combination of AudioGrapher::Source and AudioGrapher::Sink classes that are chained together by ARDOUR::ExportGraphBuilder as shown in the ASCII art
[Export Graph](https://git.ardour.org/ardour/ardour/src/commit/0df0e14e2309a00d433827fa34b87638b87f4fff/libs/ardour/export_graph_builder.cc#L73-L154). [Export Graph](https://github.com/Ardour/ardour/blob/56647acc25aa91ccf920e5ac21452bccf35b78e7/libs/ardour/export_graph_builder.cc#L73-L154).
* `libs/ardour/` * `libs/ardour/`

View file

@ -210,8 +210,8 @@ This mode provides many different operations on both regions and control points,
@edit|Editor/multi-duplicate| <@SECONDARY@>d|duplicate (multi) @edit|Editor/multi-duplicate| <@SECONDARY@>d|duplicate (multi)
@select|Editor/select-all-in-punch-range| <@TERTIARY@>d|select all in punch range @select|Editor/select-all-in-punch-range| <@TERTIARY@>d|select all in punch range
@vis|Editor/fit-selection| f|fit selection vertically @vis|Editor/fit-selection| f|fit selection vertically
@edit|Editing/toggle-follow-playhead| <@PRIMARY@>f|toggle playhead tracking @edit|EditorEditing/toggle-follow-playhead| <@PRIMARY@>f|toggle playhead tracking
@edit|Editor/toggle-stationary-playhead| <@TERTIARY@>f|toggle stationary playhead @edit|EditorEditing/toggle-stationary-playhead| <@TERTIARY@>f|toggle stationary playhead
@rop|Region/show-rhythm-ferret| <@SECONDARY@>f|show rhythm ferret window @rop|Region/show-rhythm-ferret| <@SECONDARY@>f|show rhythm ferret window
@wvis|Common/ToggleMaximalEditor| <@PRIMARY@><@SECONDARY@>f|maximise editor space @wvis|Common/ToggleMaximalEditor| <@PRIMARY@><@SECONDARY@>f|maximise editor space
@wvis|Common/ToggleMaximalMixer| <@PRIMARY@><@TERTIARY@>f|maximise mixer space @wvis|Common/ToggleMaximalMixer| <@PRIMARY@><@TERTIARY@>f|maximise mixer space

View file

@ -187,7 +187,7 @@
<menuitem action='ToggleAutoReturn'/> <menuitem action='ToggleAutoReturn'/>
<menuitem action='ToggleClick'/> <menuitem action='ToggleClick'/>
<menuitem action='EditorEditing/toggle-follow-playhead'/> <menuitem action='EditorEditing/toggle-follow-playhead'/>
<menuitem action='toggle-stationary-playhead'/> <menuitem action='EditorEditing/toggle-stationary-playhead'/>
<menuitem action='ToggleFollowEdits'/> <menuitem action='ToggleFollowEdits'/>
<menuitem action='ToggleExternalSync'/> <menuitem action='ToggleExternalSync'/>
<menuitem action='panic'/> <menuitem action='panic'/>

View file

@ -112,11 +112,9 @@ AudioClipEditor::AudioClipEditor (std::string const & name, bool with_transport)
load_bindings (); load_bindings ();
register_actions (); register_actions ();
build_canvas ();
build_grid_type_menu (); build_grid_type_menu ();
build_upper_toolbar (); build_upper_toolbar ();
build_canvas ();
build_lower_toolbar (); build_lower_toolbar ();
set_action_defaults (); set_action_defaults ();
@ -125,6 +123,8 @@ AudioClipEditor::AudioClipEditor (std::string const & name, bool with_transport)
void void
AudioClipEditor::load_shared_bindings () AudioClipEditor::load_shared_bindings ()
{ {
EC_LOCAL_TEMPO_SCOPE;
/* Full shared binding loading must have preceded this in some other EditingContext */ /* Full shared binding loading must have preceded this in some other EditingContext */
assert (!need_shared_actions); assert (!need_shared_actions);
@ -146,6 +146,8 @@ AudioClipEditor::load_shared_bindings ()
void void
AudioClipEditor::pack_inner (Gtk::Box& box) AudioClipEditor::pack_inner (Gtk::Box& box)
{ {
EC_LOCAL_TEMPO_SCOPE;
box.pack_start (snap_box, false, false); box.pack_start (snap_box, false, false);
box.pack_start (grid_box, false, false); box.pack_start (grid_box, false, false);
} }
@ -153,6 +155,8 @@ AudioClipEditor::pack_inner (Gtk::Box& box)
void void
AudioClipEditor::pack_outer (Gtk::Box& box) AudioClipEditor::pack_outer (Gtk::Box& box)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (with_transport_controls) { if (with_transport_controls) {
box.pack_start (play_box, false, false); box.pack_start (play_box, false, false);
} }
@ -164,12 +168,16 @@ AudioClipEditor::pack_outer (Gtk::Box& box)
void void
AudioClipEditor::build_lower_toolbar () AudioClipEditor::build_lower_toolbar ()
{ {
EC_LOCAL_TEMPO_SCOPE;
_toolbox.pack_start (*_canvas_hscrollbar, false, false); _toolbox.pack_start (*_canvas_hscrollbar, false, false);
} }
void void
AudioClipEditor::build_canvas () AudioClipEditor::build_canvas ()
{ {
EC_LOCAL_TEMPO_SCOPE;
_canvas.set_background_color (UIConfiguration::instance().color ("arrange base")); _canvas.set_background_color (UIConfiguration::instance().color ("arrange base"));
_canvas.signal_event().connect (sigc::mem_fun (*this, &CueEditor::canvas_pre_event), false); _canvas.signal_event().connect (sigc::mem_fun (*this, &CueEditor::canvas_pre_event), false);
_canvas.use_nsglview (UIConfiguration::instance().get_nsgl_view_mode () == NSGLHiRes); _canvas.use_nsglview (UIConfiguration::instance().get_nsgl_view_mode () == NSGLHiRes);
@ -213,14 +221,14 @@ AudioClipEditor::build_canvas ()
CANVAS_DEBUG_NAME (time_line_group, "audioclip time line group"); CANVAS_DEBUG_NAME (time_line_group, "audioclip time line group");
n_timebars = 0; n_timebars = 0;
minsec_ruler = new ArdourCanvas::Ruler (time_line_group, clip_metric, ArdourCanvas::Rect (0, 0, ArdourCanvas::COORD_MAX, timebar_height)); main_ruler = new ArdourCanvas::Ruler (time_line_group, clip_metric, ArdourCanvas::Rect (0, 0, ArdourCanvas::COORD_MAX, timebar_height));
// minsec_ruler->set_name ("audio clip editor ruler"); // main_ruler->set_name ("audio clip editor ruler");
minsec_ruler->set_font_description (UIConfiguration::instance ().get_SmallerFont ()); main_ruler->set_font_description (UIConfiguration::instance ().get_SmallerFont ());
minsec_ruler->set_fill_color (UIConfiguration::instance().color (X_("theme:bg1"))); main_ruler->set_fill_color (UIConfiguration::instance().color (X_("ruler base")));
minsec_ruler->set_outline_color (UIConfiguration::instance().color (X_("theme:contrasting less"))); main_ruler->set_outline_color (UIConfiguration::instance().color (X_("ruler text")));
n_timebars++; n_timebars++;
minsec_ruler->Event.connect (sigc::mem_fun (*this, &CueEditor::ruler_event)); main_ruler->Event.connect (sigc::mem_fun (*this, &CueEditor::ruler_event));
data_group = new ArdourCanvas::Container (hv_scroll_group); data_group = new ArdourCanvas::Container (hv_scroll_group);
CANVAS_DEBUG_NAME (data_group, "cue data group"); CANVAS_DEBUG_NAME (data_group, "cue data group");
@ -230,8 +238,6 @@ AudioClipEditor::build_canvas ()
cursor_scroll_group->set_position (ArdourCanvas::Duple (_timeline_origin, timebar_height * n_timebars)); cursor_scroll_group->set_position (ArdourCanvas::Duple (_timeline_origin, timebar_height * n_timebars));
h_scroll_group->set_position (Duple (_timeline_origin, 0.)); h_scroll_group->set_position (Duple (_timeline_origin, 0.));
_verbose_cursor = new VerboseCursor (*this);
// _playhead_cursor = new EditorCursor (*this, &Editor::canvas_playhead_cursor_event, X_("playhead")); // _playhead_cursor = new EditorCursor (*this, &Editor::canvas_playhead_cursor_event, X_("playhead"));
_playhead_cursor = new EditorCursor (*this, X_("playhead")); _playhead_cursor = new EditorCursor (*this, X_("playhead"));
_playhead_cursor->set_sensitive (UIConfiguration::instance().get_sensitize_playhead()); _playhead_cursor->set_sensitive (UIConfiguration::instance().get_sensitize_playhead());
@ -274,6 +280,8 @@ AudioClipEditor::build_canvas ()
AudioClipEditor::~AudioClipEditor () AudioClipEditor::~AudioClipEditor ()
{ {
EC_LOCAL_TEMPO_SCOPE;
drop_waves (); drop_waves ();
delete clip_metric; delete clip_metric;
} }
@ -281,6 +289,8 @@ AudioClipEditor::~AudioClipEditor ()
bool bool
AudioClipEditor::line_event_handler (GdkEvent* ev, ArdourCanvas::Line* l) AudioClipEditor::line_event_handler (GdkEvent* ev, ArdourCanvas::Line* l)
{ {
EC_LOCAL_TEMPO_SCOPE;
std::cerr << "event type " << Gtkmm2ext::event_type_string (ev->type) << " on line " << std::endl; std::cerr << "event type " << Gtkmm2ext::event_type_string (ev->type) << " on line " << std::endl;
switch (ev->type) { switch (ev->type) {
@ -317,12 +327,16 @@ AudioClipEditor::line_event_handler (GdkEvent* ev, ArdourCanvas::Line* l)
bool bool
AudioClipEditor::key_press (GdkEventKey* ev) AudioClipEditor::key_press (GdkEventKey* ev)
{ {
EC_LOCAL_TEMPO_SCOPE;
return false; return false;
} }
void void
AudioClipEditor::position_lines () AudioClipEditor::position_lines ()
{ {
EC_LOCAL_TEMPO_SCOPE;
if (!_region) { if (!_region) {
return; return;
} }
@ -362,6 +376,8 @@ AudioClipEditor::LineDrag::motion (GdkEventMotion* ev)
void void
AudioClipEditor::set_colors () AudioClipEditor::set_colors ()
{ {
EC_LOCAL_TEMPO_SCOPE;
_canvas.set_background_color (UIConfiguration::instance ().color (X_("theme:bg"))); _canvas.set_background_color (UIConfiguration::instance ().color (X_("theme:bg")));
start_line->set_outline_color (UIConfiguration::instance ().color (X_("theme:contrasting clock"))); start_line->set_outline_color (UIConfiguration::instance ().color (X_("theme:contrasting clock")));
@ -374,6 +390,8 @@ AudioClipEditor::set_colors ()
void void
AudioClipEditor::drop_waves () AudioClipEditor::drop_waves ()
{ {
EC_LOCAL_TEMPO_SCOPE;
for (auto& wave : waves) { for (auto& wave : waves) {
delete wave; delete wave;
} }
@ -384,6 +402,8 @@ AudioClipEditor::drop_waves ()
void void
AudioClipEditor::set_trigger (TriggerReference& tr) AudioClipEditor::set_trigger (TriggerReference& tr)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (tr == ref) { if (tr == ref) {
return; return;
} }
@ -391,13 +411,15 @@ AudioClipEditor::set_trigger (TriggerReference& tr)
CueEditor::set_trigger (tr); CueEditor::set_trigger (tr);
rec_box.show (); rec_box.show ();
minsec_ruler->show (); main_ruler->show ();
minsec_ruler->set_range (0, pixel_to_sample (_visible_canvas_width - 2.)); main_ruler->set_range (0, pixel_to_sample (_visible_canvas_width - 2.));
} }
void void
AudioClipEditor::set_region (std::shared_ptr<Region> region) AudioClipEditor::set_region (std::shared_ptr<Region> region)
{ {
EC_LOCAL_TEMPO_SCOPE;
CueEditor::set_region (region); CueEditor::set_region (region);
if (_visible_pending_region) { if (_visible_pending_region) {
@ -425,7 +447,7 @@ AudioClipEditor::set_region (std::shared_ptr<Region> region)
delete clip_metric; delete clip_metric;
clip_metric = new ClipBBTMetric (ref); clip_metric = new ClipBBTMetric (ref);
minsec_ruler->set_metric (clip_metric); main_ruler->set_metric (clip_metric);
uint32_t n_chans = r->n_channels (); uint32_t n_chans = r->n_channels ();
samplecnt_t len; samplecnt_t len;
@ -474,6 +496,8 @@ AudioClipEditor::set_region (std::shared_ptr<Region> region)
void void
AudioClipEditor::canvas_allocate (Gtk::Allocation& alloc) AudioClipEditor::canvas_allocate (Gtk::Allocation& alloc)
{ {
EC_LOCAL_TEMPO_SCOPE;
_canvas.size_allocate (alloc); _canvas.size_allocate (alloc);
_visible_canvas_width = alloc.get_width(); _visible_canvas_width = alloc.get_width();
@ -482,7 +506,7 @@ AudioClipEditor::canvas_allocate (Gtk::Allocation& alloc)
/* no track header here, "track width" is the whole canvas */ /* no track header here, "track width" is the whole canvas */
_track_canvas_width = _visible_canvas_width; _track_canvas_width = _visible_canvas_width;
minsec_ruler->set (ArdourCanvas::Rect (2, 2, alloc.get_width() - 4, timebar_height)); main_ruler->set (ArdourCanvas::Rect (2, 2, alloc.get_width() - 4, timebar_height));
position_lines (); position_lines ();
@ -500,6 +524,8 @@ AudioClipEditor::canvas_allocate (Gtk::Allocation& alloc)
void void
AudioClipEditor::set_spp_from_length (samplecnt_t len) AudioClipEditor::set_spp_from_length (samplecnt_t len)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (_visible_canvas_width) { if (_visible_canvas_width) {
set_samples_per_pixel (floor (len / _visible_canvas_width)); set_samples_per_pixel (floor (len / _visible_canvas_width));
} }
@ -508,6 +534,8 @@ AudioClipEditor::set_spp_from_length (samplecnt_t len)
void void
AudioClipEditor::set_wave_heights () AudioClipEditor::set_wave_heights ()
{ {
EC_LOCAL_TEMPO_SCOPE;
if (waves.empty ()) { if (waves.empty ()) {
return; return;
} }
@ -526,6 +554,8 @@ AudioClipEditor::set_wave_heights ()
void void
AudioClipEditor::set_waveform_colors () AudioClipEditor::set_waveform_colors ()
{ {
EC_LOCAL_TEMPO_SCOPE;
Gtkmm2ext::Color clip = UIConfiguration::instance ().color ("clipped waveform"); Gtkmm2ext::Color clip = UIConfiguration::instance ().color ("clipped waveform");
Gtkmm2ext::Color zero = UIConfiguration::instance ().color ("zero line"); Gtkmm2ext::Color zero = UIConfiguration::instance ().color ("zero line");
Gtkmm2ext::Color fill = UIConfiguration::instance ().color ("waveform fill"); Gtkmm2ext::Color fill = UIConfiguration::instance ().color ("waveform fill");
@ -542,17 +572,23 @@ AudioClipEditor::set_waveform_colors ()
Gtk::Widget& Gtk::Widget&
AudioClipEditor::contents () AudioClipEditor::contents ()
{ {
EC_LOCAL_TEMPO_SCOPE;
return _contents; return _contents;
} }
void void
AudioClipEditor::region_changed (const PBD::PropertyChange& what_changed) AudioClipEditor::region_changed (const PBD::PropertyChange& what_changed)
{ {
EC_LOCAL_TEMPO_SCOPE;
} }
void void
AudioClipEditor::set_samples_per_pixel (samplecnt_t spp) AudioClipEditor::set_samples_per_pixel (samplecnt_t spp)
{ {
EC_LOCAL_TEMPO_SCOPE;
CueEditor::set_samples_per_pixel (spp); CueEditor::set_samples_per_pixel (spp);
clip_metric->units_per_pixel = samples_per_pixel; clip_metric->units_per_pixel = samples_per_pixel;
@ -572,12 +608,16 @@ AudioClipEditor::set_samples_per_pixel (samplecnt_t spp)
samplecnt_t samplecnt_t
AudioClipEditor::current_page_samples() const AudioClipEditor::current_page_samples() const
{ {
EC_LOCAL_TEMPO_SCOPE;
return (samplecnt_t) _track_canvas_width * samples_per_pixel; return (samplecnt_t) _track_canvas_width * samples_per_pixel;
} }
bool bool
AudioClipEditor::canvas_enter_leave (GdkEventCrossing* ev) AudioClipEditor::canvas_enter_leave (GdkEventCrossing* ev)
{ {
EC_LOCAL_TEMPO_SCOPE;
switch (ev->type) { switch (ev->type) {
case GDK_ENTER_NOTIFY: case GDK_ENTER_NOTIFY:
if (ev->detail != GDK_NOTIFY_INFERIOR) { if (ev->detail != GDK_NOTIFY_INFERIOR) {
@ -602,26 +642,36 @@ AudioClipEditor::canvas_enter_leave (GdkEventCrossing* ev)
void void
AudioClipEditor::begin_write () AudioClipEditor::begin_write ()
{ {
EC_LOCAL_TEMPO_SCOPE;
} }
void void
AudioClipEditor::end_write () AudioClipEditor::end_write ()
{ {
EC_LOCAL_TEMPO_SCOPE;
} }
void void
AudioClipEditor::show_count_in (std::string const &) AudioClipEditor::show_count_in (std::string const &)
{ {
EC_LOCAL_TEMPO_SCOPE;
} }
void void
AudioClipEditor::hide_count_in () AudioClipEditor::hide_count_in ()
{ {
EC_LOCAL_TEMPO_SCOPE;
} }
void void
AudioClipEditor::maybe_update () AudioClipEditor::maybe_update ()
{ {
EC_LOCAL_TEMPO_SCOPE;
ARDOUR::TriggerPtr playing_trigger; ARDOUR::TriggerPtr playing_trigger;
if (ref.trigger()) { if (ref.trigger()) {
@ -679,6 +729,8 @@ AudioClipEditor::maybe_update ()
void void
AudioClipEditor::unset (bool trigger_too) AudioClipEditor::unset (bool trigger_too)
{ {
EC_LOCAL_TEMPO_SCOPE;
drop_waves (); drop_waves ();
CueEditor::unset (trigger_too); CueEditor::unset (trigger_too);
} }

View file

@ -134,7 +134,7 @@ public:
ArdourCanvas::Line* end_line; ArdourCanvas::Line* end_line;
ArdourCanvas::Line* loop_line; ArdourCanvas::Line* loop_line;
ArdourCanvas::Container* ruler_container; ArdourCanvas::Container* ruler_container;
ArdourCanvas::Ruler* minsec_ruler; ArdourCanvas::Ruler* main_ruler;
class ClipBBTMetric : public ArdourCanvas::Ruler::Metric class ClipBBTMetric : public ArdourCanvas::Ruler::Metric
{ {

View file

@ -71,11 +71,15 @@ CueEditor::~CueEditor ()
void void
CueEditor::set_snapped_cursor_position (Temporal::timepos_t const & pos) CueEditor::set_snapped_cursor_position (Temporal::timepos_t const & pos)
{ {
EC_LOCAL_TEMPO_SCOPE;
} }
std::vector<MidiRegionView*> std::vector<MidiRegionView*>
CueEditor::filter_to_unique_midi_region_views (RegionSelection const & ms) const CueEditor::filter_to_unique_midi_region_views (RegionSelection const & ms) const
{ {
EC_LOCAL_TEMPO_SCOPE;
std::vector<MidiRegionView*> mrv; std::vector<MidiRegionView*> mrv;
return mrv; return mrv;
} }
@ -83,17 +87,23 @@ CueEditor::filter_to_unique_midi_region_views (RegionSelection const & ms) const
void void
CueEditor::get_regionviews_by_id (PBD::ID const id, RegionSelection & regions) const CueEditor::get_regionviews_by_id (PBD::ID const id, RegionSelection & regions) const
{ {
EC_LOCAL_TEMPO_SCOPE;
} }
StripableTimeAxisView* StripableTimeAxisView*
CueEditor::get_stripable_time_axis_by_id (const PBD::ID& id) const CueEditor::get_stripable_time_axis_by_id (const PBD::ID& id) const
{ {
EC_LOCAL_TEMPO_SCOPE;
return nullptr; return nullptr;
} }
TrackViewList TrackViewList
CueEditor::axis_views_from_routes (std::shared_ptr<ARDOUR::RouteList>) const CueEditor::axis_views_from_routes (std::shared_ptr<ARDOUR::RouteList>) const
{ {
EC_LOCAL_TEMPO_SCOPE;
TrackViewList tvl; TrackViewList tvl;
return tvl; return tvl;
} }
@ -101,42 +111,56 @@ CueEditor::axis_views_from_routes (std::shared_ptr<ARDOUR::RouteList>) const
ARDOUR::Location* ARDOUR::Location*
CueEditor::find_location_from_marker (ArdourMarker*, bool&) const CueEditor::find_location_from_marker (ArdourMarker*, bool&) const
{ {
EC_LOCAL_TEMPO_SCOPE;
return nullptr; return nullptr;
} }
ArdourMarker* ArdourMarker*
CueEditor::find_marker_from_location_id (PBD::ID const&, bool) const CueEditor::find_marker_from_location_id (PBD::ID const&, bool) const
{ {
EC_LOCAL_TEMPO_SCOPE;
return nullptr; return nullptr;
} }
TempoMarker* TempoMarker*
CueEditor::find_marker_for_tempo (Temporal::TempoPoint const &) CueEditor::find_marker_for_tempo (Temporal::TempoPoint const &)
{ {
EC_LOCAL_TEMPO_SCOPE;
return nullptr; return nullptr;
} }
MeterMarker* MeterMarker*
CueEditor::find_marker_for_meter (Temporal::MeterPoint const &) CueEditor::find_marker_for_meter (Temporal::MeterPoint const &)
{ {
EC_LOCAL_TEMPO_SCOPE;
return nullptr; return nullptr;
} }
void void
CueEditor::redisplay_grid (bool immediate_redraw) CueEditor::redisplay_grid (bool immediate_redraw)
{ {
EC_LOCAL_TEMPO_SCOPE;
update_grid (); update_grid ();
} }
Temporal::timecnt_t Temporal::timecnt_t
CueEditor::get_nudge_distance (Temporal::timepos_t const & pos, Temporal::timecnt_t& next) const CueEditor::get_nudge_distance (Temporal::timepos_t const & pos, Temporal::timecnt_t& next) const
{ {
EC_LOCAL_TEMPO_SCOPE;
return Temporal::timecnt_t (Temporal::AudioTime); return Temporal::timecnt_t (Temporal::AudioTime);
} }
void void
CueEditor::instant_save() CueEditor::instant_save()
{ {
EC_LOCAL_TEMPO_SCOPE;
if (!_region) { if (!_region) {
return; return;
} }
@ -158,42 +182,58 @@ CueEditor::instant_save()
void void
CueEditor::begin_selection_op_history () CueEditor::begin_selection_op_history ()
{ {
EC_LOCAL_TEMPO_SCOPE;
} }
void void
CueEditor::begin_reversible_selection_op (std::string cmd_name) CueEditor::begin_reversible_selection_op (std::string cmd_name)
{ {
EC_LOCAL_TEMPO_SCOPE;
} }
void void
CueEditor::commit_reversible_selection_op () CueEditor::commit_reversible_selection_op ()
{ {
EC_LOCAL_TEMPO_SCOPE;
} }
void void
CueEditor::abort_reversible_selection_op () CueEditor::abort_reversible_selection_op ()
{ {
EC_LOCAL_TEMPO_SCOPE;
} }
void void
CueEditor::undo_selection_op () CueEditor::undo_selection_op ()
{ {
EC_LOCAL_TEMPO_SCOPE;
} }
void void
CueEditor::redo_selection_op () CueEditor::redo_selection_op ()
{ {
EC_LOCAL_TEMPO_SCOPE;
} }
double double
CueEditor::get_y_origin () const CueEditor::get_y_origin () const
{ {
EC_LOCAL_TEMPO_SCOPE;
return 0.; return 0.;
} }
void void
CueEditor::set_zoom_focus (Editing::ZoomFocus zf) CueEditor::set_zoom_focus (Editing::ZoomFocus zf)
{ {
EC_LOCAL_TEMPO_SCOPE;
using namespace Editing; using namespace Editing;
/* We don't allow playhead for zoom focus here */ /* We don't allow playhead for zoom focus here */
@ -208,6 +248,8 @@ CueEditor::set_zoom_focus (Editing::ZoomFocus zf)
void void
CueEditor::set_samples_per_pixel (samplecnt_t n) CueEditor::set_samples_per_pixel (samplecnt_t n)
{ {
EC_LOCAL_TEMPO_SCOPE;
samples_per_pixel = n; samples_per_pixel = n;
ZoomChanged(); /* EMIT SIGNAL */ ZoomChanged(); /* EMIT SIGNAL */
} }
@ -215,12 +257,16 @@ CueEditor::set_samples_per_pixel (samplecnt_t n)
samplecnt_t samplecnt_t
CueEditor::get_current_zoom () const CueEditor::get_current_zoom () const
{ {
EC_LOCAL_TEMPO_SCOPE;
return samples_per_pixel; return samples_per_pixel;
} }
void void
CueEditor::reposition_and_zoom (samplepos_t pos, double spp) CueEditor::reposition_and_zoom (samplepos_t pos, double spp)
{ {
EC_LOCAL_TEMPO_SCOPE;
pending_visual_change.add (VisualChange::ZoomLevel); pending_visual_change.add (VisualChange::ZoomLevel);
pending_visual_change.samples_per_pixel = spp; pending_visual_change.samples_per_pixel = spp;
@ -233,36 +279,30 @@ CueEditor::reposition_and_zoom (samplepos_t pos, double spp)
void void
CueEditor::set_mouse_mode (Editing::MouseMode, bool force) CueEditor::set_mouse_mode (Editing::MouseMode, bool force)
{ {
EC_LOCAL_TEMPO_SCOPE;
} }
void void
CueEditor::step_mouse_mode (bool next) CueEditor::step_mouse_mode (bool next)
{ {
EC_LOCAL_TEMPO_SCOPE;
} }
Gdk::Cursor* Gdk::Cursor*
CueEditor::get_canvas_cursor () const CueEditor::get_canvas_cursor () const
{ {
EC_LOCAL_TEMPO_SCOPE;
return nullptr; return nullptr;
} }
std::shared_ptr<Temporal::TempoMap const>
CueEditor::start_local_tempo_map (std::shared_ptr<Temporal::TempoMap> map)
{
std::shared_ptr<Temporal::TempoMap const> tmp = Temporal::TempoMap::use();
Temporal::TempoMap::set (map);
return tmp;
}
void
CueEditor::end_local_tempo_map (std::shared_ptr<Temporal::TempoMap const> map)
{
Temporal::TempoMap::set (map);
}
void void
CueEditor::do_undo (uint32_t n) CueEditor::do_undo (uint32_t n)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (_drags->active ()) { if (_drags->active ()) {
_drags->abort (); _drags->abort ();
} }
@ -273,6 +313,8 @@ CueEditor::do_undo (uint32_t n)
void void
CueEditor::do_redo (uint32_t n) CueEditor::do_redo (uint32_t n)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (_drags->active ()) { if (_drags->active ()) {
_drags->abort (); _drags->abort ();
} }
@ -283,12 +325,16 @@ CueEditor::do_redo (uint32_t n)
void void
CueEditor::history_changed () CueEditor::history_changed ()
{ {
EC_LOCAL_TEMPO_SCOPE;
update_undo_redo_actions (_history); update_undo_redo_actions (_history);
} }
Temporal::timepos_t Temporal::timepos_t
CueEditor::_get_preferred_edit_position (Editing::EditIgnoreOption ignore, bool from_context_menu, bool from_outside_canvas) CueEditor::_get_preferred_edit_position (Editing::EditIgnoreOption ignore, bool from_context_menu, bool from_outside_canvas)
{ {
EC_LOCAL_TEMPO_SCOPE;
samplepos_t where; samplepos_t where;
bool in_track_canvas = false; bool in_track_canvas = false;
@ -302,6 +348,8 @@ CueEditor::_get_preferred_edit_position (Editing::EditIgnoreOption ignore, bool
void void
CueEditor::build_upper_toolbar () CueEditor::build_upper_toolbar ()
{ {
EC_LOCAL_TEMPO_SCOPE;
using namespace Gtk::Menu_Helpers; using namespace Gtk::Menu_Helpers;
Gtk::HBox* mode_box = manage(new Gtk::HBox); Gtk::HBox* mode_box = manage(new Gtk::HBox);
@ -423,6 +471,8 @@ CueEditor::build_upper_toolbar ()
void void
CueEditor::build_zoom_focus_menu () CueEditor::build_zoom_focus_menu ()
{ {
EC_LOCAL_TEMPO_SCOPE;
using namespace Gtk::Menu_Helpers; using namespace Gtk::Menu_Helpers;
using namespace Editing; using namespace Editing;
@ -436,6 +486,8 @@ CueEditor::build_zoom_focus_menu ()
bool bool
CueEditor::bang_button_press (GdkEventButton* ev) CueEditor::bang_button_press (GdkEventButton* ev)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (!ref.trigger()) { if (!ref.trigger()) {
return true; return true;
} }
@ -448,6 +500,8 @@ CueEditor::bang_button_press (GdkEventButton* ev)
bool bool
CueEditor::play_button_press (GdkEventButton* ev) CueEditor::play_button_press (GdkEventButton* ev)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (_session && _region) { if (_session && _region) {
_session->request_locate (_region->position().samples()); _session->request_locate (_region->position().samples());
_session->request_roll (); _session->request_roll ();
@ -459,6 +513,8 @@ CueEditor::play_button_press (GdkEventButton* ev)
bool bool
CueEditor::loop_button_press (GdkEventButton* ev) CueEditor::loop_button_press (GdkEventButton* ev)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (!_region) { if (!_region) {
return true; return true;
} }
@ -476,6 +532,8 @@ CueEditor::loop_button_press (GdkEventButton* ev)
bool bool
CueEditor::solo_button_press (GdkEventButton* ev) CueEditor::solo_button_press (GdkEventButton* ev)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (!_track) { if (!_track) {
return true; return true;
} }
@ -488,6 +546,8 @@ CueEditor::solo_button_press (GdkEventButton* ev)
bool bool
CueEditor::rec_button_press (GdkEventButton* ev) CueEditor::rec_button_press (GdkEventButton* ev)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (ev->button != 1) { if (ev->button != 1) {
return false; return false;
} }
@ -510,6 +570,8 @@ CueEditor::rec_button_press (GdkEventButton* ev)
void void
CueEditor::blink_rec_enable (bool onoff) CueEditor::blink_rec_enable (bool onoff)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (onoff) { if (onoff) {
rec_enable_button.set_active_state (Gtkmm2ext::ExplicitActive); rec_enable_button.set_active_state (Gtkmm2ext::ExplicitActive);
} else { } else {
@ -520,6 +582,8 @@ CueEditor::blink_rec_enable (bool onoff)
void void
CueEditor::trigger_arm_change () CueEditor::trigger_arm_change ()
{ {
EC_LOCAL_TEMPO_SCOPE;
if (!ref.trigger()) { if (!ref.trigger()) {
return; return;
} }
@ -536,6 +600,8 @@ CueEditor::trigger_arm_change ()
void void
CueEditor::rec_enable_change () CueEditor::rec_enable_change ()
{ {
EC_LOCAL_TEMPO_SCOPE;
if (!ref.box()) { if (!ref.box()) {
return; return;
} }
@ -568,12 +634,16 @@ CueEditor::rec_enable_change ()
void void
CueEditor::set_recording_length (Temporal::BBT_Offset dur) CueEditor::set_recording_length (Temporal::BBT_Offset dur)
{ {
EC_LOCAL_TEMPO_SCOPE;
rec_length = dur; rec_length = dur;
} }
void void
CueEditor::scrolled () CueEditor::scrolled ()
{ {
EC_LOCAL_TEMPO_SCOPE;
pending_visual_change.add (VisualChange::TimeOrigin); pending_visual_change.add (VisualChange::TimeOrigin);
pending_visual_change.time_origin = horizontal_adjustment.get_value() * samples_per_pixel; pending_visual_change.time_origin = horizontal_adjustment.get_value() * samples_per_pixel;
ensure_visual_change_idle_handler (); ensure_visual_change_idle_handler ();
@ -582,6 +652,8 @@ CueEditor::scrolled ()
bool bool
CueEditor::canvas_pre_event (GdkEvent* ev) CueEditor::canvas_pre_event (GdkEvent* ev)
{ {
EC_LOCAL_TEMPO_SCOPE;
switch (ev->type) { switch (ev->type) {
case GDK_ENTER_NOTIFY: case GDK_ENTER_NOTIFY:
case GDK_LEAVE_NOTIFY: case GDK_LEAVE_NOTIFY:
@ -599,6 +671,8 @@ CueEditor::canvas_pre_event (GdkEvent* ev)
bool bool
CueEditor::autoscroll_active () const CueEditor::autoscroll_active () const
{ {
EC_LOCAL_TEMPO_SCOPE;
return autoscroll_connection.connected (); return autoscroll_connection.connected ();
} }
@ -610,6 +684,8 @@ CueEditor::autoscroll_active () const
void void
CueEditor::maybe_autoscroll (bool allow_horiz, bool allow_vert, bool from_headers) CueEditor::maybe_autoscroll (bool allow_horiz, bool allow_vert, bool from_headers)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (!UIConfiguration::instance().get_autoscroll_editor () || autoscroll_active ()) { if (!UIConfiguration::instance().get_autoscroll_editor () || autoscroll_active ()) {
return; return;
} }
@ -681,6 +757,8 @@ CueEditor::maybe_autoscroll (bool allow_horiz, bool allow_vert, bool from_header
bool bool
CueEditor::autoscroll_canvas () CueEditor::autoscroll_canvas ()
{ {
EC_LOCAL_TEMPO_SCOPE;
using std::max; using std::max;
using std::min; using std::min;
int x, y; int x, y;
@ -881,6 +959,8 @@ CueEditor::autoscroll_canvas ()
void void
CueEditor::start_canvas_autoscroll (bool allow_horiz, bool allow_vert, const ArdourCanvas::Rect& boundary) CueEditor::start_canvas_autoscroll (bool allow_horiz, bool allow_vert, const ArdourCanvas::Rect& boundary)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (!_session) { if (!_session) {
return; return;
} }
@ -904,6 +984,8 @@ CueEditor::start_canvas_autoscroll (bool allow_horiz, bool allow_vert, const Ard
void void
CueEditor::stop_canvas_autoscroll () CueEditor::stop_canvas_autoscroll ()
{ {
EC_LOCAL_TEMPO_SCOPE;
autoscroll_connection.disconnect (); autoscroll_connection.disconnect ();
autoscroll_cnt = 0; autoscroll_cnt = 0;
} }
@ -911,6 +993,8 @@ CueEditor::stop_canvas_autoscroll ()
void void
CueEditor::visual_changer (const VisualChange& vc) CueEditor::visual_changer (const VisualChange& vc)
{ {
EC_LOCAL_TEMPO_SCOPE;
/** /**
* Changed first so the correct horizontal canvas position is calculated in * Changed first so the correct horizontal canvas position is calculated in
* EditingContext::set_horizontal_position * EditingContext::set_horizontal_position
@ -951,6 +1035,8 @@ CueEditor::visual_changer (const VisualChange& vc)
void void
CueEditor::catch_pending_show_region () CueEditor::catch_pending_show_region ()
{ {
EC_LOCAL_TEMPO_SCOPE;
if (_visible_pending_region) { if (_visible_pending_region) {
std::shared_ptr<Region> r (_visible_pending_region); std::shared_ptr<Region> r (_visible_pending_region);
_visible_pending_region.reset (); _visible_pending_region.reset ();
@ -961,6 +1047,8 @@ CueEditor::catch_pending_show_region ()
RegionSelection RegionSelection
CueEditor::region_selection() CueEditor::region_selection()
{ {
EC_LOCAL_TEMPO_SCOPE;
RegionSelection rs; RegionSelection rs;
/* there is never any region-level selection in a pianoroll */ /* there is never any region-level selection in a pianoroll */
return rs; return rs;
@ -969,6 +1057,8 @@ CueEditor::region_selection()
void void
CueEditor::mouse_mode_chosen (Editing::MouseMode m) CueEditor::mouse_mode_chosen (Editing::MouseMode m)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (!mouse_mode_actions[m]->get_active()) { if (!mouse_mode_actions[m]->get_active()) {
/* this was just the notification that the old mode has been /* this was just the notification that the old mode has been
* left. we'll get called again with the new mode active in a * left. we'll get called again with the new mode active in a
@ -989,6 +1079,8 @@ CueEditor::mouse_mode_chosen (Editing::MouseMode m)
std::pair<Temporal::timepos_t,Temporal::timepos_t> std::pair<Temporal::timepos_t,Temporal::timepos_t>
CueEditor::max_zoom_extent() const CueEditor::max_zoom_extent() const
{ {
EC_LOCAL_TEMPO_SCOPE;
if (_region) { if (_region) {
Temporal::Beats len; Temporal::Beats len;
@ -1011,6 +1103,8 @@ CueEditor::max_zoom_extent() const
void void
CueEditor::zoom_to_show (Temporal::timecnt_t const & duration) CueEditor::zoom_to_show (Temporal::timecnt_t const & duration)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (!_track_canvas_width) { if (!_track_canvas_width) {
zoom_in_allocate = true; zoom_in_allocate = true;
return; return;
@ -1022,6 +1116,8 @@ CueEditor::zoom_to_show (Temporal::timecnt_t const & duration)
void void
CueEditor::full_zoom_clicked() CueEditor::full_zoom_clicked()
{ {
EC_LOCAL_TEMPO_SCOPE;
/* XXXX NEED LOCAL TEMPO MAP */ /* XXXX NEED LOCAL TEMPO MAP */
std::pair<Temporal::timepos_t,Temporal::timepos_t> dur (max_zoom_extent()); std::pair<Temporal::timepos_t,Temporal::timepos_t> dur (max_zoom_extent());
@ -1032,12 +1128,16 @@ CueEditor::full_zoom_clicked()
void void
CueEditor::set_show_source (bool yn) CueEditor::set_show_source (bool yn)
{ {
EC_LOCAL_TEMPO_SCOPE;
show_source = yn; show_source = yn;
} }
void void
CueEditor::update_solo_display () CueEditor::update_solo_display ()
{ {
EC_LOCAL_TEMPO_SCOPE;
if (_track->solo_control()->get_value()) { if (_track->solo_control()->get_value()) {
solo_button.set_active_state (Gtkmm2ext::ExplicitActive); solo_button.set_active_state (Gtkmm2ext::ExplicitActive);
} else { } else {
@ -1048,6 +1148,8 @@ CueEditor::update_solo_display ()
void void
CueEditor::set_track (std::shared_ptr<Track> t) CueEditor::set_track (std::shared_ptr<Track> t)
{ {
EC_LOCAL_TEMPO_SCOPE;
_track = t; _track = t;
_track->solo_control()->Changed.connect (object_connections, invalidator (*this), std::bind (&CueEditor::update_solo_display, this), gui_context()); _track->solo_control()->Changed.connect (object_connections, invalidator (*this), std::bind (&CueEditor::update_solo_display, this), gui_context());
update_solo_display (); update_solo_display ();
@ -1056,6 +1158,8 @@ CueEditor::set_track (std::shared_ptr<Track> t)
void void
CueEditor::set_region (std::shared_ptr<Region> r) CueEditor::set_region (std::shared_ptr<Region> r)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (r == _region) { if (r == _region) {
return; return;
} }
@ -1064,6 +1168,9 @@ CueEditor::set_region (std::shared_ptr<Region> r)
_region = r; _region = r;
std::shared_ptr<TempoMap> tmap (new TempoMap (_region->tempo(), _region->meter()));
start_local_tempo_map (tmap);
if (!get_canvas()->is_visible()) { if (!get_canvas()->is_visible()) {
_visible_pending_region = r; _visible_pending_region = r;
} else { } else {
@ -1074,6 +1181,8 @@ CueEditor::set_region (std::shared_ptr<Region> r)
void void
CueEditor::maybe_set_from_rsu () CueEditor::maybe_set_from_rsu ()
{ {
EC_LOCAL_TEMPO_SCOPE;
RegionUISettingsManager::iterator rsu = ARDOUR_UI::instance()->region_ui_settings_manager.find (_region->id()); RegionUISettingsManager::iterator rsu = ARDOUR_UI::instance()->region_ui_settings_manager.find (_region->id());
if (rsu != ARDOUR_UI::instance()->region_ui_settings_manager.end()) { if (rsu != ARDOUR_UI::instance()->region_ui_settings_manager.end()) {
set_from_rsu (rsu->second); set_from_rsu (rsu->second);
@ -1083,6 +1192,8 @@ CueEditor::maybe_set_from_rsu ()
void void
CueEditor::set_from_rsu (RegionUISettings& rsu) CueEditor::set_from_rsu (RegionUISettings& rsu)
{ {
EC_LOCAL_TEMPO_SCOPE;
follow_playhead_action->set_active (rsu.follow_playhead); follow_playhead_action->set_active (rsu.follow_playhead);
/* XXXX play selection */ /* XXXX play selection */
@ -1101,6 +1212,8 @@ CueEditor::set_from_rsu (RegionUISettings& rsu)
void void
CueEditor::set_trigger (TriggerReference& tref) CueEditor::set_trigger (TriggerReference& tref)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (tref == ref) { if (tref == ref) {
return; return;
} }
@ -1122,6 +1235,8 @@ CueEditor::set_trigger (TriggerReference& tref)
void void
CueEditor::ruler_locate (GdkEventButton* ev) CueEditor::ruler_locate (GdkEventButton* ev)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (!_session) { if (!_session) {
return; return;
} }
@ -1143,6 +1258,8 @@ CueEditor::ruler_locate (GdkEventButton* ev)
void void
CueEditor::maybe_set_count_in () CueEditor::maybe_set_count_in ()
{ {
EC_LOCAL_TEMPO_SCOPE;
if (!ref.box()) { if (!ref.box()) {
std::cerr << "msci no box\n"; std::cerr << "msci no box\n";
return; return;
@ -1179,6 +1296,8 @@ CueEditor::maybe_set_count_in ()
void void
CueEditor::count_in (Temporal::timepos_t audible, unsigned int clock_interval_msecs) CueEditor::count_in (Temporal::timepos_t audible, unsigned int clock_interval_msecs)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (!_session) { if (!_session) {
return; return;
} }
@ -1224,6 +1343,8 @@ CueEditor::count_in (Temporal::timepos_t audible, unsigned int clock_interval_ms
bool bool
CueEditor::ruler_event (GdkEvent* ev) CueEditor::ruler_event (GdkEvent* ev)
{ {
EC_LOCAL_TEMPO_SCOPE;
switch (ev->type) { switch (ev->type) {
case GDK_BUTTON_RELEASE: case GDK_BUTTON_RELEASE:
if (ev->button.button == 1) { if (ev->button.button == 1) {
@ -1240,6 +1361,8 @@ CueEditor::ruler_event (GdkEvent* ev)
void void
CueEditor::data_captured (samplecnt_t total_duration) CueEditor::data_captured (samplecnt_t total_duration)
{ {
EC_LOCAL_TEMPO_SCOPE;
data_capture_duration = total_duration; data_capture_duration = total_duration;
if (!idle_update_queued.exchange (1)) { if (!idle_update_queued.exchange (1)) {
@ -1250,6 +1373,8 @@ CueEditor::data_captured (samplecnt_t total_duration)
bool bool
CueEditor::idle_data_captured () CueEditor::idle_data_captured ()
{ {
EC_LOCAL_TEMPO_SCOPE;
if (!ref.box()) { if (!ref.box()) {
return false; return false;
} }
@ -1274,6 +1399,7 @@ CueEditor::idle_data_captured ()
void void
CueEditor::unset (bool trigger_too) CueEditor::unset (bool trigger_too)
{ {
end_local_tempo_map ();
_history.clear (); _history.clear ();
history_connection.disconnect(); history_connection.disconnect();
_update_connection.disconnect(); _update_connection.disconnect();
@ -1293,6 +1419,8 @@ CueEditor::unset (bool trigger_too)
void void
CueEditor::session_going_away () CueEditor::session_going_away ()
{ {
EC_LOCAL_TEMPO_SCOPE;
EditingContext::session_going_away (); EditingContext::session_going_away ();
unset (true); unset (true);
} }
@ -1300,6 +1428,8 @@ CueEditor::session_going_away ()
void void
CueEditor::load_bindings () CueEditor::load_bindings ()
{ {
EC_LOCAL_TEMPO_SCOPE;
load_shared_bindings (); load_shared_bindings ();
for (auto & b : bindings) { for (auto & b : bindings) {
b->associate (); b->associate ();
@ -1310,6 +1440,8 @@ CueEditor::load_bindings ()
void void
CueEditor::register_actions () CueEditor::register_actions ()
{ {
EC_LOCAL_TEMPO_SCOPE;
editor_actions = ActionManager::create_action_group (own_bindings, editor_name()); editor_actions = ActionManager::create_action_group (own_bindings, editor_name());
bind_mouse_mode_buttons (); bind_mouse_mode_buttons ();
} }
@ -1317,12 +1449,16 @@ CueEditor::register_actions ()
ArdourCanvas::GtkCanvasViewport* ArdourCanvas::GtkCanvasViewport*
CueEditor::get_canvas_viewport() const CueEditor::get_canvas_viewport() const
{ {
EC_LOCAL_TEMPO_SCOPE;
return const_cast<ArdourCanvas::GtkCanvasViewport*>(&_canvas_viewport); return const_cast<ArdourCanvas::GtkCanvasViewport*>(&_canvas_viewport);
} }
ArdourCanvas::GtkCanvas* ArdourCanvas::GtkCanvas*
CueEditor::get_canvas() const CueEditor::get_canvas() const
{ {
EC_LOCAL_TEMPO_SCOPE;
return &_canvas; return &_canvas;
} }
@ -1330,6 +1466,8 @@ CueEditor::get_canvas() const
int int
CueEditor::set_state (XMLNode const & node, int version) CueEditor::set_state (XMLNode const & node, int version)
{ {
EC_LOCAL_TEMPO_SCOPE;
set_common_editing_state (node); set_common_editing_state (node);
return 0; return 0;
} }
@ -1337,6 +1475,8 @@ CueEditor::set_state (XMLNode const & node, int version)
XMLNode& XMLNode&
CueEditor::get_state () const CueEditor::get_state () const
{ {
EC_LOCAL_TEMPO_SCOPE;
XMLNode* node (new XMLNode (editor_name())); XMLNode* node (new XMLNode (editor_name()));
get_common_editing_state (*node); get_common_editing_state (*node);
return *node; return *node;
@ -1354,6 +1494,8 @@ edit_last_mark_label (std::vector<ArdourCanvas::Ruler::Mark>& marks, const std::
void void
CueEditor::metric_get_bbt (std::vector<ArdourCanvas::Ruler::Mark>& marks, samplepos_t leftmost, samplepos_t rightmost, gint /*maxchars*/) CueEditor::metric_get_bbt (std::vector<ArdourCanvas::Ruler::Mark>& marks, samplepos_t leftmost, samplepos_t rightmost, gint /*maxchars*/)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (!_session) { if (!_session) {
return; return;
} }

View file

@ -113,9 +113,6 @@ class CueEditor : public EditingContext, public PBD::HistoryOwner
std::vector<MidiRegionView*> filter_to_unique_midi_region_views (RegionSelection const & ms) const; std::vector<MidiRegionView*> filter_to_unique_midi_region_views (RegionSelection const & ms) const;
std::shared_ptr<Temporal::TempoMap const> start_local_tempo_map (std::shared_ptr<Temporal::TempoMap>);
void end_local_tempo_map (std::shared_ptr<Temporal::TempoMap const>);
void scrolled (); void scrolled ();
bool canvas_pre_event (GdkEvent*); bool canvas_pre_event (GdkEvent*);
void catch_pending_show_region (); void catch_pending_show_region ();

File diff suppressed because it is too large Load diff

View file

@ -87,18 +87,17 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
Temporal::TimeDomain time_domain () const; Temporal::TimeDomain time_domain () const;
struct TempoMapScope { struct TempoMapScope {
TempoMapScope (EditingContext& context, std::shared_ptr<Temporal::TempoMap> map) TempoMapScope (EditingContext& context, std::shared_ptr<Temporal::TempoMap> map)
: ec (context) : ec (context)
{ {
old_map = ec.start_local_tempo_map (map); ec.start_local_tempo_map (map);
ec.ensure_local_tempo_scope ();
} }
~TempoMapScope () { ~TempoMapScope () {
ec.end_local_tempo_map (old_map); ec.end_local_tempo_map ();
} }
EditingContext& ec; EditingContext& ec;
std::shared_ptr<Temporal::TempoMap const> old_map;
}; };
DragManager* drags () const { DragManager* drags () const {
@ -385,8 +384,8 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
static MouseCursors const* cursors () { static MouseCursors const* cursors () {
return _cursors; return _cursors;
} }
virtual VerboseCursor* verbose_cursor () const { virtual VerboseCursor& verbose_cursor () const {
return _verbose_cursor; return *_verbose_cursor;
} }
virtual void set_snapped_cursor_position (Temporal::timepos_t const & pos) = 0; virtual void set_snapped_cursor_position (Temporal::timepos_t const & pos) = 0;
@ -503,6 +502,14 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
void enable_automation_bindings (); void enable_automation_bindings ();
void disable_automation_bindings (); void disable_automation_bindings ();
/* playhead/screen stuff */
void set_stationary_playhead (bool yn);
void toggle_stationary_playhead ();
bool stationary_playhead() const;
bool dragging_playhead () const { return _dragging_playhead; }
protected: protected:
std::string _name; std::string _name;
bool within_track_canvas; bool within_track_canvas;
@ -573,7 +580,6 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
virtual void play_note_selection_clicked(); virtual void play_note_selection_clicked();
virtual void note_mode_clicked() {} virtual void note_mode_clicked() {}
virtual void follow_playhead_clicked ();
virtual void full_zoom_clicked() {}; virtual void full_zoom_clicked() {};
virtual void set_visible_channel (int) {} virtual void set_visible_channel (int) {}
@ -596,6 +602,9 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
Glib::RefPtr<Gtk::ToggleAction> follow_playhead_action; Glib::RefPtr<Gtk::ToggleAction> follow_playhead_action;
void follow_playhead_chosen (); void follow_playhead_chosen ();
Glib::RefPtr<Gtk::ToggleAction> stationary_playhead_action;
void stationary_playhead_chosen ();
/* selection process */ /* selection process */
Selection* selection; Selection* selection;
@ -606,7 +615,7 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
static MouseCursors* _cursors; static MouseCursors* _cursors;
VerboseCursor* _verbose_cursor; std::unique_ptr<VerboseCursor> _verbose_cursor;
samplecnt_t samples_per_pixel; samplecnt_t samples_per_pixel;
@ -656,8 +665,9 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
QuantizeDialog* quantize_dialog; QuantizeDialog* quantize_dialog;
friend struct TempoMapScope; friend struct TempoMapScope;
virtual std::shared_ptr<Temporal::TempoMap const> start_local_tempo_map (std::shared_ptr<Temporal::TempoMap>); void set_local_tempo_map (std::shared_ptr<Temporal::TempoMap>);
virtual void end_local_tempo_map (std::shared_ptr<Temporal::TempoMap const>) { /* no-op by default */ } void start_local_tempo_map (std::shared_ptr<Temporal::TempoMap>);
void end_local_tempo_map ();
virtual bool button_press_handler (ArdourCanvas::Item*, GdkEvent*, ItemType) = 0; virtual bool button_press_handler (ArdourCanvas::Item*, GdkEvent*, ItemType) = 0;
virtual bool button_press_handler_1 (ArdourCanvas::Item*, GdkEvent*, ItemType) = 0; virtual bool button_press_handler_1 (ArdourCanvas::Item*, GdkEvent*, ItemType) = 0;
@ -775,7 +785,7 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
ARDOUR::Location* transport_loop_location(); ARDOUR::Location* transport_loop_location();
std::vector<ArdourCanvas::Ruler::Mark> grid_marks; std::vector<ArdourCanvas::Ruler::Mark> grid_marks;
GridLines* grid_lines; std::unique_ptr<GridLines> grid_lines;
ArdourCanvas::Container* time_line_group; ArdourCanvas::Container* time_line_group;
void drop_grid (); void drop_grid ();
@ -821,4 +831,15 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
virtual void automation_move_points_earlier () {}; virtual void automation_move_points_earlier () {};
bool temporary_zoom_focus_change; bool temporary_zoom_focus_change;
bool _dragging_playhead;
mutable std::shared_ptr<Temporal::TempoMap> _local_tempo_map;
void ensure_local_tempo_scope () const {
if (_local_tempo_map) {
Temporal::TempoMap::set (_local_tempo_map);
}
}
}; };
#define EC_LOCAL_TEMPO_SCOPE ensure_local_tempo_scope ()
#define EC_GIVEN_LOCAL_TEMPO_SCOPE(ec) ec.ensure_local_tempo_scope ()

View file

@ -315,9 +315,7 @@ Editor::Editor ()
, ignore_gui_changes (false) , ignore_gui_changes (false)
, lock_dialog (nullptr) , lock_dialog (nullptr)
, _last_event_time (g_get_monotonic_time ()) , _last_event_time (g_get_monotonic_time ())
, _dragging_playhead (false)
, ignore_map_change (false) , ignore_map_change (false)
, _stationary_playhead (false)
, _maximised (false) , _maximised (false)
, global_rect_group (nullptr) , global_rect_group (nullptr)
, tempo_marker_menu (nullptr) , tempo_marker_menu (nullptr)
@ -740,7 +738,6 @@ Editor::~Editor()
delete _track_canvas_viewport; delete _track_canvas_viewport;
delete _drags; delete _drags;
delete nudge_clock; delete nudge_clock;
delete _verbose_cursor;
delete _region_peak_cursor; delete _region_peak_cursor;
delete quantize_dialog; delete quantize_dialog;
delete _summary; delete _summary;
@ -2358,7 +2355,7 @@ Editor::get_state () const
node->set_property ("maximised", _maximised); node->set_property ("maximised", _maximised);
node->set_property ("follow-playhead", follow_playhead()); node->set_property ("follow-playhead", follow_playhead());
node->set_property ("stationary-playhead", _stationary_playhead); node->set_property ("stationary-playhead", stationary_playhead());
node->set_property ("mouse-mode", current_mouse_mode()); node->set_property ("mouse-mode", current_mouse_mode());
node->set_property ("join-object-range", smart_mode_action->get_active ()); node->set_property ("join-object-range", smart_mode_action->get_active ());
@ -3406,25 +3403,6 @@ Editor::cycle_marker_click_behavior ()
} }
} }
void
Editor::toggle_stationary_playhead ()
{
RefPtr<ToggleAction> tact = ActionManager::get_toggle_action (X_("Editor"), X_("toggle-stationary-playhead"));
set_stationary_playhead (tact->get_active());
}
void
Editor::set_stationary_playhead (bool yn)
{
if (_stationary_playhead != yn) {
if ((_stationary_playhead = yn) == true) {
/* catch up -- FIXME need a 3.0 equivalent of this 2.X call */
// update_current_screen ();
}
instant_save ();
}
}
bool bool
Editor::show_touched_automation() const Editor::show_touched_automation() const
{ {
@ -5310,7 +5288,7 @@ Editor::super_rapid_screen_update ()
return; return;
} }
if (!_stationary_playhead) { if (!stationary_playhead()) {
reset_x_origin_to_follow_playhead (); reset_x_origin_to_follow_playhead ();
} else { } else {
samplepos_t const sample = _playhead_cursor->current_sample (); samplepos_t const sample = _playhead_cursor->current_sample ();

View file

@ -320,14 +320,6 @@ public:
void sequence_regions (); void sequence_regions ();
/* playhead/screen stuff */
void set_stationary_playhead (bool yn);
void toggle_stationary_playhead ();
bool stationary_playhead() const { return _stationary_playhead; }
bool dragging_playhead () const { return _dragging_playhead; }
void toggle_zero_line_visibility (); void toggle_zero_line_visibility ();
void set_summary (); void set_summary ();
void set_group_tabs (); void set_group_tabs ();
@ -1488,8 +1480,6 @@ private:
ARDOUR::PlaylistSet motion_frozen_playlists; ARDOUR::PlaylistSet motion_frozen_playlists;
bool _dragging_playhead;
void marker_drag_motion_callback (GdkEvent*); void marker_drag_motion_callback (GdkEvent*);
void marker_drag_finished_callback (GdkEvent*); void marker_drag_finished_callback (GdkEvent*);
@ -1645,8 +1635,6 @@ private:
/* display control */ /* display control */
/// true if we scroll the tracks rather than the playhead
bool _stationary_playhead;
/// true if we are in fullscreen mode /// true if we are in fullscreen mode
bool _maximised; bool _maximised;

View file

@ -478,8 +478,6 @@ Editor::register_actions ()
act = reg_sens (editor_actions, "remove-last-capture", _("Remove Last Capture"), (sigc::mem_fun(*this, &Editor::remove_last_capture))); act = reg_sens (editor_actions, "remove-last-capture", _("Remove Last Capture"), (sigc::mem_fun(*this, &Editor::remove_last_capture)));
act = reg_sens (editor_actions, "tag-last-capture", _("Tag Last Capture"), (sigc::mem_fun(*this, &Editor::tag_last_capture))); act = reg_sens (editor_actions, "tag-last-capture", _("Tag Last Capture"), (sigc::mem_fun(*this, &Editor::tag_last_capture)));
ActionManager::register_toggle_action (editor_actions, "toggle-stationary-playhead", _("Stationary Playhead"), (mem_fun(*this, &Editor::toggle_stationary_playhead)));
show_touched_automation_action = ActionManager::register_toggle_action (editor_actions, "show-touched-automation", _("Show Automation Lane on Touch"), (mem_fun(*this, &Editor::toggle_show_touched_automation))); show_touched_automation_action = ActionManager::register_toggle_action (editor_actions, "show-touched-automation", _("Show Automation Lane on Touch"), (mem_fun(*this, &Editor::toggle_show_touched_automation)));
act = reg_sens (editor_actions, "insert-time", _("Insert Time"), (sigc::mem_fun(*this, &Editor::do_insert_time))); act = reg_sens (editor_actions, "insert-time", _("Insert Time"), (sigc::mem_fun(*this, &Editor::do_insert_time)));

View file

@ -95,7 +95,7 @@ Editor::initialize_canvas ()
*/ */
no_scroll_group = new ArdourCanvas::Container (_track_canvas->root()); no_scroll_group = new ArdourCanvas::Container (_track_canvas->root());
_verbose_cursor = new VerboseCursor (*this); _verbose_cursor.reset (new VerboseCursor (*this));
ArdourCanvas::ScrollGroup* hsg; ArdourCanvas::ScrollGroup* hsg;
ArdourCanvas::ScrollGroup* hg; ArdourCanvas::ScrollGroup* hg;

View file

@ -426,7 +426,7 @@ Drag::end_grab (GdkEvent* event)
finished (event, _starting_point_passed); finished (event, _starting_point_passed);
editing_context.verbose_cursor ()->hide (); editing_context.verbose_cursor().hide ();
return _starting_point_passed; return _starting_point_passed;
} }
@ -595,28 +595,28 @@ Drag::abort ()
aborted (_move_threshold_passed); aborted (_move_threshold_passed);
editing_context.stop_canvas_autoscroll (); editing_context.stop_canvas_autoscroll ();
editing_context.verbose_cursor ()->hide (); editing_context.verbose_cursor().hide ();
} }
void void
Drag::show_verbose_cursor_time (timepos_t const& pos) Drag::show_verbose_cursor_time (timepos_t const& pos)
{ {
editing_context.verbose_cursor ()->set_time (pos.samples ()); editing_context.verbose_cursor().set_time (pos.samples ());
editing_context.verbose_cursor ()->show (); editing_context.verbose_cursor().show ();
} }
void void
Drag::show_verbose_cursor_duration (timepos_t const& start, timepos_t const& end, double /*xoffset*/) Drag::show_verbose_cursor_duration (timepos_t const& start, timepos_t const& end, double /*xoffset*/)
{ {
editing_context.verbose_cursor ()->set_duration (start.samples (), end.samples ()); editing_context.verbose_cursor().set_duration (start.samples (), end.samples ());
editing_context.verbose_cursor ()->show (); editing_context.verbose_cursor().show ();
} }
void void
Drag::show_verbose_cursor_text (string const& text) Drag::show_verbose_cursor_text (string const& text)
{ {
editing_context.verbose_cursor ()->set (text); editing_context.verbose_cursor().set (text);
editing_context.verbose_cursor ()->show (); editing_context.verbose_cursor().show ();
} }
void void

View file

@ -122,11 +122,11 @@ MidiStreamView::create_region_view (std::shared_ptr<Region> r, bool /*wfd*/, boo
if (recording) { if (recording) {
region_view = new MidiRegionView ( region_view = new MidiRegionView (
_region_group, _trackview.editor(), _trackview, region, _region_group, _trackview.editor(), _trackview, region,
_samples_per_pixel, MidiViewBackground::region_color(), recording, _samples_per_pixel, StreamView::region_color, recording,
TimeAxisViewItem::Visibility(TimeAxisViewItem::ShowFrame)); TimeAxisViewItem::Visibility(TimeAxisViewItem::ShowFrame));
} else { } else {
region_view = new MidiRegionView (_region_group, _trackview.editor(), _trackview, region, region_view = new MidiRegionView (_region_group, _trackview.editor(), _trackview, region,
_samples_per_pixel, MidiViewBackground::region_color()); _samples_per_pixel, StreamView::region_color);
} }
region_view->init (false); region_view->init (false);

View file

@ -4478,7 +4478,7 @@ MidiView::remove_ghost_note ()
void void
MidiView::hide_verbose_cursor () MidiView::hide_verbose_cursor ()
{ {
_editing_context.verbose_cursor()->hide (); _editing_context.verbose_cursor().hide ();
_midi_context.set_note_highlight (NO_MIDI_NOTE); _midi_context.set_note_highlight (NO_MIDI_NOTE);
} }
@ -4865,9 +4865,9 @@ MidiView::show_verbose_cursor (std::shared_ptr<NoteType> n) const
void void
MidiView::show_verbose_cursor (string const & text, double xoffset, double yoffset) const MidiView::show_verbose_cursor (string const & text, double xoffset, double yoffset) const
{ {
_editing_context.verbose_cursor()->set (text); _editing_context.verbose_cursor().set (text);
_editing_context.verbose_cursor()->show (); _editing_context.verbose_cursor().show ();
_editing_context.verbose_cursor()->set_offset (ArdourCanvas::Duple (xoffset, yoffset)); _editing_context.verbose_cursor().set_offset (ArdourCanvas::Duple (xoffset, yoffset));
} }

View file

@ -105,6 +105,8 @@ Pianoroll::~Pianoroll ()
void void
Pianoroll::set_show_source (bool yn) Pianoroll::set_show_source (bool yn)
{ {
EC_LOCAL_TEMPO_SCOPE;
CueEditor::set_show_source (yn); CueEditor::set_show_source (yn);
if (view) { if (view) {
view->set_show_source (yn); view->set_show_source (yn);
@ -114,6 +116,8 @@ Pianoroll::set_show_source (bool yn)
void void
Pianoroll::rebuild_parameter_button_map() Pianoroll::rebuild_parameter_button_map()
{ {
EC_LOCAL_TEMPO_SCOPE;
parameter_button_map.clear (); parameter_button_map.clear ();
parameter_button_map.insert (std::make_pair (velocity_button, Evoral::Parameter (ARDOUR::MidiVelocityAutomation, _visible_channel))); parameter_button_map.insert (std::make_pair (velocity_button, Evoral::Parameter (ARDOUR::MidiVelocityAutomation, _visible_channel)));
parameter_button_map.insert (std::make_pair (bender_button, Evoral::Parameter (ARDOUR::MidiPitchBenderAutomation, _visible_channel))); parameter_button_map.insert (std::make_pair (bender_button, Evoral::Parameter (ARDOUR::MidiPitchBenderAutomation, _visible_channel)));
@ -129,6 +133,8 @@ Pianoroll::rebuild_parameter_button_map()
void void
Pianoroll::reset_user_cc_choice (std::string name, Evoral::Parameter param, MetaButton* metabutton) Pianoroll::reset_user_cc_choice (std::string name, Evoral::Parameter param, MetaButton* metabutton)
{ {
EC_LOCAL_TEMPO_SCOPE;
ParameterButtonMap::iterator iter; ParameterButtonMap::iterator iter;
for (iter = parameter_button_map.begin(); iter != parameter_button_map.end(); ++iter) { for (iter = parameter_button_map.begin(); iter != parameter_button_map.end(); ++iter) {
@ -149,6 +155,8 @@ Pianoroll::add_single_controller_item (Gtk::Menu_Helpers::MenuList& ctl_items,
const std::string& name, const std::string& name,
ArdourWidgets::MetaButton* mb) ArdourWidgets::MetaButton* mb)
{ {
EC_LOCAL_TEMPO_SCOPE;
using namespace Gtk::Menu_Helpers; using namespace Gtk::Menu_Helpers;
const uint16_t selected_channels = 0xffff; const uint16_t selected_channels = 0xffff;
@ -174,6 +182,8 @@ Pianoroll::add_multi_controller_item (Gtk::Menu_Helpers::MenuList&,
const std::string& name, const std::string& name,
MetaButton* mb) MetaButton* mb)
{ {
EC_LOCAL_TEMPO_SCOPE;
using namespace Gtk; using namespace Gtk;
using namespace Gtk::Menu_Helpers; using namespace Gtk::Menu_Helpers;
@ -223,6 +233,8 @@ Pianoroll::add_multi_controller_item (Gtk::Menu_Helpers::MenuList&,
void void
Pianoroll::build_lower_toolbar () Pianoroll::build_lower_toolbar ()
{ {
EC_LOCAL_TEMPO_SCOPE;
horizontal_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &Pianoroll::scrolled)); horizontal_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &Pianoroll::scrolled));
ArdourButton::Element elements = ArdourButton::Element (ArdourButton::Text|ArdourButton::Indicator|ArdourButton::Edge|ArdourButton::Body); ArdourButton::Element elements = ArdourButton::Element (ArdourButton::Text|ArdourButton::Indicator|ArdourButton::Edge|ArdourButton::Body);
@ -292,6 +304,8 @@ Pianoroll::build_lower_toolbar ()
void void
Pianoroll::pack_inner (Gtk::Box& box) Pianoroll::pack_inner (Gtk::Box& box)
{ {
EC_LOCAL_TEMPO_SCOPE;
box.pack_start (snap_box, false, false); box.pack_start (snap_box, false, false);
box.pack_start (grid_box, false, false); box.pack_start (grid_box, false, false);
box.pack_start (draw_box, false, false); box.pack_start (draw_box, false, false);
@ -300,6 +314,8 @@ Pianoroll::pack_inner (Gtk::Box& box)
void void
Pianoroll::pack_outer (Gtk::Box& box) Pianoroll::pack_outer (Gtk::Box& box)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (with_transport_controls) { if (with_transport_controls) {
box.pack_start (play_box, false, false); box.pack_start (play_box, false, false);
} }
@ -314,6 +330,8 @@ Pianoroll::pack_outer (Gtk::Box& box)
void void
Pianoroll::set_visible_channel (int n) Pianoroll::set_visible_channel (int n)
{ {
EC_LOCAL_TEMPO_SCOPE;
PBD::Unwinder<bool> uw (ignore_channel_changes, true); PBD::Unwinder<bool> uw (ignore_channel_changes, true);
_visible_channel = n; _visible_channel = n;
@ -332,6 +350,8 @@ Pianoroll::set_visible_channel (int n)
void void
Pianoroll::build_canvas () Pianoroll::build_canvas ()
{ {
EC_LOCAL_TEMPO_SCOPE;
_canvas.set_background_color (UIConfiguration::instance().color ("arrange base")); _canvas.set_background_color (UIConfiguration::instance().color ("arrange base"));
_canvas.signal_event().connect (sigc::mem_fun (*this, &Pianoroll::canvas_pre_event), false); _canvas.signal_event().connect (sigc::mem_fun (*this, &Pianoroll::canvas_pre_event), false);
dynamic_cast<ArdourCanvas::GtkCanvas*>(&_canvas)->use_nsglview (UIConfiguration::instance().get_nsgl_view_mode () == NSGLHiRes); dynamic_cast<ArdourCanvas::GtkCanvas*>(&_canvas)->use_nsglview (UIConfiguration::instance().get_nsgl_view_mode () == NSGLHiRes);
@ -453,7 +473,7 @@ Pianoroll::build_canvas ()
cursor_scroll_group->set_position (ArdourCanvas::Duple (_timeline_origin, timebar_height * n_timebars)); cursor_scroll_group->set_position (ArdourCanvas::Duple (_timeline_origin, timebar_height * n_timebars));
h_scroll_group->set_position (Duple (_timeline_origin, 0.)); h_scroll_group->set_position (Duple (_timeline_origin, 0.));
_verbose_cursor = new VerboseCursor (*this); _verbose_cursor.reset (new VerboseCursor (*this));
// _playhead_cursor = new EditorCursor (*this, &Editor::canvas_playhead_cursor_event, X_("playhead")); // _playhead_cursor = new EditorCursor (*this, &Editor::canvas_playhead_cursor_event, X_("playhead"));
_playhead_cursor = new EditorCursor (*this, X_("playhead")); _playhead_cursor = new EditorCursor (*this, X_("playhead"));
@ -473,6 +493,8 @@ Pianoroll::build_canvas ()
void void
Pianoroll::visible_channel_changed () Pianoroll::visible_channel_changed ()
{ {
EC_LOCAL_TEMPO_SCOPE;
if (ignore_channel_changes) { if (ignore_channel_changes) {
/* We're changing it */ /* We're changing it */
return; return;
@ -491,6 +513,8 @@ Pianoroll::visible_channel_changed ()
void void
Pianoroll::bindings_changed () Pianoroll::bindings_changed ()
{ {
EC_LOCAL_TEMPO_SCOPE;
bindings.clear (); bindings.clear ();
load_shared_bindings (); load_shared_bindings ();
} }
@ -498,6 +522,8 @@ Pianoroll::bindings_changed ()
void void
Pianoroll::maybe_update () Pianoroll::maybe_update ()
{ {
EC_LOCAL_TEMPO_SCOPE;
ARDOUR::TriggerPtr playing_trigger; ARDOUR::TriggerPtr playing_trigger;
if (ref.trigger()) { if (ref.trigger()) {
@ -555,6 +581,8 @@ Pianoroll::maybe_update ()
bool bool
Pianoroll::canvas_enter_leave (GdkEventCrossing* ev) Pianoroll::canvas_enter_leave (GdkEventCrossing* ev)
{ {
EC_LOCAL_TEMPO_SCOPE;
switch (ev->type) { switch (ev->type) {
case GDK_ENTER_NOTIFY: case GDK_ENTER_NOTIFY:
if (ev->detail != GDK_NOTIFY_INFERIOR) { if (ev->detail != GDK_NOTIFY_INFERIOR) {
@ -579,6 +607,8 @@ Pianoroll::canvas_enter_leave (GdkEventCrossing* ev)
void void
Pianoroll::canvas_allocate (Gtk::Allocation alloc) Pianoroll::canvas_allocate (Gtk::Allocation alloc)
{ {
EC_LOCAL_TEMPO_SCOPE;
_visible_canvas_width = alloc.get_width(); _visible_canvas_width = alloc.get_width();
_visible_canvas_height = alloc.get_height(); _visible_canvas_height = alloc.get_height();
@ -610,6 +640,8 @@ Pianoroll::canvas_allocate (Gtk::Allocation alloc)
timepos_t timepos_t
Pianoroll::snap_to_grid (timepos_t const & presnap, Temporal::RoundMode direction, SnapPref gpref) const Pianoroll::snap_to_grid (timepos_t const & presnap, Temporal::RoundMode direction, SnapPref gpref) const
{ {
EC_LOCAL_TEMPO_SCOPE;
/* BBT time only */ /* BBT time only */
return snap_to_bbt (presnap, direction, gpref); return snap_to_bbt (presnap, direction, gpref);
} }
@ -617,6 +649,8 @@ Pianoroll::snap_to_grid (timepos_t const & presnap, Temporal::RoundMode directio
void void
Pianoroll::snap_to_internal (timepos_t& start, Temporal::RoundMode direction, SnapPref pref, bool ensure_snap) const Pianoroll::snap_to_internal (timepos_t& start, Temporal::RoundMode direction, SnapPref pref, bool ensure_snap) const
{ {
EC_LOCAL_TEMPO_SCOPE;
UIConfiguration const& uic (UIConfiguration::instance ()); UIConfiguration const& uic (UIConfiguration::instance ());
const timepos_t presnap = start; const timepos_t presnap = start;
@ -654,6 +688,8 @@ Pianoroll::set_samples_per_pixel (samplecnt_t spp)
return; return;
} }
EC_LOCAL_TEMPO_SCOPE;
CueEditor::set_samples_per_pixel (spp); CueEditor::set_samples_per_pixel (spp);
if (view) { if (view) {
@ -671,54 +707,72 @@ Pianoroll::set_samples_per_pixel (samplecnt_t spp)
samplecnt_t samplecnt_t
Pianoroll::current_page_samples() const Pianoroll::current_page_samples() const
{ {
EC_LOCAL_TEMPO_SCOPE;
return (samplecnt_t) _track_canvas_width * samples_per_pixel; return (samplecnt_t) _track_canvas_width * samples_per_pixel;
} }
bool bool
Pianoroll::canvas_bg_event (GdkEvent* event, ArdourCanvas::Item* item) Pianoroll::canvas_bg_event (GdkEvent* event, ArdourCanvas::Item* item)
{ {
EC_LOCAL_TEMPO_SCOPE;
return typed_event (item, event, RegionItem); return typed_event (item, event, RegionItem);
} }
bool bool
Pianoroll::canvas_control_point_event (GdkEvent* event, ArdourCanvas::Item* item, ControlPoint* cp) Pianoroll::canvas_control_point_event (GdkEvent* event, ArdourCanvas::Item* item, ControlPoint* cp)
{ {
EC_LOCAL_TEMPO_SCOPE;
return typed_event (item, event, ControlPointItem); return typed_event (item, event, ControlPointItem);
} }
bool bool
Pianoroll::canvas_note_event (GdkEvent* event, ArdourCanvas::Item* item) Pianoroll::canvas_note_event (GdkEvent* event, ArdourCanvas::Item* item)
{ {
EC_LOCAL_TEMPO_SCOPE;
return typed_event (item, event, NoteItem); return typed_event (item, event, NoteItem);
} }
bool bool
Pianoroll::canvas_velocity_base_event (GdkEvent* event, ArdourCanvas::Item* item) Pianoroll::canvas_velocity_base_event (GdkEvent* event, ArdourCanvas::Item* item)
{ {
EC_LOCAL_TEMPO_SCOPE;
return typed_event (item, event, VelocityBaseItem); return typed_event (item, event, VelocityBaseItem);
} }
bool bool
Pianoroll::canvas_velocity_event (GdkEvent* event, ArdourCanvas::Item* item) Pianoroll::canvas_velocity_event (GdkEvent* event, ArdourCanvas::Item* item)
{ {
EC_LOCAL_TEMPO_SCOPE;
return typed_event (item, event, VelocityItem); return typed_event (item, event, VelocityItem);
} }
bool bool
Pianoroll::canvas_cue_start_event (GdkEvent* event, ArdourCanvas::Item* item) Pianoroll::canvas_cue_start_event (GdkEvent* event, ArdourCanvas::Item* item)
{ {
EC_LOCAL_TEMPO_SCOPE;
return typed_event (item, event, ClipStartItem); return typed_event (item, event, ClipStartItem);
} }
bool bool
Pianoroll::canvas_cue_end_event (GdkEvent* event, ArdourCanvas::Item* item) Pianoroll::canvas_cue_end_event (GdkEvent* event, ArdourCanvas::Item* item)
{ {
EC_LOCAL_TEMPO_SCOPE;
return typed_event (item, event, ClipEndItem); return typed_event (item, event, ClipEndItem);
} }
void void
Pianoroll::set_trigger_start (Temporal::timepos_t const & p) Pianoroll::set_trigger_start (Temporal::timepos_t const & p)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (ref.trigger()) { if (ref.trigger()) {
ref.trigger()->the_region()->trim_front (p); ref.trigger()->the_region()->trim_front (p);
} else { } else {
@ -733,6 +787,8 @@ Pianoroll::set_trigger_start (Temporal::timepos_t const & p)
void void
Pianoroll::set_trigger_end (Temporal::timepos_t const & p) Pianoroll::set_trigger_end (Temporal::timepos_t const & p)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (ref.trigger()) { if (ref.trigger()) {
ref.trigger()->the_region()->trim_end (p); ref.trigger()->the_region()->trim_end (p);
} else { } else {
@ -747,12 +803,16 @@ Pianoroll::set_trigger_end (Temporal::timepos_t const & p)
Gtk::Widget& Gtk::Widget&
Pianoroll::contents () Pianoroll::contents ()
{ {
EC_LOCAL_TEMPO_SCOPE;
return _contents; return _contents;
} }
bool bool
Pianoroll::idle_data_captured () Pianoroll::idle_data_captured ()
{ {
EC_LOCAL_TEMPO_SCOPE;
if (!ref.box()) { if (!ref.box()) {
return false; return false;
} }
@ -769,6 +829,8 @@ Pianoroll::idle_data_captured ()
bool bool
Pianoroll::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type) Pianoroll::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (event->type != GDK_BUTTON_PRESS) { if (event->type != GDK_BUTTON_PRESS) {
return false; return false;
} }
@ -797,6 +859,8 @@ Pianoroll::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, Item
bool bool
Pianoroll::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type) Pianoroll::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
{ {
EC_LOCAL_TEMPO_SCOPE;
NoteBase* note = nullptr; NoteBase* note = nullptr;
Editing::MouseMode mouse_mode = current_mouse_mode(); Editing::MouseMode mouse_mode = current_mouse_mode();
switch (item_type) { switch (item_type) {
@ -899,12 +963,16 @@ Pianoroll::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, It
bool bool
Pianoroll::button_press_handler_2 (ArdourCanvas::Item*, GdkEvent*, ItemType) Pianoroll::button_press_handler_2 (ArdourCanvas::Item*, GdkEvent*, ItemType)
{ {
EC_LOCAL_TEMPO_SCOPE;
return true; return true;
} }
bool bool
Pianoroll::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type) Pianoroll::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (!Keyboard::is_context_menu_event (&event->button)) { if (!Keyboard::is_context_menu_event (&event->button)) {
/* see if we're finishing a drag */ /* see if we're finishing a drag */
@ -946,6 +1014,8 @@ Pianoroll::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, It
void void
Pianoroll::popup_region_context_menu (ArdourCanvas::Item* item, GdkEvent* event) Pianoroll::popup_region_context_menu (ArdourCanvas::Item* item, GdkEvent* event)
{ {
EC_LOCAL_TEMPO_SCOPE;
using namespace Gtk::Menu_Helpers; using namespace Gtk::Menu_Helpers;
if (!view) { if (!view) {
@ -981,6 +1051,8 @@ Pianoroll::popup_region_context_menu (ArdourCanvas::Item* item, GdkEvent* event)
bool bool
Pianoroll::button_press_dispatch (GdkEventButton* ev) Pianoroll::button_press_dispatch (GdkEventButton* ev)
{ {
EC_LOCAL_TEMPO_SCOPE;
/* this function is intended only for buttons 4 and above. */ /* this function is intended only for buttons 4 and above. */
Gtkmm2ext::MouseButton b (ev->state, ev->button); Gtkmm2ext::MouseButton b (ev->state, ev->button);
@ -990,6 +1062,8 @@ Pianoroll::button_press_dispatch (GdkEventButton* ev)
bool bool
Pianoroll::button_release_dispatch (GdkEventButton* ev) Pianoroll::button_release_dispatch (GdkEventButton* ev)
{ {
EC_LOCAL_TEMPO_SCOPE;
/* this function is intended only for buttons 4 and above. */ /* this function is intended only for buttons 4 and above. */
Gtkmm2ext::MouseButton b (ev->state, ev->button); Gtkmm2ext::MouseButton b (ev->state, ev->button);
@ -999,6 +1073,8 @@ Pianoroll::button_release_dispatch (GdkEventButton* ev)
bool bool
Pianoroll::motion_handler (ArdourCanvas::Item*, GdkEvent* event, bool from_autoscroll) Pianoroll::motion_handler (ArdourCanvas::Item*, GdkEvent* event, bool from_autoscroll)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (_drags->active ()) { if (_drags->active ()) {
//drags change the snapped_cursor location, because we are snapping the thing being dragged, not the actual mouse cursor //drags change the snapped_cursor location, because we are snapping the thing being dragged, not the actual mouse cursor
return _drags->motion_handler (event, from_autoscroll); return _drags->motion_handler (event, from_autoscroll);
@ -1010,6 +1086,8 @@ Pianoroll::motion_handler (ArdourCanvas::Item*, GdkEvent* event, bool from_autos
bool bool
Pianoroll::key_press_handler (ArdourCanvas::Item*, GdkEvent* ev, ItemType) Pianoroll::key_press_handler (ArdourCanvas::Item*, GdkEvent* ev, ItemType)
{ {
EC_LOCAL_TEMPO_SCOPE;
switch (ev->key.keyval) { switch (ev->key.keyval) {
case GDK_d: case GDK_d:
@ -1026,12 +1104,16 @@ Pianoroll::key_press_handler (ArdourCanvas::Item*, GdkEvent* ev, ItemType)
bool bool
Pianoroll::key_release_handler (ArdourCanvas::Item*, GdkEvent*, ItemType) Pianoroll::key_release_handler (ArdourCanvas::Item*, GdkEvent*, ItemType)
{ {
EC_LOCAL_TEMPO_SCOPE;
return true; return true;
} }
void void
Pianoroll::set_mouse_mode (Editing::MouseMode m, bool force) Pianoroll::set_mouse_mode (Editing::MouseMode m, bool force)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (m != Editing::MouseDraw && m != Editing::MouseContent) { if (m != Editing::MouseDraw && m != Editing::MouseContent) {
return; return;
} }
@ -1042,6 +1124,8 @@ Pianoroll::set_mouse_mode (Editing::MouseMode m, bool force)
void void
Pianoroll::midi_action (void (MidiView::*method)()) Pianoroll::midi_action (void (MidiView::*method)())
{ {
EC_LOCAL_TEMPO_SCOPE;
if (!view) { if (!view) {
return; return;
} }
@ -1052,6 +1136,8 @@ Pianoroll::midi_action (void (MidiView::*method)())
void void
Pianoroll::escape () Pianoroll::escape ()
{ {
EC_LOCAL_TEMPO_SCOPE;
if (!view) { if (!view) {
return; return;
} }
@ -1062,12 +1148,16 @@ Pianoroll::escape ()
Gdk::Cursor* Gdk::Cursor*
Pianoroll::which_track_cursor () const Pianoroll::which_track_cursor () const
{ {
EC_LOCAL_TEMPO_SCOPE;
return _cursors->grabber; return _cursors->grabber;
} }
Gdk::Cursor* Gdk::Cursor*
Pianoroll::which_mode_cursor () const Pianoroll::which_mode_cursor () const
{ {
EC_LOCAL_TEMPO_SCOPE;
Gdk::Cursor* mode_cursor = MouseCursors::invalid_cursor (); Gdk::Cursor* mode_cursor = MouseCursors::invalid_cursor ();
switch (current_mouse_mode()) { switch (current_mouse_mode()) {
@ -1089,6 +1179,8 @@ Pianoroll::which_mode_cursor () const
Gdk::Cursor* Gdk::Cursor*
Pianoroll::which_trim_cursor (bool left_side) const Pianoroll::which_trim_cursor (bool left_side) const
{ {
EC_LOCAL_TEMPO_SCOPE;
abort (); abort ();
/*NOTREACHED*/ /*NOTREACHED*/
return nullptr; return nullptr;
@ -1098,6 +1190,8 @@ Pianoroll::which_trim_cursor (bool left_side) const
Gdk::Cursor* Gdk::Cursor*
Pianoroll::which_canvas_cursor (ItemType type) const Pianoroll::which_canvas_cursor (ItemType type) const
{ {
EC_LOCAL_TEMPO_SCOPE;
Gdk::Cursor* cursor = which_mode_cursor (); Gdk::Cursor* cursor = which_mode_cursor ();
Editing::MouseMode mouse_mode = current_mouse_mode (); Editing::MouseMode mouse_mode = current_mouse_mode ();
@ -1185,6 +1279,8 @@ Pianoroll::which_canvas_cursor (ItemType type) const
bool bool
Pianoroll::enter_handler (ArdourCanvas::Item* item, GdkEvent* ev, ItemType item_type) Pianoroll::enter_handler (ArdourCanvas::Item* item, GdkEvent* ev, ItemType item_type)
{ {
EC_LOCAL_TEMPO_SCOPE;
choose_canvas_cursor_on_entry (item_type); choose_canvas_cursor_on_entry (item_type);
switch (item_type) { switch (item_type) {
@ -1214,6 +1310,8 @@ Pianoroll::enter_handler (ArdourCanvas::Item* item, GdkEvent* ev, ItemType item_
bool bool
Pianoroll::leave_handler (ArdourCanvas::Item* item, GdkEvent* ev, ItemType item_type) Pianoroll::leave_handler (ArdourCanvas::Item* item, GdkEvent* ev, ItemType item_type)
{ {
EC_LOCAL_TEMPO_SCOPE;
EditorAutomationLine* al; EditorAutomationLine* al;
set_canvas_cursor (which_mode_cursor()); set_canvas_cursor (which_mode_cursor());
@ -1247,6 +1345,8 @@ Pianoroll::leave_handler (ArdourCanvas::Item* item, GdkEvent* ev, ItemType item_
std::list<SelectableOwner*> std::list<SelectableOwner*>
Pianoroll::selectable_owners() Pianoroll::selectable_owners()
{ {
EC_LOCAL_TEMPO_SCOPE;
if (view) { if (view) {
return view->selectable_owners(); return view->selectable_owners();
} }
@ -1257,6 +1357,8 @@ Pianoroll::selectable_owners()
void void
Pianoroll::trigger_prop_change (PBD::PropertyChange const & what_changed) Pianoroll::trigger_prop_change (PBD::PropertyChange const & what_changed)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (what_changed.contains (Properties::region)) { if (what_changed.contains (Properties::region)) {
std::shared_ptr<MidiRegion> mr = std::dynamic_pointer_cast<MidiRegion> (ref.trigger()->the_region()); std::shared_ptr<MidiRegion> mr = std::dynamic_pointer_cast<MidiRegion> (ref.trigger()->the_region());
if (mr) { if (mr) {
@ -1268,6 +1370,8 @@ Pianoroll::trigger_prop_change (PBD::PropertyChange const & what_changed)
void void
Pianoroll::region_prop_change (PBD::PropertyChange const & what_changed) Pianoroll::region_prop_change (PBD::PropertyChange const & what_changed)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (what_changed.contains (Properties::length)) { if (what_changed.contains (Properties::length)) {
std::shared_ptr<MidiRegion> mr = view->midi_region(); std::shared_ptr<MidiRegion> mr = view->midi_region();
if (mr) { if (mr) {
@ -1279,6 +1383,8 @@ Pianoroll::region_prop_change (PBD::PropertyChange const & what_changed)
void void
Pianoroll::set_trigger (TriggerReference & tref) Pianoroll::set_trigger (TriggerReference & tref)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (ref == tref) { if (ref == tref) {
return; return;
} }
@ -1314,6 +1420,8 @@ Pianoroll::set_trigger (TriggerReference & tref)
void void
Pianoroll::make_a_region () Pianoroll::make_a_region ()
{ {
EC_LOCAL_TEMPO_SCOPE;
std::shared_ptr<MidiSource> new_source = _session->create_midi_source_for_session (_track->name()); std::shared_ptr<MidiSource> new_source = _session->create_midi_source_for_session (_track->name());
SourceList sources; SourceList sources;
sources.push_back (new_source); sources.push_back (new_source);
@ -1339,6 +1447,8 @@ Pianoroll::make_a_region ()
void void
Pianoroll::unset (bool trigger_too) Pianoroll::unset (bool trigger_too)
{ {
EC_LOCAL_TEMPO_SCOPE;
CueEditor::unset (trigger_too); CueEditor::unset (trigger_too);
view->set_region (nullptr); view->set_region (nullptr);
} }
@ -1346,6 +1456,8 @@ Pianoroll::unset (bool trigger_too)
void void
Pianoroll::set_track (std::shared_ptr<ARDOUR::Track> track) Pianoroll::set_track (std::shared_ptr<ARDOUR::Track> track)
{ {
EC_LOCAL_TEMPO_SCOPE;
CueEditor::set_track (track); CueEditor::set_track (track);
if (view) { if (view) {
@ -1374,6 +1486,8 @@ Pianoroll::set_track (std::shared_ptr<ARDOUR::Track> track)
void void
Pianoroll::set_region (std::shared_ptr<ARDOUR::Region> region) Pianoroll::set_region (std::shared_ptr<ARDOUR::Region> region)
{ {
EC_LOCAL_TEMPO_SCOPE;
CueEditor::set_region (region); CueEditor::set_region (region);
if (_visible_pending_region) { if (_visible_pending_region) {
@ -1383,6 +1497,7 @@ Pianoroll::set_region (std::shared_ptr<ARDOUR::Region> region)
std::shared_ptr<MidiRegion> r (std::dynamic_pointer_cast<ARDOUR::MidiRegion> (region)); std::shared_ptr<MidiRegion> r (std::dynamic_pointer_cast<ARDOUR::MidiRegion> (region));
if (!r || !region) { if (!r || !region) {
_update_connection.disconnect ();
return; return;
} }
@ -1442,6 +1557,8 @@ Pianoroll::set_region (std::shared_ptr<ARDOUR::Region> region)
bool bool
Pianoroll::user_automation_button_event (GdkEventButton* ev, MetaButton* mb) Pianoroll::user_automation_button_event (GdkEventButton* ev, MetaButton* mb)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (mb->is_menu_popup_event (ev)) { if (mb->is_menu_popup_event (ev)) {
return false; return false;
} }
@ -1466,6 +1583,8 @@ Pianoroll::user_automation_button_event (GdkEventButton* ev, MetaButton* mb)
void void
Pianoroll::user_led_click (GdkEventButton* ev, MetaButton* metabutton) Pianoroll::user_led_click (GdkEventButton* ev, MetaButton* metabutton)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (ev->button != 1) { if (ev->button != 1) {
return; return;
} }
@ -1482,6 +1601,8 @@ Pianoroll::user_led_click (GdkEventButton* ev, MetaButton* metabutton)
bool bool
Pianoroll::automation_button_event (GdkEventButton* ev, Evoral::ParameterType type, int id) Pianoroll::automation_button_event (GdkEventButton* ev, Evoral::ParameterType type, int id)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (ev->button != 1) { if (ev->button != 1) {
return false; return false;
} }
@ -1496,6 +1617,8 @@ Pianoroll::automation_button_event (GdkEventButton* ev, Evoral::ParameterType ty
void void
Pianoroll::automation_led_click (GdkEventButton* ev, Evoral::ParameterType type, int id) Pianoroll::automation_led_click (GdkEventButton* ev, Evoral::ParameterType type, int id)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (ev->button != 1) { if (ev->button != 1) {
return; return;
} }
@ -1515,6 +1638,8 @@ Pianoroll::automation_led_click (GdkEventButton* ev, Evoral::ParameterType type,
void void
Pianoroll::automation_state_changed () Pianoroll::automation_state_changed ()
{ {
EC_LOCAL_TEMPO_SCOPE;
assert (view); assert (view);
for (ParameterButtonMap::iterator i = parameter_button_map.begin(); i != parameter_button_map.end(); ++i) { for (ParameterButtonMap::iterator i = parameter_button_map.begin(); i != parameter_button_map.end(); ++i) {
@ -1541,6 +1666,8 @@ Pianoroll::automation_state_changed ()
void void
Pianoroll::note_mode_clicked () Pianoroll::note_mode_clicked ()
{ {
EC_LOCAL_TEMPO_SCOPE;
assert (bg); assert (bg);
if (bg->note_mode() == Sustained) { if (bg->note_mode() == Sustained) {
@ -1553,6 +1680,8 @@ Pianoroll::note_mode_clicked ()
void void
Pianoroll::set_note_mode (NoteMode nm) Pianoroll::set_note_mode (NoteMode nm)
{ {
EC_LOCAL_TEMPO_SCOPE;
assert (bg); assert (bg);
if (nm != bg->note_mode()) { if (nm != bg->note_mode()) {
@ -1568,6 +1697,8 @@ Pianoroll::set_note_mode (NoteMode nm)
void void
Pianoroll::point_selection_changed () Pianoroll::point_selection_changed ()
{ {
EC_LOCAL_TEMPO_SCOPE;
if (view) { if (view) {
view->point_selection_changed (); view->point_selection_changed ();
} }
@ -1576,6 +1707,8 @@ Pianoroll::point_selection_changed ()
void void
Pianoroll::delete_ () Pianoroll::delete_ ()
{ {
EC_LOCAL_TEMPO_SCOPE;
/* Editor has a lot to do here, potentially. But we don't */ /* Editor has a lot to do here, potentially. But we don't */
cut_copy (Editing::Delete); cut_copy (Editing::Delete);
} }
@ -1583,6 +1716,8 @@ Pianoroll::delete_ ()
void void
Pianoroll::paste (float times, bool from_context_menu) Pianoroll::paste (float times, bool from_context_menu)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (view) { if (view) {
// view->paste (Editing::Cut); // view->paste (Editing::Cut);
} }
@ -1591,6 +1726,8 @@ Pianoroll::paste (float times, bool from_context_menu)
void void
Pianoroll::keyboard_paste () Pianoroll::keyboard_paste ()
{ {
EC_LOCAL_TEMPO_SCOPE;
} }
/** Cut, copy or clear selected regions, automation points or a time range. /** Cut, copy or clear selected regions, automation points or a time range.
@ -1600,6 +1737,8 @@ Pianoroll::keyboard_paste ()
void void
Pianoroll::cut_copy (Editing::CutCopyOp op) Pianoroll::cut_copy (Editing::CutCopyOp op)
{ {
EC_LOCAL_TEMPO_SCOPE;
using namespace Editing; using namespace Editing;
/* only cancel selection if cut/copy is successful.*/ /* only cancel selection if cut/copy is successful.*/
@ -1659,6 +1798,8 @@ Pianoroll::cut_copy (Editing::CutCopyOp op)
void void
Pianoroll::select_all_within (Temporal::timepos_t const & start, Temporal::timepos_t const & end, double y0, double y1, std::list<SelectableOwner*> const & ignored, ARDOUR::SelectionOperation op, bool preserve_if_selected) Pianoroll::select_all_within (Temporal::timepos_t const & start, Temporal::timepos_t const & end, double y0, double y1, std::list<SelectableOwner*> const & ignored, ARDOUR::SelectionOperation op, bool preserve_if_selected)
{ {
EC_LOCAL_TEMPO_SCOPE;
std::list<Selectable*> found; std::list<Selectable*> found;
if (!view) { if (!view) {
@ -1741,6 +1882,8 @@ Pianoroll::select_all_within (Temporal::timepos_t const & start, Temporal::timep
void void
Pianoroll::set_session (ARDOUR::Session* s) Pianoroll::set_session (ARDOUR::Session* s)
{ {
EC_LOCAL_TEMPO_SCOPE;
CueEditor::set_session (s); CueEditor::set_session (s);
if (with_transport_controls) { if (with_transport_controls) {
@ -1753,9 +1896,7 @@ Pianoroll::set_session (ARDOUR::Session* s)
map_transport_state (); map_transport_state ();
} }
if (!_session) { if (_session) {
_update_connection.disconnect ();
} else {
zoom_to_show (timecnt_t (timepos_t (max_extents_scale() * max_zoom_extent ().second.samples()))); zoom_to_show (timecnt_t (timepos_t (max_extents_scale() * max_zoom_extent ().second.samples())));
} }
} }
@ -1763,6 +1904,8 @@ Pianoroll::set_session (ARDOUR::Session* s)
void void
Pianoroll::map_transport_state () Pianoroll::map_transport_state ()
{ {
EC_LOCAL_TEMPO_SCOPE;
if (!_session) { if (!_session) {
loop_button.unset_active_state (); loop_button.unset_active_state ();
play_button.unset_active_state (); play_button.unset_active_state ();
@ -1800,6 +1943,8 @@ Pianoroll::map_transport_state ()
bool bool
Pianoroll::allow_trim_cursors () const Pianoroll::allow_trim_cursors () const
{ {
EC_LOCAL_TEMPO_SCOPE;
auto mouse_mode = current_mouse_mode (); auto mouse_mode = current_mouse_mode ();
return mouse_mode == Editing::MouseContent || mouse_mode == Editing::MouseTimeFX; return mouse_mode == Editing::MouseContent || mouse_mode == Editing::MouseTimeFX;
} }
@ -1807,6 +1952,8 @@ Pianoroll::allow_trim_cursors () const
void void
Pianoroll::shift_midi (timepos_t const & t, bool model) Pianoroll::shift_midi (timepos_t const & t, bool model)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (!view) { if (!view) {
return; return;
} }
@ -1817,6 +1964,8 @@ Pianoroll::shift_midi (timepos_t const & t, bool model)
InstrumentInfo* InstrumentInfo*
Pianoroll::instrument_info () const Pianoroll::instrument_info () const
{ {
EC_LOCAL_TEMPO_SCOPE;
if (!view || !view->midi_track()) { if (!view || !view->midi_track()) {
return nullptr; return nullptr;
} }
@ -1827,6 +1976,8 @@ Pianoroll::instrument_info () const
void void
Pianoroll::update_tempo_based_rulers () Pianoroll::update_tempo_based_rulers ()
{ {
EC_LOCAL_TEMPO_SCOPE;
if (!_session) { if (!_session) {
return; return;
} }
@ -1839,6 +1990,8 @@ Pianoroll::update_tempo_based_rulers ()
void void
Pianoroll::set_note_selection (uint8_t note) Pianoroll::set_note_selection (uint8_t note)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (!view) { if (!view) {
return; return;
} }
@ -1853,6 +2006,8 @@ Pianoroll::set_note_selection (uint8_t note)
void void
Pianoroll::add_note_selection (uint8_t note) Pianoroll::add_note_selection (uint8_t note)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (!view) { if (!view) {
return; return;
} }
@ -1867,6 +2022,8 @@ Pianoroll::add_note_selection (uint8_t note)
void void
Pianoroll::extend_note_selection (uint8_t note) Pianoroll::extend_note_selection (uint8_t note)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (!view) { if (!view) {
return; return;
} }
@ -1881,6 +2038,8 @@ Pianoroll::extend_note_selection (uint8_t note)
void void
Pianoroll::toggle_note_selection (uint8_t note) Pianoroll::toggle_note_selection (uint8_t note)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (!view) { if (!view) {
return; return;
} }
@ -1895,6 +2054,8 @@ Pianoroll::toggle_note_selection (uint8_t note)
void void
Pianoroll::begin_write () Pianoroll::begin_write ()
{ {
EC_LOCAL_TEMPO_SCOPE;
if (view) { if (view) {
view->begin_write (); view->begin_write ();
} }
@ -1903,6 +2064,8 @@ Pianoroll::begin_write ()
void void
Pianoroll::end_write () Pianoroll::end_write ()
{ {
EC_LOCAL_TEMPO_SCOPE;
if (view) { if (view) {
view->end_write (); view->end_write ();
} }
@ -1911,6 +2074,8 @@ Pianoroll::end_write ()
void void
Pianoroll::manage_possible_header (Gtk::Allocation& alloc) Pianoroll::manage_possible_header (Gtk::Allocation& alloc)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (prh) { if (prh) {
double w, h; double w, h;
prh->size_request (w, h); prh->size_request (w, h);
@ -1922,6 +2087,8 @@ Pianoroll::manage_possible_header (Gtk::Allocation& alloc)
void void
Pianoroll::show_count_in (std::string const & str) Pianoroll::show_count_in (std::string const & str)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (view) { if (view) {
view->set_overlay_text (str); view->set_overlay_text (str);
} }
@ -1930,6 +2097,8 @@ Pianoroll::show_count_in (std::string const & str)
void void
Pianoroll::hide_count_in () Pianoroll::hide_count_in ()
{ {
EC_LOCAL_TEMPO_SCOPE;
if (view) { if (view) {
view->hide_overlay_text (); view->hide_overlay_text ();
} }
@ -1938,6 +2107,8 @@ Pianoroll::hide_count_in ()
void void
Pianoroll::instant_save () Pianoroll::instant_save ()
{ {
EC_LOCAL_TEMPO_SCOPE;
region_ui_settings.draw_length = draw_length(); region_ui_settings.draw_length = draw_length();
region_ui_settings.draw_velocity = draw_velocity(); region_ui_settings.draw_velocity = draw_velocity();
region_ui_settings.channel = draw_channel(); region_ui_settings.channel = draw_channel();
@ -1950,6 +2121,8 @@ Pianoroll::instant_save ()
void void
Pianoroll::parameter_changed (std::string param) Pianoroll::parameter_changed (std::string param)
{ {
EC_LOCAL_TEMPO_SCOPE;
if (param == X_("note-name-display")) { if (param == X_("note-name-display")) {
if (prh) { if (prh) {
prh->instrument_info_change (); prh->instrument_info_change ();

View file

@ -278,14 +278,9 @@ public:
virtual void hide_track_in_display (TimeAxisView* tv, bool apply_to_selection = false) = 0; virtual void hide_track_in_display (TimeAxisView* tv, bool apply_to_selection = false) = 0;
virtual void show_track_in_display (TimeAxisView* tv, bool move_into_view = false) = 0; virtual void show_track_in_display (TimeAxisView* tv, bool move_into_view = false) = 0;
virtual void set_stationary_playhead (bool yn) = 0;
virtual void toggle_stationary_playhead () = 0;
virtual bool stationary_playhead() const = 0;
virtual void toggle_cue_behavior () = 0; virtual void toggle_cue_behavior () = 0;
/** @return true if the playhead is currently being dragged, otherwise false */ /** @return true if the playhead is currently being dragged, otherwise false */
virtual bool dragging_playhead () const = 0;
virtual samplepos_t leftmost_sample() const = 0; virtual samplepos_t leftmost_sample() const = 0;
virtual samplecnt_t current_page_samples() const = 0; virtual samplecnt_t current_page_samples() const = 0;
virtual double visible_canvas_height () const = 0; virtual double visible_canvas_height () const = 0;

View file

@ -141,8 +141,8 @@ RegionUISettingsManager::save (std::string const & path)
state_tree.set_root (&get_state()); state_tree.set_root (&get_state());
state_tree.set_filename (path); state_tree.set_filename (path);
if (state_tree.write()) { if (!state_tree.write()) {
error << string_compose (_("could not save region GUI settings to %1"), path) << endmsg; error << string_compose (_("Could not save region GUI settings to %1"), path) << endmsg;
} }
} }

View file

@ -126,10 +126,10 @@ UI_CONFIG_VARIABLE (uint32_t, action_table_columns, "action-table-columns", 3)
UI_CONFIG_VARIABLE (bool, hide_splash_screen, "hide-splash-screen", true) UI_CONFIG_VARIABLE (bool, hide_splash_screen, "hide-splash-screen", true)
UI_CONFIG_VARIABLE (bool, check_announcements, "check-announcements,", true) UI_CONFIG_VARIABLE (bool, check_announcements, "check-announcements,", true)
UI_CONFIG_VARIABLE (bool, use_wm_visibility, "use-wm-visibility", true) UI_CONFIG_VARIABLE (bool, use_wm_visibility, "use-wm-visibility", true)
UI_CONFIG_VARIABLE (std::string, stripable_color_palette, "stripable-color-palette", "#AA3939:#FFAAAA:#D46A6A:#801515:#550000:#AA8E39:#FFEAAA:#D4BA6A:#806515:#554000:#343477:#8080B3:#565695:#1A1A59:#09093B:#2D882D:#88CC88:#55AA55:#116611:#004400") /* Gtk::ColorSelection::palette_to_string */
UI_CONFIG_VARIABLE (bool, use_palette_for_new_track, "use-palette-for-new-track", true) UI_CONFIG_VARIABLE (bool, use_palette_for_new_track, "use-palette-for-new-track", true)
UI_CONFIG_VARIABLE (bool, use_palette_for_new_bus, "use-palette-for-new-bus", true) UI_CONFIG_VARIABLE (bool, use_palette_for_new_bus, "use-palette-for-new-bus", true)
UI_CONFIG_VARIABLE (bool, use_palette_for_new_vca, "use-palette-for-new-vca", true) UI_CONFIG_VARIABLE (bool, use_palette_for_new_vca, "use-palette-for-new-vca", true)
UI_CONFIG_VARIABLE (std::string, stripable_color_palette, "stripable-color-palette", "#AA3939:#FFAAAA:#D46A6A:#801515:#550000:#AA8E39:#FFEAAA:#D4BA6A:#806515:#554000:#343477:#8080B3:#565695:#1A1A59:#09093B:#2D882D:#88CC88:#55AA55:#116611:#004400") /* Gtk::ColorSelection::palette_to_string */
UI_CONFIG_VARIABLE (bool, use_note_bars_for_velocity, "use-note-bars-for-velocity", true) UI_CONFIG_VARIABLE (bool, use_note_bars_for_velocity, "use-note-bars-for-velocity", true)
UI_CONFIG_VARIABLE (bool, use_note_color_for_velocity, "use-note-color-for-velocity", true) UI_CONFIG_VARIABLE (bool, use_note_color_for_velocity, "use-note-color-for-velocity", true)
UI_CONFIG_VARIABLE (bool, show_snapped_cursor, "show-snapped-cursor", true) UI_CONFIG_VARIABLE (bool, show_snapped_cursor, "show-snapped-cursor", true)

View file

@ -327,9 +327,9 @@ VelocityDisplay::drag_lolli (ArdourCanvas::Lollipop* l, GdkEventMotion* ev)
snprintf (buf, sizeof (buf), "Velocity %d (%d)", verbose_velocity, verbose_velocity - oldvel); snprintf (buf, sizeof (buf), "Velocity %d (%d)", verbose_velocity, verbose_velocity - oldvel);
} }
editing_context.verbose_cursor()->set (buf); editing_context.verbose_cursor().set (buf);
editing_context.verbose_cursor()->show (); editing_context.verbose_cursor().show ();
editing_context.verbose_cursor()->set_offset (ArdourCanvas::Duple (10., 10.)); editing_context.verbose_cursor().set_offset (ArdourCanvas::Duple (10., 10.));
} }
int int

View file

@ -291,6 +291,8 @@ class LIBARDOUR_API AudioRegion : public Region, public AudioReadable
int _set_state (const XMLNode&, int version, PBD::PropertyChange& what_changed, bool send_signal); int _set_state (const XMLNode&, int version, PBD::PropertyChange& what_changed, bool send_signal);
void send_change (const PBD::PropertyChange&); void send_change (const PBD::PropertyChange&);
void ensure_length_sanity (); void ensure_length_sanity ();
void set_tempo_stuff_from_source ();
}; };
} /* namespace ARDOUR */ } /* namespace ARDOUR */

View file

@ -117,6 +117,7 @@ namespace PBD {
LIBARDOUR_API extern DebugBits WiimoteControl; LIBARDOUR_API extern DebugBits WiimoteControl;
LIBARDOUR_API extern DebugBits Freesound; LIBARDOUR_API extern DebugBits Freesound;
LIBARDOUR_API extern DebugBits ClipRecording; LIBARDOUR_API extern DebugBits ClipRecording;
LIBARDOUR_API extern DebugBits TempoEstimation;
} }
} }

View file

@ -157,6 +157,8 @@ class LIBARDOUR_API MidiRegion : public Region
void model_shifted (timecnt_t qn_distance); void model_shifted (timecnt_t qn_distance);
void model_automation_state_changed (Evoral::Parameter const &); void model_automation_state_changed (Evoral::Parameter const &);
void set_tempo_stuff_from_source ();
std::set<Evoral::Parameter> _filtered_parameters; ///< parameters that we ask our source not to return when reading std::set<Evoral::Parameter> _filtered_parameters; ///< parameters that we ask our source not to return when reading
PBD::ScopedConnection _model_connection; PBD::ScopedConnection _model_connection;
PBD::ScopedConnection _model_shift_connection; PBD::ScopedConnection _model_shift_connection;

View file

@ -29,6 +29,7 @@
#include "temporal/domain_swap.h" #include "temporal/domain_swap.h"
#include "temporal/timeline.h" #include "temporal/timeline.h"
#include "temporal/range.h" #include "temporal/range.h"
#include "temporal/tempo.h"
#include "pbd/undo.h" #include "pbd/undo.h"
#include "pbd/signals.h" #include "pbd/signals.h"
@ -541,6 +542,9 @@ public:
} }
} }
Temporal::Tempo tempo() const { return _tempo; }
Temporal::Meter meter() const { return _meter; }
protected: protected:
virtual XMLNode& state () const; virtual XMLNode& state () const;
@ -593,6 +597,9 @@ protected:
uint32_t _fx_tail; uint32_t _fx_tail;
RegionFxList _plugins; RegionFxList _plugins;
Temporal::Tempo _tempo;
Temporal::Meter _meter;
PBD::Property<bool> _sync_marked; PBD::Property<bool> _sync_marked;
PBD::Property<bool> _left_of_split; PBD::Property<bool> _left_of_split;
PBD::Property<bool> _right_of_split; PBD::Property<bool> _right_of_split;

View file

@ -44,10 +44,15 @@
class XMLNode; class XMLNode;
namespace Temporal {
class Meter;
}
namespace ARDOUR { namespace ARDOUR {
class Route; class Route;
class Track; class Track;
class Region;
LIBARDOUR_API std::string legalize_for_path (const std::string& str); LIBARDOUR_API std::string legalize_for_path (const std::string& str);
LIBARDOUR_API std::string legalize_for_universal_path (const std::string& str); LIBARDOUR_API std::string legalize_for_universal_path (const std::string& str);
@ -146,6 +151,8 @@ template<typename T> std::shared_ptr<AutomationControlList> stripable_list_to_co
return cl; return cl;
} }
LIBARDOUR_API bool estimate_audio_tempo (std::shared_ptr<Region> region, Sample* data, samplecnt_t data_length, samplecnt_t sample_rate, double& qpm, Temporal::Meter& meter, double& beatcount);
#if __APPLE__ #if __APPLE__
LIBARDOUR_API std::string CFStringRefToStdString(CFStringRef stringRef); LIBARDOUR_API std::string CFStringRefToStdString(CFStringRef stringRef);
#endif // __APPLE__ #endif // __APPLE__

View file

@ -433,6 +433,21 @@ AudioRegion::~AudioRegion ()
} }
} }
void
AudioRegion::set_tempo_stuff_from_source ()
{
samplecnt_t data_size = _session.sample_rate() * 10;
std::unique_ptr<Sample> data (new Sample[data_size]);
if (read (data.get(), 0, data_size, 0) == data_size) {
double tempo;
double beatcount;
estimate_audio_tempo (shared_from_this(), data.get(), data_size, _session.sample_rate(), tempo, _meter, beatcount);
_tempo = Temporal::Tempo (tempo, 4);
}
}
void void
AudioRegion::post_set (const PropertyChange& /*ignored*/) AudioRegion::post_set (const PropertyChange& /*ignored*/)
{ {
@ -2740,4 +2755,3 @@ AudioRegion::ensure_length_sanity ()
_length = timecnt_t (timepos_t (_length.val().samples()), _length.val().position()); _length = timecnt_t (timepos_t (_length.val().samples()), _length.val().position());
} }
} }

View file

@ -113,3 +113,4 @@ PBD::DebugBits PBD::DEBUG::VSTCallbacks = PBD::new_debug_bit ("vstcallbacks");
PBD::DebugBits PBD::DEBUG::WiimoteControl = PBD::new_debug_bit ("wiimotecontrol"); PBD::DebugBits PBD::DEBUG::WiimoteControl = PBD::new_debug_bit ("wiimotecontrol");
PBD::DebugBits PBD::DEBUG::Freesound = PBD::new_debug_bit ("freesound"); PBD::DebugBits PBD::DEBUG::Freesound = PBD::new_debug_bit ("freesound");
PBD::DebugBits PBD::DEBUG::ClipRecording = PBD::new_debug_bit ("cliprecording"); PBD::DebugBits PBD::DEBUG::ClipRecording = PBD::new_debug_bit ("cliprecording");
PBD::DebugBits PBD::DEBUG::TempoEstimation = PBD::new_debug_bit ("tempoestimation");

View file

@ -3528,7 +3528,7 @@ LuaBindings::non_rt (lua_State* L)
.addFunction ("add_master_bus", &Session::add_master_bus) .addFunction ("add_master_bus", &Session::add_master_bus)
.endClass () .endClass ()
.deriveWSPtrClass <Route, Stripable> ("Route") .beginWSPtrClass <Route> ("Route")
.addFunction ("save_as_template", &Route::save_as_template) .addFunction ("save_as_template", &Route::save_as_template)
.addFunction ("add_sidechain", &Route::add_sidechain) .addFunction ("add_sidechain", &Route::add_sidechain)
.addFunction ("remove_sidechain", &Route::remove_sidechain) .addFunction ("remove_sidechain", &Route::remove_sidechain)

View file

@ -70,6 +70,8 @@ MidiRegion::MidiRegion (const SourceList& srcs)
: Region (srcs) : Region (srcs)
, _ignore_shift (false) , _ignore_shift (false)
{ {
set_tempo_stuff_from_source ();
/* by default MIDI regions are transparent, /* by default MIDI regions are transparent,
* this should probably be set depending on use-case, * this should probably be set depending on use-case,
* (eg. loop recording, vs copy/edit/paste) * (eg. loop recording, vs copy/edit/paste)
@ -106,6 +108,26 @@ MidiRegion::~MidiRegion ()
{ {
} }
void
MidiRegion::set_tempo_stuff_from_source ()
{
std::shared_ptr<Evoral::SMF> smf = std::dynamic_pointer_cast<Evoral::SMF> (midi_source ());
assert (smf);
bool provided;
Temporal::TempoMap::SharedPtr new_map (smf->tempo_map (provided));
if (!provided) {
new_map.reset (new Temporal::TempoMap());
}
Temporal::TempoPoint const tp (new_map->tempo_at (start()));
Temporal::MeterPoint const mp (new_map->meter_at (start()));
_tempo = tp;
_meter = mp;
}
/** Export the MIDI data of the MidiRegion to a new MIDI file (SMF). /** Export the MIDI data of the MidiRegion to a new MIDI file (SMF).
*/ */
bool bool

View file

@ -228,7 +228,9 @@ Region::register_properties ()
} }
#define REGION_DEFAULT_STATE(s,l) \ #define REGION_DEFAULT_STATE(s,l) \
_sync_marked (Properties::sync_marked, false) \ _tempo (120, 4) \
, _meter (4, 4) \
, _sync_marked (Properties::sync_marked, false) \
, _left_of_split (Properties::left_of_split, false) \ , _left_of_split (Properties::left_of_split, false) \
, _right_of_split (Properties::right_of_split, false) \ , _right_of_split (Properties::right_of_split, false) \
, _valid_transients (Properties::valid_transients, false) \ , _valid_transients (Properties::valid_transients, false) \
@ -259,7 +261,9 @@ Region::register_properties ()
, _contents (Properties::contents, false) , _contents (Properties::contents, false)
#define REGION_COPY_STATE(other) \ #define REGION_COPY_STATE(other) \
_sync_marked (Properties::sync_marked, other->_sync_marked) \ _tempo (other->_tempo) \
, _meter (other->_meter) \
, _sync_marked (Properties::sync_marked, other->_sync_marked) \
, _left_of_split (Properties::left_of_split, other->_left_of_split) \ , _left_of_split (Properties::left_of_split, other->_left_of_split) \
, _right_of_split (Properties::right_of_split, other->_right_of_split) \ , _right_of_split (Properties::right_of_split, other->_right_of_split) \
, _valid_transients (Properties::valid_transients, other->_valid_transients) \ , _valid_transients (Properties::valid_transients, other->_valid_transients) \
@ -1420,6 +1424,9 @@ Region::state () const
node->set_property ("id", id ()); node->set_property ("id", id ());
node->set_property ("type", _type); node->set_property ("type", _type);
node->add_child_nocopy (_tempo.get_state());
node->add_child_nocopy (_meter.get_state());
std::string fe; std::string fe;
switch (_first_edit) { switch (_first_edit) {
@ -1619,6 +1626,10 @@ Region::_set_state (const XMLNode& node, int version, PropertyChange& what_chang
} }
_plugins.push_back (rfx); _plugins.push_back (rfx);
changed = true; changed = true;
} else if (child->name() == Temporal::Tempo::xml_node_name) {
_tempo.set_state (*child, version);
} else if (child->name() == Temporal::Meter::xml_node_name) {
_meter.set_state (*child, version);
} }
} }
lm.release (); lm.release ();

View file

@ -1773,123 +1773,11 @@ AudioTrigger::set_region_in_worker_thread_internal (std::shared_ptr<Region> r, b
void void
AudioTrigger::estimate_tempo () AudioTrigger::estimate_tempo ()
{ {
using namespace Temporal; double beatcount;
TempoMap::SharedPtr tm (TempoMap::use()); ARDOUR::estimate_audio_tempo (_region, data[0], data.length, _box.session().sample_rate(), _estimated_tempo, _meter, beatcount);
/* initialize our follow_length to match the beatcnt ... user can later change this value to have the clip end sooner or later than its data length */
set_follow_length(Temporal::BBT_Offset( 0, rint(beatcount), 0));
TimelineRange range (_region->start(), _region->start() + _region->length(), 0);
SegmentDescriptor segment;
bool have_segment;
have_segment = _region->source (0)->get_segment_descriptor (range, segment);
if (have_segment) {
_estimated_tempo = segment.tempo().quarter_notes_per_minute ();
_meter = segment.meter();
DEBUG_TRACE (DEBUG::Triggers, string_compose ("%1: tempo and meter from segment descriptor\n", index()));
} else {
/* not a great guess, but what else can we do? */
TempoMetric const & metric (tm->metric_at (timepos_t (AudioTime)));
_meter = metric.meter ();
/* check the name to see if there's a (heuristically obvious) hint
* about the tempo.
*/
string str = _region->name();
string::size_type bi;
string::size_type ni;
double text_tempo = -1.;
if (((bi = str.find (" bpm")) != string::npos) ||
((bi = str.find ("bpm")) != string::npos) ||
((bi = str.find (" BPM")) != string::npos) ||
((bi = str.find ("BPM")) != string::npos) ){
string sub (str.substr (0, bi));
if ((ni = sub.find_last_of ("0123456789.,_-")) != string::npos) {
int nni = ni; /* ni is unsigned, nni is signed */
while (nni >= 0) {
if (!isdigit (sub[nni]) &&
(sub[nni] != '.') &&
(sub[nni] != ',')) {
break;
}
--nni;
}
if (nni > 0) {
std::stringstream p (sub.substr (nni + 1));
p >> text_tempo;
if (!p) {
text_tempo = -1.;
} else {
_estimated_tempo = text_tempo;
}
}
}
}
if (text_tempo < 0) {
breakfastquay::MiniBPM mbpm (_box.session().sample_rate());
_estimated_tempo = mbpm.estimateTempoOfSamples (data[0], data.length);
//cerr << name() << "MiniBPM Estimated: " << _estimated_tempo << " bpm from " << (double) data.length / _box.session().sample_rate() << " seconds\n";
}
}
const double seconds = (double) data.length / _box.session().sample_rate();
/* now check the determined tempo and force it to a value that gives us
an integer beat/quarter count. This is a heuristic that tries to
avoid clips that slightly over- or underrun a quantization point,
resulting in small or larger gaps in output if they are repeating.
*/
if ((_estimated_tempo != 0.)) {
/* fractional beatcnt */
double maybe_beats = (seconds / 60.) * _estimated_tempo;
double beatcount = round (maybe_beats);
/* the vast majority of third-party clips are 1,2,4,8, or 16-bar 'beats'.
* Given no other metadata, it makes things 'just work' if we assume 4/4 time signature, and power-of-2 bars (1,2,4,8 or 16)
* TODO: someday we could provide a widget for users who have unlabeled, un-metadata'd, clips that they *know* are 3/4 or 5/4 or 11/4 */
{
double barcount = round (beatcount/4);
if (barcount <= 18) { /* why not 16 here? fuzzy logic allows minibpm to misjudge the clip a bit */
for (int pwr = 0; pwr <= 4; pwr++) {
float bc = pow(2,pwr);
if (barcount <= bc) {
barcount = bc;
break;
}
}
}
beatcount = round(barcount * 4);
}
DEBUG_RESULT (double, est, _estimated_tempo);
_estimated_tempo = beatcount / (seconds/60.);
DEBUG_TRACE (DEBUG::Triggers, string_compose ("given original estimated tempo %1, rounded beatcnt is %2 : resulting in working bpm = %3\n", est, _beatcnt, _estimated_tempo));
/* initialize our follow_length to match the beatcnt ... user can later change this value to have the clip end sooner or later than its data length */
set_follow_length(Temporal::BBT_Offset( 0, rint(beatcount), 0));
}
#if 0
cerr << "estimated tempo: " << _estimated_tempo << endl;
const samplecnt_t one_beat = tm->bbt_duration_at (timepos_t (AudioTime), BBT_Offset (0, 1, 0)).samples();
cerr << "one beat in samples: " << one_beat << endl;
cerr << "rounded beatcount = " << round (beatcount) << endl;
#endif
} }
bool bool
@ -2757,14 +2645,9 @@ SegmentDescriptor
MIDITrigger::get_segment_descriptor () const MIDITrigger::get_segment_descriptor () const
{ {
SegmentDescriptor sd; SegmentDescriptor sd;
std::shared_ptr<MidiRegion> mr = std::dynamic_pointer_cast<MidiRegion> (_region);
assert (mr);
sd.set_extent (Temporal::Beats(), mr->length().beats());
/* we don't really have tempo information for MIDI yet */
sd.set_tempo (Temporal::Tempo (120, 4));
sd.set_extent (Temporal::Beats(), _region->length().beats());
sd.set_tempo (_region->tempo());
return sd; return sd;
} }

View file

@ -60,8 +60,15 @@
#include "pbd/strsplit.h" #include "pbd/strsplit.h"
#include "pbd/replace_all.h" #include "pbd/replace_all.h"
#include "ardour/utils.h" #include "temporal/tempo.h"
#include "ardour/debug.h"
#include "ardour/minibpm.h"
#include "ardour/region.h"
#include "ardour/rc_configuration.h" #include "ardour/rc_configuration.h"
#include "ardour/segment_descriptor.h"
#include "ardour/source.h"
#include "ardour/utils.h"
#include "pbd/i18n.h" #include "pbd/i18n.h"
@ -793,3 +800,126 @@ ARDOUR::compute_sha1_of_file (std::string path)
sha1_result_hash (&s, hash); sha1_result_hash (&s, hash);
return std::string (hash); return std::string (hash);
} }
bool
ARDOUR::estimate_audio_tempo (std::shared_ptr<Region> region, Sample* data, samplecnt_t data_length, samplecnt_t sample_rate, double& qpm, Temporal::Meter& meter, double& beatcount)
{
using namespace Temporal;
TempoMap::SharedPtr tm (TempoMap::use());
TimelineRange range (region->start(), region->start() + region->length(), 0);
SegmentDescriptor segment;
bool have_segment;
have_segment = region->source (0)->get_segment_descriptor (range, segment);
if (have_segment) {
qpm = segment.tempo().quarter_notes_per_minute ();
meter = segment.meter();
DEBUG_TRACE (DEBUG::TempoEstimation, string_compose ("%1: tempo and meter from segment descriptor\n", region->name()));
} else {
/* not a great guess, but what else can we do? */
TempoMetric const & metric (tm->metric_at (timepos_t (AudioTime)));
meter = metric.meter ();
/* check the name to see if there's a (heuristically obvious) hint
* about the tempo.
*/
string str = region->name();
string::size_type bi;
string::size_type ni;
double text_tempo = -1.;
if (((bi = str.find (" bpm")) != string::npos) ||
((bi = str.find ("bpm")) != string::npos) ||
((bi = str.find (" BPM")) != string::npos) ||
((bi = str.find ("BPM")) != string::npos) ){
string sub (str.substr (0, bi));
if ((ni = sub.find_last_of ("0123456789.,_-")) != string::npos) {
int nni = ni; /* ni is unsigned, nni is signed */
while (nni >= 0) {
if (!isdigit (sub[nni]) &&
(sub[nni] != '.') &&
(sub[nni] != ',')) {
break;
}
--nni;
}
if (nni > 0) {
std::stringstream p (sub.substr (nni + 1));
p >> text_tempo;
if (!p) {
text_tempo = -1.;
} else {
qpm = text_tempo;
}
}
}
}
if (text_tempo < 0) {
breakfastquay::MiniBPM mbpm (sample_rate);
qpm = mbpm.estimateTempoOfSamples (data, data_length);
//cerr << name() << "MiniBPM Estimated: " << qpm << " bpm from " << (double) data.length / _box.session().sample_rate() << " seconds\n";
}
}
const double seconds = (double) data_length / sample_rate;
/* now check the determined tempo and force it to a value that gives us
an integer beat/quarter count. This is a heuristic that tries to
avoid clips that slightly over- or underrun a quantization point,
resulting in small or larger gaps in output if they are repeating.
*/
if ((qpm != 0.)) {
/* fractional beatcnt */
double maybe_beats = (seconds / 60.) * qpm;
beatcount = round (maybe_beats);
/* the vast majority of third-party clips are 1,2,4,8, or 16-bar 'beats'.
* Given no other metadata, it makes things 'just work' if we assume 4/4 time signature, and power-of-2 bars (1,2,4,8 or 16)
* TODO: someday we could provide a widget for users who have unlabeled, un-metadata'd, clips that they *know* are 3/4 or 5/4 or 11/4 */
{
double barcount = round (beatcount/4);
if (barcount <= 18) { /* why not 16 here? fuzzy logic allows minibpm to misjudge the clip a bit */
for (int pwr = 0; pwr <= 4; pwr++) {
float bc = pow(2,pwr);
if (barcount <= bc) {
barcount = bc;
break;
}
}
}
beatcount = round(barcount * 4);
}
DEBUG_RESULT (double, est, qpm);
qpm = beatcount / (seconds/60.);
DEBUG_TRACE (DEBUG::TempoEstimation, string_compose ("given original estimated tempo %1, rounded beatcnt is %2 : resulting in working bpm = %3\n", est, beatcount, qpm));
}
#if 0
cerr << "estimated tempo: " << qpm << endl;
const samplecnt_t one_beat = tm->bbt_duration_at (timepos_t (AudioTime), BBT_Offset (0, 1, 0)).samples();
cerr << "one beat in samples: " << one_beat << endl;
cerr << "rounded beatcount = " << round (beatcount) << endl;
#endif
return true;
}

View file

@ -1883,20 +1883,33 @@ ControlList::rt_safe_earliest_event_linear_unlocked (Temporal::timepos_t const&
} }
/* This method is ONLY used for interpolating to generate value/time /* This method is ONLY used for interpolating to generate value/time
* duples not present in the actual ControlList, and because of this, * duples not present in the actual ControlList
* the desired time domain is always audio time.
*/ */
double a = first->when.superclocks (); double slope;
double b = next->when.superclocks ();
const double slope = (b - a) / (next->value - first->value); if (time_domain() == Temporal::AudioTime) {
assert (slope != 0); double a = first->when.superclocks ();
double b = next->when.superclocks ();
slope = (b - a) / (next->value - first->value);
assert (slope != 0);
double t = start_time.superclocks ();
double dt = fmod (t, fabs (slope));
t += fabs (slope) - dt;
x = timecnt_t::from_superclock (t + 1);
y = rint (first->value + (t - a) / slope);
} else {
double a = first->when.beats().to_ticks();
double b = next->when.beats().to_ticks();
slope = (b - a) / (next->value - first->value);
assert (slope != 0);
double t = start_time.beats ().to_ticks();
double dt = fmod (t, fabs (slope));
t += fabs (slope) - dt;
x = timecnt_t::from_ticks (t + 1);
y = rint (first->value + (t - a) / slope);
}
double t = start_time.superclocks ();
double dt = fmod (t, fabs (slope));
t += fabs (slope) - dt;
x = timecnt_t::from_superclock (t + 1);
y = rint (first->value + (t - a) / slope);
if (slope > 0) { if (slope > 0) {
y = std::max (first->value, std::min (next->value, y)); y = std::max (first->value, std::min (next->value, y));
} else { } else {

View file

@ -234,7 +234,7 @@ Strip::set_stripable (std::shared_ptr<Stripable> r, bool /*with_messages*/)
_stripable->solo_control()->Changed.connect (stripable_connections, MISSING_INVALIDATOR, std::bind (&Strip::notify_solo_changed, this), ui_context()); _stripable->solo_control()->Changed.connect (stripable_connections, MISSING_INVALIDATOR, std::bind (&Strip::notify_solo_changed, this), ui_context());
_stripable->mute_control()->Changed.connect(stripable_connections, MISSING_INVALIDATOR, std::bind (&Strip::notify_mute_changed, this), ui_context()); _stripable->mute_control()->Changed.connect(stripable_connections, MISSING_INVALIDATOR, std::bind (&Strip::notify_mute_changed, this), ui_context());
_stripable->MappedControlsChanged.connect (stripable_connections, MISSING_INVALIDATOR, std::bind (&Strip::notify_eq_type_changed, this), ui_context()); _stripable->MappedControlsChanged.connect (stripable_connections, MISSING_INVALIDATOR, std::bind (&Strip::notify_subview_type_changed, this), ui_context());
std::shared_ptr<AutomationControl> pan_control = _stripable->pan_azimuth_control(); std::shared_ptr<AutomationControl> pan_control = _stripable->pan_azimuth_control();
if (pan_control) { if (pan_control) {
@ -350,7 +350,7 @@ Strip::notify_record_enable_changed ()
} }
void void
Strip::notify_eq_type_changed () Strip::notify_subview_type_changed ()
{ {
if (_stripable) { if (_stripable) {
_surface->mcp().MackieControlProtocol::redisplay_subview_mode(); _surface->mcp().MackieControlProtocol::redisplay_subview_mode();
@ -719,6 +719,17 @@ Strip::remove_units (std::string s) {
s = std::regex_replace (s, std::regex(" dB$"), ""); s = std::regex_replace (s, std::regex(" dB$"), "");
s = std::regex_replace (s, std::regex(" ms$"), ""); s = std::regex_replace (s, std::regex(" ms$"), "");
// convert seconds to milliseconds
if (s.rfind(" s") != string::npos) {
char buf[32];
s = std::regex_replace (s, std::regex(" s$"), "");
if (sprintf(buf, "%2.0f", 1000.0*stof(s)) >= 0) {
s = std::string (buf);
} else {
DEBUG_TRACE (DEBUG::MackieControl, "couldn't convert string to float\n");
}
}
return s; return s;
} }

View file

@ -157,7 +157,7 @@ private:
void notify_solo_changed (); void notify_solo_changed ();
void notify_mute_changed (); void notify_mute_changed ();
void notify_record_enable_changed (); void notify_record_enable_changed ();
void notify_eq_type_changed (); void notify_subview_type_changed ();
void notify_gain_changed (bool force_update = true); void notify_gain_changed (bool force_update = true);
void notify_property_changed (const PBD::PropertyChange&); void notify_property_changed (const PBD::PropertyChange&);
void notify_panner_azi_changed (bool force_update = true); void notify_panner_azi_changed (bool force_update = true);

View file

@ -278,6 +278,7 @@ void NoneSubview::setup_vpot(
EQSubview::EQSubview(MackieControlProtocol& mcp, std::shared_ptr<ARDOUR::Stripable> subview_stripable) EQSubview::EQSubview(MackieControlProtocol& mcp, std::shared_ptr<ARDOUR::Stripable> subview_stripable)
: Subview(mcp, subview_stripable) : Subview(mcp, subview_stripable)
, _current_bank(0)
{} {}
EQSubview::~EQSubview() EQSubview::~EQSubview()
@ -308,8 +309,8 @@ void EQSubview::setup_vpot(
Pot* vpot, Pot* vpot,
std::string pending_display[2]) std::string pending_display[2])
{ {
const uint32_t global_strip_position = _mcp.global_index (*strip); const uint32_t global_strip_position = _mcp.global_index (*strip) + _current_bank;
store_pointers(strip, vpot, pending_display, global_strip_position); store_pointers(strip, vpot, pending_display, global_strip_position - _current_bank);
if (!_subview_stripable) { if (!_subview_stripable) {
return; return;
@ -357,6 +358,18 @@ void EQSubview::setup_vpot(
pc = _subview_stripable->mapped_control(EQ_Enable); pc = _subview_stripable->mapped_control(EQ_Enable);
pot_id = "EQ"; pot_id = "EQ";
break; break;
case 11:
pc = _subview_stripable->mapped_control(LPF_Freq);
pot_id = "LPF";
break;
case 12:
pc = _subview_stripable->mapped_control(HPF_Freq);
pot_id = "HPF";
break;
case 13:
pc = _subview_stripable->mapped_control(HPF_Enable); // shared HP/LP
pot_id = "Filter";
break;
} }
} else { //mixbus or master bus ( these are currently the same for MB & 32C ) } else { //mixbus or master bus ( these are currently the same for MB & 32C )
@ -402,7 +415,7 @@ void EQSubview::notify_change (std::weak_ptr<ARDOUR::AutomationControl> pc, uint
Strip* strip = 0; Strip* strip = 0;
Pot* vpot = 0; Pot* vpot = 0;
std::string* pending_display = 0; std::string* pending_display = 0;
if (!retrieve_pointers(&strip, &vpot, &pending_display, global_strip_position)) if (!retrieve_pointers(&strip, &vpot, &pending_display, global_strip_position - _current_bank))
{ {
return; return;
} }
@ -416,10 +429,32 @@ void EQSubview::notify_change (std::weak_ptr<ARDOUR::AutomationControl> pc, uint
} }
} }
bool EQSubview::handle_cursor_left_press()
{
if (_current_bank >= 1)
{
_current_bank -= 1;
mcp().redisplay_subview_mode();
}
return true;
}
bool EQSubview::handle_cursor_right_press()
{
if (/* todo: generate this value on redisplay */ 14 > _current_bank + 1) {
_current_bank += 1;
mcp().redisplay_subview_mode();
}
return true;
}
DynamicsSubview::DynamicsSubview(MackieControlProtocol& mcp, std::shared_ptr<ARDOUR::Stripable> subview_stripable) DynamicsSubview::DynamicsSubview(MackieControlProtocol& mcp, std::shared_ptr<ARDOUR::Stripable> subview_stripable)
: Subview(mcp, subview_stripable) : Subview(mcp, subview_stripable)
, _current_bank(0)
{} {}
DynamicsSubview::~DynamicsSubview() DynamicsSubview::~DynamicsSubview()
@ -450,54 +485,46 @@ void DynamicsSubview::setup_vpot(
Pot* vpot, Pot* vpot,
std::string pending_display[2]) std::string pending_display[2])
{ {
const uint32_t global_strip_position = _mcp.global_index (*strip); const uint32_t global_strip_position = _mcp.global_index (*strip) + _current_bank;
store_pointers(strip, vpot, pending_display, global_strip_position); store_pointers(strip, vpot, pending_display, global_strip_position - _current_bank);
if (!_subview_stripable) { if (!_subview_stripable) {
return; return;
} }
std::shared_ptr<AutomationControl> hpfc = _subview_stripable->mapped_control (HPF_Freq); available.clear();
std::shared_ptr<AutomationControl> lpfc = _subview_stripable->mapped_control (LPF_Freq);
std::shared_ptr<AutomationControl> fec = _subview_stripable->mapped_control (HPF_Enable); // shared HP/LP
std::shared_ptr<AutomationControl> cec = _subview_stripable->mapped_control (Comp_Enable);
std::shared_ptr<AutomationControl> ctc = _subview_stripable->mapped_control (Comp_Threshold); std::shared_ptr<AutomationControl> ctc = _subview_stripable->mapped_control (Comp_Threshold);
std::shared_ptr<AutomationControl> crc = _subview_stripable->mapped_control (Comp_Ratio); std::shared_ptr<AutomationControl> crc = _subview_stripable->mapped_control (Comp_Ratio);
std::shared_ptr<AutomationControl> cac = _subview_stripable->mapped_control (Comp_Attack); std::shared_ptr<AutomationControl> cac = _subview_stripable->mapped_control (Comp_Attack);
std::shared_ptr<AutomationControl> csc = _subview_stripable->mapped_control (Comp_Release); std::shared_ptr<AutomationControl> csc = _subview_stripable->mapped_control (Comp_Release);
std::shared_ptr<AutomationControl> ckc = _subview_stripable->mapped_control (Comp_Makeup); std::shared_ptr<AutomationControl> ckc = _subview_stripable->mapped_control (Comp_Makeup);
std::shared_ptr<AutomationControl> cec = _subview_stripable->mapped_control (Comp_Enable);
std::shared_ptr<AutomationControl> gec = _subview_stripable->mapped_control (Gate_Enable);
std::shared_ptr<AutomationControl> gtc = _subview_stripable->mapped_control (Gate_Threshold); std::shared_ptr<AutomationControl> gtc = _subview_stripable->mapped_control (Gate_Threshold);
std::shared_ptr<AutomationControl> gdc = _subview_stripable->mapped_control (Gate_Depth); std::shared_ptr<AutomationControl> gdc = _subview_stripable->mapped_control (Gate_Depth);
std::shared_ptr<AutomationControl> gac = _subview_stripable->mapped_control (Gate_Attack); std::shared_ptr<AutomationControl> gac = _subview_stripable->mapped_control (Gate_Attack);
std::shared_ptr<AutomationControl> gsc = _subview_stripable->mapped_control (Gate_Release); std::shared_ptr<AutomationControl> gsc = _subview_stripable->mapped_control (Gate_Release);
std::shared_ptr<AutomationControl> gec = _subview_stripable->mapped_control (Gate_Enable);
/* we will control the global_strip_position-th available parameter, from the list in the /* we will control the global_strip_position-th available parameter, from the list in the
* order shown above. * order shown above.
*/ */
std::vector<std::pair<std::shared_ptr<AutomationControl>, std::string > > available;
std::vector<AutomationType> params; std::vector<AutomationType> params;
//Mixbus32C needs to spill the filter controls into the comp section if (cec) { available.push_back (std::make_pair (cec, "Comp")); }
if (hpfc) { available.push_back (std::make_pair (hpfc, "HPF")); } if (ctc) { available.push_back (std::make_pair (ctc, "CThrsh")); }
if (lpfc) { available.push_back (std::make_pair (lpfc, "LPF")); } if (crc) { available.push_back (std::make_pair (crc, "CRatio")); }
if (fec) { available.push_back (std::make_pair (fec, "FiltIn")); } if (cac) { available.push_back (std::make_pair (cac, "CAttk")); }
if (csc) { available.push_back (std::make_pair (csc, "CRels")); }
if (ckc) { available.push_back (std::make_pair (ckc, "CMkup")); }
if (ctc) { available.push_back (std::make_pair (ctc, "Thresh")); } if (gec) { available.push_back (std::make_pair (gec, "Gate")); }
if (crc) { available.push_back (std::make_pair (crc, "Ratio")); } if (gtc) { available.push_back (std::make_pair (gtc, "GThrsh")); }
if (cac) { available.push_back (std::make_pair (cac, "Attk")); } if (gdc) { available.push_back (std::make_pair (gdc, "GDepth")); }
if (csc) { available.push_back (std::make_pair (csc, "Rels")); } if (gac) { available.push_back (std::make_pair (gac, "GAttk")); }
if (ckc) { available.push_back (std::make_pair (ckc, "Makeup")); } if (gsc) { available.push_back (std::make_pair (gsc, "GRels")); }
if (cec) { available.push_back (std::make_pair (cec, "on/off")); }
if (gtc) { available.push_back (std::make_pair (gtc, "Thresh")); }
if (gdc) { available.push_back (std::make_pair (gdc, "Depth")); }
if (gac) { available.push_back (std::make_pair (gac, "Attk")); }
if (gsc) { available.push_back (std::make_pair (gsc, "Rels")); }
if (gec) { available.push_back (std::make_pair (gec, "on/off")); }
if (global_strip_position >= available.size()) { if (global_strip_position >= available.size()) {
/* this knob is not needed to control the available parameters */ /* this knob is not needed to control the available parameters */
@ -535,7 +562,7 @@ DynamicsSubview::notify_change (std::weak_ptr<ARDOUR::AutomationControl> pc, uin
Strip* strip = 0; Strip* strip = 0;
Pot* vpot = 0; Pot* vpot = 0;
std::string* pending_display = 0; std::string* pending_display = 0;
if (!retrieve_pointers(&strip, &vpot, &pending_display, global_strip_position)) if (!retrieve_pointers(&strip, &vpot, &pending_display, global_strip_position - _current_bank))
{ {
return; return;
} }
@ -550,16 +577,33 @@ DynamicsSubview::notify_change (std::weak_ptr<ARDOUR::AutomationControl> pc, uin
if (control) { if (control) {
float val = control->get_value(); float val = control->get_value();
if (control == _subview_stripable->mapped_control (Comp_Mode)) { pending_display[1] = Strip::remove_units(control->get_user_string());
pending_display[1] = control->get_user_string ();
} else {
do_parameter_display(pending_display[1], control->desc(), val, strip, true);
}
/* update pot/encoder */ /* update pot/encoder */
strip->surface()->write (vpot->set (control->internal_to_interface (val), true, Pot::wrap)); strip->surface()->write (vpot->set (control->internal_to_interface (val), true, Pot::wrap));
} }
} }
bool DynamicsSubview::handle_cursor_left_press()
{
if (_current_bank >= 1)
{
_current_bank -= 1;
mcp().redisplay_subview_mode();
}
return true;
}
bool DynamicsSubview::handle_cursor_right_press()
{
if (available.size() > _current_bank + 1) {
_current_bank += 1;
mcp().redisplay_subview_mode();
}
return true;
}
SendsSubview::SendsSubview(MackieControlProtocol& mcp, std::shared_ptr<ARDOUR::Stripable> subview_stripable) SendsSubview::SendsSubview(MackieControlProtocol& mcp, std::shared_ptr<ARDOUR::Stripable> subview_stripable)

View file

@ -127,6 +127,10 @@ class EQSubview : public Subview {
Pot* vpot, Pot* vpot,
std::string pending_display[2]); std::string pending_display[2]);
void notify_change (std::weak_ptr<ARDOUR::AutomationControl>, uint32_t global_strip_position, bool force); void notify_change (std::weak_ptr<ARDOUR::AutomationControl>, uint32_t global_strip_position, bool force);
virtual bool handle_cursor_left_press();
virtual bool handle_cursor_right_press();
protected:
uint32_t _current_bank;
}; };
class DynamicsSubview : public Subview { class DynamicsSubview : public Subview {
@ -142,6 +146,11 @@ class DynamicsSubview : public Subview {
Pot* vpot, Pot* vpot,
std::string pending_display[2]); std::string pending_display[2]);
void notify_change (std::weak_ptr<ARDOUR::AutomationControl>, uint32_t global_strip_position, bool force, bool propagate_mode_change); void notify_change (std::weak_ptr<ARDOUR::AutomationControl>, uint32_t global_strip_position, bool force, bool propagate_mode_change);
virtual bool handle_cursor_left_press();
virtual bool handle_cursor_right_press();
protected:
uint32_t _current_bank;
std::vector<std::pair<std::shared_ptr<ARDOUR::AutomationControl>, std::string>> available;
}; };
class SendsSubview : public Subview { class SendsSubview : public Subview {

View file

@ -18,5 +18,7 @@
<true/> <true/>
<key>com.apple.security.device.usb</key> <key>com.apple.security.device.usb</key>
<true/> <true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
</dict> </dict>
</plist> </plist>