diff options
44 files changed, 314 insertions, 252 deletions
diff --git a/gtk2_ardour/ardour_knob.cc b/gtk2_ardour/ardour_knob.cc index f7e4a939f2..8cea0f4a4d 100644 --- a/gtk2_ardour/ardour_knob.cc +++ b/gtk2_ardour/ardour_knob.cc @@ -365,14 +365,14 @@ ArdourKnob::on_motion_notify_event (GdkEventMotion *ev) delta = tozero + remain; _dead_zone_delta = 0; } else { - c->set_value (c->normal()); + c->set_value (c->normal(), Controllable::NoGroup); _dead_zone_delta = remain / px_deadzone; return true; } } if (fabsf (rintf((val - _normal) / scale) + _dead_zone_delta) < 1) { - c->set_value (c->normal()); + c->set_value (c->normal(), Controllable::NoGroup); _dead_zone_delta += delta / px_deadzone; return true; } @@ -430,7 +430,7 @@ ArdourKnob::on_button_release_event (GdkEventButton *ev) if ( (_grabbed_y == ev->y && _grabbed_x == ev->x) && Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) { //no move, shift-click sets to default boost::shared_ptr<PBD::Controllable> c = binding_proxy.get_controllable(); if (!c) return false; - c->set_value (c->normal()); + c->set_value (c->normal(), Controllable::NoGroup); return true; } diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 665da7dcf1..3efd815951 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -4687,7 +4687,7 @@ ARDOUR_UI::TransportControllable::TransportControllable (std::string name, ARDOU } void -ARDOUR_UI::TransportControllable::set_value (double val) +ARDOUR_UI::TransportControllable::set_value (double val, PBD::Controllable::GroupControlDisposition /*group_override*/) { if (val < 0.5) { /* do nothing: these are radio-style actions */ diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h index cc800a2e2f..d08dd9aeef 100644 --- a/gtk2_ardour/ardour_ui.h +++ b/gtk2_ardour/ardour_ui.h @@ -430,7 +430,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr }; TransportControllable (std::string name, ARDOUR_UI&, ToggleType); - void set_value (double); + void set_value (double, PBD::Controllable::GroupControlDisposition group_override); double get_value (void) const; ARDOUR_UI& ui; diff --git a/gtk2_ardour/automation_controller.cc b/gtk2_ardour/automation_controller.cc index dd2d71d9cd..3ae1b2184f 100644 --- a/gtk2_ardour/automation_controller.cc +++ b/gtk2_ardour/automation_controller.cc @@ -40,6 +40,8 @@ using namespace ARDOUR; using namespace Gtk; +using PBD::Controllable; + AutomationBarController::AutomationBarController ( boost::shared_ptr<Automatable> printer, boost::shared_ptr<AutomationControl> ac, @@ -153,7 +155,7 @@ void AutomationController::value_adjusted () { if (!_ignore_change) { - _controllable->set_value (_controllable->interface_to_internal(_adjustment->get_value())); + _controllable->set_value (_controllable->interface_to_internal(_adjustment->get_value()), Controllable::NoGroup); } /* A bar controller will automatically follow the adjustment, but for a @@ -248,7 +250,7 @@ AutomationController::run_note_select_dialog() const double value = ((_controllable->desc().unit == ARDOUR::ParameterDescriptor::HZ) ? midi_note_to_hz(dialog->note_number()) : dialog->note_number()); - _controllable->set_value(clamp(value, desc.lower, desc.upper)); + _controllable->set_value(clamp(value, desc.lower, desc.upper), Controllable::NoGroup); } delete dialog; } @@ -263,7 +265,7 @@ AutomationController::set_freq_beats(double beats) const double bpm = tempo.beats_per_minute(); const double bps = bpm / 60.0; const double freq = bps / beats; - _controllable->set_value(clamp(freq, desc.lower, desc.upper)); + _controllable->set_value(clamp(freq, desc.lower, desc.upper), Controllable::NoGroup); } void @@ -271,7 +273,7 @@ AutomationController::set_ratio(double ratio) { const ARDOUR::ParameterDescriptor& desc = _controllable->desc(); const double value = _controllable->get_value() * ratio; - _controllable->set_value(clamp(value, desc.lower, desc.upper)); + _controllable->set_value(clamp(value, desc.lower, desc.upper), Controllable::NoGroup); } bool diff --git a/gtk2_ardour/generic_pluginui.cc b/gtk2_ardour/generic_pluginui.cc index 47b5f93a98..ef2de43309 100644 --- a/gtk2_ardour/generic_pluginui.cc +++ b/gtk2_ardour/generic_pluginui.cc @@ -923,7 +923,7 @@ GenericPluginUI::control_port_toggled (ControlUI* cui) } else { cui->button->set_name ("PluginEditorButton"); } - insert->automation_control (cui->parameter())->set_value (active); + insert->automation_control (cui->parameter())->set_value (active, Controllable::NoGroup); cui->ignore_change--; } @@ -932,7 +932,7 @@ GenericPluginUI::control_combo_changed (ControlUI* cui) { if (!cui->ignore_change && cui->scale_points) { string value = cui->combo->get_active_text(); - insert->automation_control (cui->parameter())->set_value ((*cui->scale_points)[value]); + insert->automation_control (cui->parameter())->set_value ((*cui->scale_points)[value], Controllable::NoGroup); } } diff --git a/gtk2_ardour/lv2_plugin_ui.cc b/gtk2_ardour/lv2_plugin_ui.cc index 20f59b5e83..fe6b3c70bd 100644 --- a/gtk2_ardour/lv2_plugin_ui.cc +++ b/gtk2_ardour/lv2_plugin_ui.cc @@ -59,7 +59,7 @@ LV2PluginUI::write_from_ui(void* controller, me->_updates.insert (port_index); if (ac) { - ac->set_value(*(const float*)buffer); + ac->set_value(*(const float*)buffer, Controllable::NoGroup); } } else if (format == URIMap::instance().urids.atom_eventTransfer) { diff --git a/gtk2_ardour/mono_panner.cc b/gtk2_ardour/mono_panner.cc index 23b64eee28..0dd54ef6ac 100644 --- a/gtk2_ardour/mono_panner.cc +++ b/gtk2_ardour/mono_panner.cc @@ -51,6 +51,8 @@ using namespace Gtk; using namespace Gtkmm2ext; using namespace ARDOUR_UI_UTILS; +using PBD::Controllable; + MonoPanner::ColorScheme MonoPanner::colors; bool MonoPanner::have_colors = false; @@ -318,11 +320,11 @@ MonoPanner::on_button_press_event (GdkEventButton* ev) if (ev->x <= width/3) { /* left side dbl click */ - position_control->set_value (0); + position_control->set_value (0, Controllable::NoGroup); } else if (ev->x > 2*width/3) { - position_control->set_value (1.0); + position_control->set_value (1.0, Controllable::NoGroup); } else { - position_control->set_value (0.5); + position_control->set_value (0.5, Controllable::NoGroup); } _dragging = false; @@ -393,12 +395,12 @@ MonoPanner::on_scroll_event (GdkEventScroll* ev) case GDK_SCROLL_UP: case GDK_SCROLL_LEFT: pv -= step; - position_control->set_value (pv); + position_control->set_value (pv, Controllable::NoGroup); break; case GDK_SCROLL_DOWN: case GDK_SCROLL_RIGHT: pv += step; - position_control->set_value (pv); + position_control->set_value (pv, Controllable::NoGroup); break; } @@ -423,7 +425,7 @@ MonoPanner::on_motion_notify_event (GdkEventMotion* ev) if (!detented && ARDOUR::Panner::equivalent (position_control->get_value(), 0.5)) { detented = true; /* snap to center */ - position_control->set_value (0.5); + position_control->set_value (0.5, Controllable::NoGroup); } if (detented) { @@ -432,13 +434,13 @@ MonoPanner::on_motion_notify_event (GdkEventMotion* ev) /* have we pulled far enough to escape ? */ if (fabs (accumulated_delta) >= 0.025) { - position_control->set_value (position_control->get_value() + accumulated_delta); + position_control->set_value (position_control->get_value() + accumulated_delta, Controllable::NoGroup); detented = false; accumulated_delta = false; } } else { double pv = position_control->get_value(); // 0..1.0 ; 0 = left - position_control->set_value (pv + delta); + position_control->set_value (pv + delta, Controllable::NoGroup); } last_drag_x = ev->x; @@ -465,15 +467,15 @@ MonoPanner::on_key_press_event (GdkEventKey* ev) switch (ev->keyval) { case GDK_Left: pv -= step; - position_control->set_value (pv); + position_control->set_value (pv, Controllable::NoGroup); break; case GDK_Right: pv += step; - position_control->set_value (pv); + position_control->set_value (pv, Controllable::NoGroup); break; case GDK_0: case GDK_KP_0: - position_control->set_value (0.0); + position_control->set_value (0.0, Controllable::NoGroup); break; default: return false; diff --git a/gtk2_ardour/mono_panner_editor.cc b/gtk2_ardour/mono_panner_editor.cc index 134c812822..5a9a0927c5 100644 --- a/gtk2_ardour/mono_panner_editor.cc +++ b/gtk2_ardour/mono_panner_editor.cc @@ -29,6 +29,8 @@ using namespace Gtk; using namespace Gtkmm2ext; +using PBD::Controllable; + MonoPannerEditor::MonoPannerEditor (MonoPanner* p) : PannerEditor (_("Mono Panner")) , _panner (p) @@ -98,7 +100,7 @@ MonoPannerEditor::left_changed () _ignore_changes = true; _right.set_value (100 * v); - _panner->get_controllable()->set_value (v); + _panner->get_controllable()->set_value (v, Controllable::NoGroup); _ignore_changes = false; } @@ -113,7 +115,7 @@ MonoPannerEditor::right_changed () _ignore_changes = true; _left.set_value (100 * (1 - v)); - _panner->get_controllable()->set_value (v); + _panner->get_controllable()->set_value (v, Controllable::NoGroup); _ignore_changes = false; } diff --git a/gtk2_ardour/processor_box.cc b/gtk2_ardour/processor_box.cc index d1de736e57..29e230920c 100644 --- a/gtk2_ardour/processor_box.cc +++ b/gtk2_ardour/processor_box.cc @@ -711,7 +711,7 @@ ProcessorEntry::Control::slider_adjusted () return; } - c->set_value ( c->interface_to_internal(_adjustment.get_value ()) ); + c->set_value ( c->interface_to_internal(_adjustment.get_value ()) , Controllable::NoGroup); set_tooltip (); } @@ -726,7 +726,7 @@ ProcessorEntry::Control::button_clicked () bool const n = _button.get_active (); - c->set_value (n ? 0 : 1); + c->set_value (n ? 0 : 1, Controllable::NoGroup); _button.set_active (!n); set_tooltip (); } diff --git a/gtk2_ardour/shuttle_control.cc b/gtk2_ardour/shuttle_control.cc index 94c27c2807..4616b76734 100644 --- a/gtk2_ardour/shuttle_control.cc +++ b/gtk2_ardour/shuttle_control.cc @@ -678,7 +678,7 @@ ShuttleControl::ShuttleControllable::ShuttleControllable (ShuttleControl& s) } void -ShuttleControl::ShuttleControllable::set_value (double val) +ShuttleControl::ShuttleControllable::set_value (double val, PBD::Controllable::GroupControlDisposition /*group_override*/) { sc.set_shuttle_fract ((val - lower()) / (upper() - lower()), true); } diff --git a/gtk2_ardour/shuttle_control.h b/gtk2_ardour/shuttle_control.h index ed15a12bdf..20fe46096f 100644 --- a/gtk2_ardour/shuttle_control.h +++ b/gtk2_ardour/shuttle_control.h @@ -46,7 +46,7 @@ class ShuttleControl : public CairoWidget, public ARDOUR::SessionHandlePtr struct ShuttleControllable : public PBD::Controllable { ShuttleControllable (ShuttleControl&); - void set_value (double); + void set_value (double, PBD::Controllable::GroupControlDisposition group_override); double get_value (void) const; double lower() const { return -1.0; } diff --git a/gtk2_ardour/stereo_panner.cc b/gtk2_ardour/stereo_panner.cc index 91c8b025ac..304300fcdb 100644 --- a/gtk2_ardour/stereo_panner.cc +++ b/gtk2_ardour/stereo_panner.cc @@ -52,6 +52,8 @@ using namespace Gtk; using namespace Gtkmm2ext; using namespace ARDOUR_UI_UTILS; +using PBD::Controllable; + StereoPanner::ColorScheme StereoPanner::colors[3]; bool StereoPanner::have_colors = false; @@ -355,21 +357,21 @@ StereoPanner::on_button_press_event (GdkEventButton* ev) /* left side dbl click */ if (Keyboard::modifier_state_contains (ev->state, Keyboard::SecondaryModifier)) { /* 2ndary-double click on left, collapse to hard left */ - width_control->set_value (0); - position_control->set_value (0); + width_control->set_value (0, Controllable::NoGroup); + position_control->set_value (0, Controllable::NoGroup); } else { - position_control->set_value (min_pos); + position_control->set_value (min_pos, Controllable::NoGroup); } } else if (ev->x > 2*width/3) { if (Keyboard::modifier_state_contains (ev->state, Keyboard::SecondaryModifier)) { /* 2ndary-double click on right, collapse to hard right */ - width_control->set_value (0); - position_control->set_value (1.0); + width_control->set_value (0, Controllable::NoGroup); + position_control->set_value (1.0, Controllable::NoGroup); } else { - position_control->set_value (max_pos); + position_control->set_value (max_pos, Controllable::NoGroup); } } else { - position_control->set_value (0.5); + position_control->set_value (0.5, Controllable::NoGroup); } } else { @@ -381,13 +383,13 @@ StereoPanner::on_button_press_event (GdkEventButton* ev) if (ev->x <= width/3) { /* left side dbl click */ - width_control->set_value (max_width); // reset width to 100% + width_control->set_value (max_width, Controllable::NoGroup); // reset width to 100% } else if (ev->x > 2*width/3) { /* right side dbl click */ - width_control->set_value (-max_width); // reset width to inverted 100% + width_control->set_value (-max_width, Controllable::NoGroup); // reset width to inverted 100% } else { /* center dbl click */ - width_control->set_value (0); // collapse width to 0% + width_control->set_value (0, Controllable::NoGroup); // collapse width to 0% } } @@ -500,19 +502,19 @@ StereoPanner::on_scroll_event (GdkEventScroll* ev) switch (ev->direction) { case GDK_SCROLL_LEFT: wv += step; - width_control->set_value (wv); + width_control->set_value (wv, Controllable::NoGroup); break; case GDK_SCROLL_UP: pv -= step; - position_control->set_value (pv); + position_control->set_value (pv, Controllable::NoGroup); break; case GDK_SCROLL_RIGHT: wv -= step; - width_control->set_value (wv); + width_control->set_value (wv, Controllable::NoGroup); break; case GDK_SCROLL_DOWN: pv += step; - position_control->set_value (pv); + position_control->set_value (pv, Controllable::NoGroup); break; } @@ -551,9 +553,9 @@ StereoPanner::on_motion_notify_event (GdkEventMotion* ev) double pv = position_control->get_value(); if (dragging_left) { - position_control->set_value (pv - delta); + position_control->set_value (pv - delta, Controllable::NoGroup); } else { - position_control->set_value (pv + delta); + position_control->set_value (pv + delta, Controllable::NoGroup); } if (delta > 0.0) { @@ -563,9 +565,9 @@ StereoPanner::on_motion_notify_event (GdkEventMotion* ev) other side remains in place when we set the position as well. */ - width_control->set_value (current_width + (delta * 2.0)); + width_control->set_value (current_width + (delta * 2.0), Controllable::NoGroup); } else { - width_control->set_value (current_width + delta); + width_control->set_value (current_width + delta, Controllable::NoGroup); } _panner->thaw (); @@ -579,7 +581,7 @@ StereoPanner::on_motion_notify_event (GdkEventMotion* ev) if (!detented && fabs (current_width) < 0.02) { detented = true; /* snap to zero */ - width_control->set_value (0); + width_control->set_value (0, Controllable::NoGroup); } if (detented) { @@ -589,21 +591,21 @@ StereoPanner::on_motion_notify_event (GdkEventMotion* ev) /* have we pulled far enough to escape ? */ if (fabs (accumulated_delta) >= 0.025) { - width_control->set_value (current_width + accumulated_delta); + width_control->set_value (current_width + accumulated_delta, Controllable::NoGroup); detented = false; accumulated_delta = false; } } else { /* width needs to change by 2 * delta because both L & R move */ - width_control->set_value (current_width + (delta * 2.0)); + width_control->set_value (current_width + (delta * 2.0), Controllable::NoGroup); } } } else if (dragging_position) { double pv = position_control->get_value(); // 0..1.0 ; 0 = left - position_control->set_value (pv + delta); + position_control->set_value (pv + delta, Controllable::NoGroup); } last_drag_x = ev->x; @@ -635,30 +637,30 @@ StereoPanner::on_key_press_event (GdkEventKey* ev) switch (ev->keyval) { case GDK_Up: if (Keyboard::modifier_state_equals (ev->state, Keyboard::SecondaryModifier)) { - width_control->set_value (1.0); + width_control->set_value (1.0, Controllable::NoGroup); } else { - width_control->set_value (wv + step); + width_control->set_value (wv + step, Controllable::NoGroup); } break; case GDK_Down: if (Keyboard::modifier_state_equals (ev->state, Keyboard::SecondaryModifier)) { - width_control->set_value (-1.0); + width_control->set_value (-1.0, Controllable::NoGroup); } else { - width_control->set_value (wv - step); + width_control->set_value (wv - step, Controllable::NoGroup); } break; case GDK_Left: pv -= step; - position_control->set_value (pv); + position_control->set_value (pv, Controllable::NoGroup); break; case GDK_Right: pv += step; - position_control->set_value (pv); + position_control->set_value (pv, Controllable::NoGroup); break; case GDK_0: case GDK_KP_0: - width_control->set_value (0.0); + width_control->set_value (0.0, Controllable::NoGroup); break; default: diff --git a/gtk2_ardour/stereo_panner_editor.cc b/gtk2_ardour/stereo_panner_editor.cc index e7a4a452fe..477a6650a4 100644 --- a/gtk2_ardour/stereo_panner_editor.cc +++ b/gtk2_ardour/stereo_panner_editor.cc @@ -31,6 +31,8 @@ using namespace std; using namespace Gtk; using namespace Gtkmm2ext; +using PBD::Controllable; + StereoPannerEditor::StereoPannerEditor (StereoPanner* p) : PannerEditor (_("Stereo Panner")) , _panner (p) @@ -103,7 +105,7 @@ StereoPannerEditor::position_changed () _ignore_changes = true; double const v = _position.get_value() / 100; - _panner->get_position_controllable()->set_value (v); + _panner->get_position_controllable()->set_value (v, Controllable::NoGroup); set_width_range (); _ignore_changes = false; } @@ -117,7 +119,7 @@ StereoPannerEditor::width_changed () _ignore_changes = true; double const v = _width.get_value() / 100; - _panner->get_width_controllable()->set_value (v); + _panner->get_width_controllable()->set_value (v, Controllable::NoGroup); set_position_range (); _ignore_changes = false; } diff --git a/libs/ardour/amp.cc b/libs/ardour/amp.cc index 955dd13ccc..924a77e666 100644 --- a/libs/ardour/amp.cc +++ b/libs/ardour/amp.cc @@ -368,7 +368,7 @@ Amp::inc_gain (gain_t factor, void *src) void Amp::set_gain (gain_t val, void *) { - _gain_control->set_value (val); + _gain_control->set_value (val, Controllable::NoGroup); } XMLNode& @@ -396,7 +396,7 @@ Amp::set_state (const XMLNode& node, int version) } void -Amp::GainControl::set_value (double val) +Amp::GainControl::set_value (double val, PBD::Controllable::GroupControlDisposition /* group_override */) { if (writable()) { set_value_unchecked (val); @@ -406,7 +406,7 @@ Amp::GainControl::set_value (double val) void Amp::GainControl::set_value_unchecked (double val) { - AutomationControl::set_value (std::max (std::min (val, (double)_desc.upper), (double)_desc.lower)); + AutomationControl::set_value (std::max (std::min (val, (double)_desc.upper), (double)_desc.lower), Controllable::NoGroup); _amp->session().set_dirty (); } diff --git a/libs/ardour/ardour/amp.h b/libs/ardour/ardour/amp.h index e8445c4853..c92edcc5fc 100644 --- a/libs/ardour/ardour/amp.h +++ b/libs/ardour/ardour/amp.h @@ -92,7 +92,7 @@ public: range_db = accurate_coefficient_to_dB (_desc.upper) - lower_db; } - void set_value (double val); + void set_value (double val, PBD::Controllable::GroupControlDisposition group_override); void set_value_unchecked (double); double internal_to_interface (double) const; diff --git a/libs/ardour/ardour/automation_control.h b/libs/ardour/ardour/automation_control.h index b26d781e2f..0d065686e2 100644 --- a/libs/ardour/ardour/automation_control.h +++ b/libs/ardour/ardour/automation_control.h @@ -85,9 +85,12 @@ public: * Derived classes MUST call ::writable() to verify * that writing to the parameter is legal at that time. */ - void set_value (double); double get_value () const; - + /* inherited from PBD::Controllable. + * Derived classes MUST call ::writable() to verify + * that writing to the parameter is legal at that time. + */ + void set_value (double value, PBD::Controllable::GroupControlDisposition group_override); /* automation related value setting */ virtual bool writable () const; /* Call to ::set_value() with no test for writable() because @@ -110,7 +113,6 @@ public: void commit_transaction (bool did_write); protected: - ARDOUR::Session& _session; const ParameterDescriptor _desc; diff --git a/libs/ardour/ardour/midi_track.h b/libs/ardour/ardour/midi_track.h index 80bb743b10..ba418082f8 100644 --- a/libs/ardour/ardour/midi_track.h +++ b/libs/ardour/ardour/midi_track.h @@ -89,7 +89,7 @@ public: , _route (route) {} - void set_value (double val); + void set_value (double val, PBD::Controllable::GroupControlDisposition group_override); void set_value_unchecked (double); bool writable() const { return true; } diff --git a/libs/ardour/ardour/monitor_processor.h b/libs/ardour/ardour/monitor_processor.h index c7d73dca00..ffee1fbbd2 100644 --- a/libs/ardour/ardour/monitor_processor.h +++ b/libs/ardour/ardour/monitor_processor.h @@ -54,7 +54,7 @@ public: /* Controllable API */ - void set_value (double v) { + void set_value (double v, PBD::Controllable::GroupControlDisposition group_override) { T newval = (T) v; if (newval != _value) { _value = std::max (_lower, std::min (_upper, newval)); diff --git a/libs/ardour/ardour/pan_controllable.h b/libs/ardour/ardour/pan_controllable.h index ff00d8119f..77acbee04f 100644 --- a/libs/ardour/ardour/pan_controllable.h +++ b/libs/ardour/ardour/pan_controllable.h @@ -36,7 +36,7 @@ class Pannable; class LIBARDOUR_API PanControllable : public AutomationControl { -public: + public: PanControllable (Session& s, std::string name, Pannable* o, Evoral::Parameter param) : AutomationControl (s, param, @@ -47,10 +47,10 @@ public: {} double lower () const; - void set_value (double); + void set_value (double, PBD::Controllable::GroupControlDisposition group_override); void set_value_unchecked (double); -private: + private: Pannable* owner; }; diff --git a/libs/ardour/ardour/plugin_insert.h b/libs/ardour/ardour/plugin_insert.h index 0873825c02..6b434bef7f 100644 --- a/libs/ardour/ardour/plugin_insert.h +++ b/libs/ardour/ardour/plugin_insert.h @@ -95,7 +95,7 @@ class LIBARDOUR_API PluginInsert : public Processor const ParameterDescriptor& desc, boost::shared_ptr<AutomationList> list=boost::shared_ptr<AutomationList>()); - void set_value (double val); + void set_value (double val, PBD::Controllable::GroupControlDisposition group_override); void set_value_unchecked (double); double get_value (void) const; void catch_up_with_external_value (double val); @@ -113,8 +113,7 @@ class LIBARDOUR_API PluginInsert : public Processor const ParameterDescriptor& desc, boost::shared_ptr<AutomationList> list=boost::shared_ptr<AutomationList>()); - void set_value (const Variant& val); - void set_value (double val); + void set_value (double val, PBD::Controllable::GroupControlDisposition group_override); void set_value_unchecked (double); double get_value (void) const; XMLNode& get_state(); diff --git a/libs/ardour/ardour/proxy_controllable.h b/libs/ardour/ardour/proxy_controllable.h index b2f230ec87..c60f5f1b74 100644 --- a/libs/ardour/ardour/proxy_controllable.h +++ b/libs/ardour/ardour/proxy_controllable.h @@ -31,7 +31,7 @@ namespace ARDOUR { */ class LIBARDOUR_API ProxyControllable : public PBD::Controllable { -public: + public: ProxyControllable (const std::string& name, PBD::Controllable::Flag flags, boost::function1<bool,double> setter, boost::function0<double> getter) @@ -40,7 +40,7 @@ public: , _getter (getter) {} - void set_value (double v) { if (_setter (v)) { Changed(); /* EMIT SIGNAL */ } } + void set_value (double v, PBD::Controllable::GroupControlDisposition /*group_override*/) { if (_setter (v)) { Changed(); /* EMIT SIGNAL */ } } double get_value () const { return _getter (); } double internal_to_user (double i) const { return accurate_coefficient_to_dB (i);} @@ -51,7 +51,7 @@ public: return std::string(theBuf); } -private: + private: boost::function1<bool,double> _setter; boost::function0<double> _getter; }; diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index 0ef063b29c..2086f32119 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -383,23 +383,44 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou /* Controls (not all directly owned by the Route */ + class RouteAutomationControl : public AutomationControl { + public: + RouteAutomationControl (const std::string& name, + AutomationType atype, + boost::shared_ptr<AutomationList> alist, + boost::shared_ptr<Route> route); + + void set_value (double val, PBD::Controllable::GroupControlDisposition group_override) { + boost::shared_ptr<Route> r = _route.lock(); + if (r) { + r->set_control (*this, val, group_override); + } + } + + protected: + friend class Route; + + void route_set_value (double val) { + AutomationControl::set_value (val, Controllable::NoGroup); + } + + boost::weak_ptr<Route> _route; + }; + boost::shared_ptr<AutomationControl> get_control (const Evoral::Parameter& param); - class SoloControllable : public AutomationControl { + class SoloControllable : public RouteAutomationControl { public: SoloControllable (std::string name, boost::shared_ptr<Route>); - void set_value (double); + void set_value (double, PBD::Controllable::GroupControlDisposition group_override); void set_value_unchecked (double); double get_value () const; - - private: - boost::weak_ptr<Route> _route; }; - struct MuteControllable : public AutomationControl { + struct MuteControllable : public RouteAutomationControl { public: MuteControllable (std::string name, boost::shared_ptr<Route>); - void set_value (double); + void set_value (double, PBD::Controllable::GroupControlDisposition group_override); void set_value_unchecked (double); double get_value () const; @@ -410,27 +431,18 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou boost::weak_ptr<Route> _route; }; - class LIBARDOUR_API PhaseControllable : public AutomationControl { + class LIBARDOUR_API PhaseControllable : public RouteAutomationControl { public: PhaseControllable (std::string name, boost::shared_ptr<Route>); - void set_value (double); + void set_value (double, PBD::Controllable::GroupControlDisposition group_override); void set_channel (uint32_t); double get_value () const; uint32_t channel() const; - private: - boost::weak_ptr<Route> _route; uint32_t _current_phase; }; - class LIBARDOUR_API GroupGainControllable : public AutomationControl { - public: - GroupGainControllable (std::string name, boost::shared_ptr<Route>); - void set_value (double); - double get_value () const; - private: - boost::weak_ptr<Route> _route; - }; + void set_control (RouteAutomationControl&, double val, PBD::Controllable::GroupControlDisposition group_override); boost::shared_ptr<SoloControllable> solo_control() const { return _solo_control; @@ -448,10 +460,6 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou return _phase_control; } - boost::shared_ptr<GroupGainControllable> group_gain_control() const { - return _group_gain_control; - } - /* Route doesn't own these items, but sub-objects that it does own have them and to make UI code a bit simpler, we provide direct access to them here. @@ -544,7 +552,7 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou bool has_external_redirects() const; /* can only be executed by a route for which is_monitor() is true - (i.e. the monitor out) + (i.e. the monitor out) */ void monitor_run (framepos_t start_frame, framepos_t end_frame, pframes_t nframes, int declick); @@ -635,7 +643,6 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou boost::shared_ptr<MuteControllable> _mute_control; boost::shared_ptr<MuteMaster> _mute_master; boost::shared_ptr<PhaseControllable> _phase_control; - boost::shared_ptr<GroupGainControllable> _group_gain_control; virtual void act_on_mute () {} @@ -679,7 +686,7 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou int set_state_2X (const XMLNode&, int); void set_processor_state_2X (XMLNodeList const &, int); - uint32_t _order_key; + uint32_t _order_key; bool _has_order_key; uint32_t _remote_control_id; diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h index fa7b1f30bb..5bf887f517 100644 --- a/libs/ardour/ardour/track.h +++ b/libs/ardour/ardour/track.h @@ -206,7 +206,7 @@ class LIBARDOUR_API Track : public Route, public PublicDiskstream struct RecEnableControl : public AutomationControl { RecEnableControl (boost::shared_ptr<Track> t); - void set_value (double); + void set_value (double, PBD::Controllable::GroupControlDisposition); void set_value_unchecked (double); double get_value (void) const; diff --git a/libs/ardour/automation_control.cc b/libs/ardour/automation_control.cc index 1f507b7015..583f38807d 100644 --- a/libs/ardour/automation_control.cc +++ b/libs/ardour/automation_control.cc @@ -72,7 +72,7 @@ AutomationControl::get_value() const * @param value `user' value */ void -AutomationControl::set_value (double value) +AutomationControl::set_value (double value, PBD::Controllable::GroupControlDisposition /* group_override */) { bool to_list = _list && ((AutomationList*)_list.get())->automation_write(); @@ -135,7 +135,7 @@ AutomationControl::start_touch(double when) if (alist()->automation_state() == Touch) { /* subtle. aligns the user value with the playback */ - set_value (get_value ()); + set_value (get_value (), Controllable::NoGroup); alist()->start_touch (when); if (!_desc.toggled) { AutomationWatch::instance().add_automation_watch (shared_from_this()); diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc index 03ba42b6af..69d10c44e0 100644 --- a/libs/ardour/midi_track.cc +++ b/libs/ardour/midi_track.cc @@ -543,7 +543,7 @@ MidiTrack::non_realtime_locate (framepos_t pos) (rcontrol = region->control(tcontrol->parameter()))) { const Evoral::Beats pos_beats = bfc.from(pos - origin); if (rcontrol->list()->size() > 0) { - tcontrol->set_value(rcontrol->list()->eval(pos_beats.to_double())); + tcontrol->set_value(rcontrol->list()->eval(pos_beats.to_double()), Controllable::NoGroup); } } } @@ -725,7 +725,7 @@ MidiTrack::set_parameter_automation_state (Evoral::Parameter param, AutoState st } void -MidiTrack::MidiControl::set_value(double val) +MidiTrack::MidiControl::set_value (double val, PBD::Controllable::GroupControlDisposition /* group_override */) { if (writable()) { set_value_unchecked (val); @@ -790,7 +790,7 @@ MidiTrack::MidiControl::set_value_unchecked(double val) _route->write_immediate_event(size, ev); } - AutomationControl::set_value(val); + AutomationControl::set_value(val, Controllable::NoGroup); } void diff --git a/libs/ardour/monitor_processor.cc b/libs/ardour/monitor_processor.cc index 92beed547c..4264ee7793 100644 --- a/libs/ardour/monitor_processor.cc +++ b/libs/ardour/monitor_processor.cc @@ -37,7 +37,7 @@ using namespace std; /* specialize for bool because of set_value() semantics */ namespace ARDOUR { - template<> void MPControl<bool>::set_value (double v) { + template<> void MPControl<bool>::set_value (double v, PBD::Controllable::GroupControlDisposition /*group_override*/) { bool newval = fabs (v) >= 0.5; if (newval != _value) { _value = newval; diff --git a/libs/ardour/pan_controllable.cc b/libs/ardour/pan_controllable.cc index 71c8a9f62f..faf04cc8d7 100644 --- a/libs/ardour/pan_controllable.cc +++ b/libs/ardour/pan_controllable.cc @@ -35,7 +35,7 @@ PanControllable::lower () const } void -PanControllable::set_value (double v) +PanControllable::set_value (double v, PBD::Controllable::GroupControlDisposition /* group_override */) { if (writable()) { set_value_unchecked (v); @@ -49,7 +49,7 @@ PanControllable::set_value_unchecked (double v) if (!p) { /* no panner: just do it */ - AutomationControl::set_value (v); + AutomationControl::set_value (v, Controllable::NoGroup); return; } @@ -70,7 +70,7 @@ PanControllable::set_value_unchecked (double v) } if (can_set) { - AutomationControl::set_value (v); + AutomationControl::set_value (v, Controllable::NoGroup); } } diff --git a/libs/ardour/pannable.cc b/libs/ardour/pannable.cc index 247397d415..f589024435 100644 --- a/libs/ardour/pannable.cc +++ b/libs/ardour/pannable.cc @@ -242,27 +242,27 @@ Pannable::set_state (const XMLNode& root, int version) if ((*niter)->name() == X_("azimuth")) { prop = (*niter)->property (X_("value")); if (prop) { - pan_azimuth_control->set_value (atof (prop->value())); + pan_azimuth_control->set_value (atof (prop->value()), Controllable::NoGroup); } } else if ((*niter)->name() == X_("width")) { prop = (*niter)->property (X_("value")); if (prop) { - pan_width_control->set_value (atof (prop->value())); + pan_width_control->set_value (atof (prop->value()), Controllable::NoGroup); } } else if ((*niter)->name() == X_("elevation")) { prop = (*niter)->property (X_("value")); if (prop) { - pan_elevation_control->set_value (atof (prop->value())); + pan_elevation_control->set_value (atof (prop->value()), Controllable::NoGroup); } } else if ((*niter)->name() == X_("frontback")) { prop = (*niter)->property (X_("value")); if (prop) { - pan_frontback_control->set_value (atof (prop->value())); + pan_frontback_control->set_value (atof (prop->value()), Controllable::NoGroup); } } else if ((*niter)->name() == X_("lfe")) { prop = (*niter)->property (X_("value")); if (prop) { - pan_lfe_control->set_value (atof (prop->value())); + pan_lfe_control->set_value (atof (prop->value()), Controllable::NoGroup); } } } diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc index 827e6d19f4..77a223880e 100644 --- a/libs/ardour/plugin_insert.cc +++ b/libs/ardour/plugin_insert.cc @@ -660,7 +660,7 @@ PluginInsert::reset_parameters_to_default () continue; } - ac->set_value (dflt); + ac->set_value (dflt, Controllable::NoGroup); } return all; } @@ -1337,7 +1337,7 @@ PluginInsert::PluginControl::PluginControl (PluginInsert* p, /** @param val `user' value */ void -PluginInsert::PluginControl::set_value (double user_val) +PluginInsert::PluginControl::set_value (double user_val, PBD::Controllable::GroupControlDisposition /* group_override */) { if (writable()) { set_value_unchecked (user_val); @@ -1358,13 +1358,13 @@ PluginInsert::PluginControl::set_value_unchecked (double user_val) iasp->set_parameter (_list->parameter().id(), user_val); } - AutomationControl::set_value (user_val); + AutomationControl::set_value (user_val, Controllable::NoGroup); } void PluginInsert::PluginControl::catch_up_with_external_value (double user_val) { - AutomationControl::set_value (user_val); + AutomationControl::set_value (user_val, Controllable::NoGroup); } XMLNode& @@ -1410,7 +1410,7 @@ PluginInsert::PluginPropertyControl::PluginPropertyControl (PluginInsert* } void -PluginInsert::PluginPropertyControl::set_value (double user_val) +PluginInsert::PluginPropertyControl::set_value (double user_val, PBD::Controllable::GroupControlDisposition /* group_override*/) { if (writable()) { set_value_unchecked (user_val); @@ -1434,7 +1434,7 @@ PluginInsert::PluginPropertyControl::set_value_unchecked (double user_val) } _value = value; - AutomationControl::set_value(user_val); + AutomationControl::set_value (user_val, Controllable::NoGroup); } XMLNode& diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index fef1ea14a3..5abe96b263 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -178,11 +178,6 @@ Route::init () _amp->set_display_name ("Monitor"); } - // amp should exist before amp controls - _group_gain_control.reset (new GroupGainControllable (X_("groupgain"), shared_from_this ())); - _group_gain_control->set_flags (Controllable::Flag (_group_gain_control->flags() | Controllable::GainLike)); - add_control (_group_gain_control); - /* and input trim */ _trim.reset (new Amp (_session, "trim")); _trim->set_display_to_user (false); @@ -2804,7 +2799,7 @@ Route::set_state_2X (const XMLNode& node, int version) gain_t val; if (sscanf (prop->value().c_str(), "%f", &val) == 1) { - _amp->gain_control()->set_value (val); + _amp->gain_control()->set_value (val, Controllable::NoGroup); } } @@ -3885,20 +3880,84 @@ Route::set_latency_compensation (framecnt_t longest_session_latency) } } -Route::SoloControllable::SoloControllable (std::string name, boost::shared_ptr<Route> r) - : AutomationControl (r->session(), - Evoral::Parameter (SoloAutomation), - ParameterDescriptor(Evoral::Parameter (SoloAutomation)), - boost::shared_ptr<AutomationList>(), name) +void +Route::set_control (RouteAutomationControl& control, double val, PBD::Controllable::GroupControlDisposition /*group_override*/) +{ + boost::shared_ptr<RouteList> rl; + + switch (control.parameter().type()) { + case GainAutomation: + /* route must mediate group control */ + set_gain (val, this); /* any "src" argument will do other than our route group */ + return; + break; + + case RecEnableAutomation: + /* session must mediate group control */ + rl.reset (new RouteList); + rl->push_back (shared_from_this()); + _session.set_record_enabled (rl, val >= 0.5 ? true : false); + return; + break; + + case SoloAutomation: + /* session must mediate group control */ + rl.reset (new RouteList); + rl->push_back (shared_from_this()); + if (Config->get_solo_control_is_listen_control()) { + _session.set_listen (rl, val >= 0.5 ? true : false); + } else { + _session.set_solo (rl, val >= 0.5 ? true : false); + } + + return; + break; + + case MuteAutomation: + /* session must mediate group control */ + rl.reset (new RouteList); + rl->push_back (shared_from_this()); + _session.set_mute (rl, !muted()); + return; + break; + + case PanAzimuthAutomation: + case PanElevationAutomation: + case PanWidthAutomation: + case PanFrontBackAutomation: + case PanLFEAutomation: + break; + + default: + /* Not a route automation control */ + return; + } + + control.route_set_value (val); +} + + +Route::RouteAutomationControl::RouteAutomationControl (const std::string& name, + AutomationType atype, + boost::shared_ptr<AutomationList> alist, + boost::shared_ptr<Route> r) + : AutomationControl (r->session(), Evoral::Parameter (atype), + ParameterDescriptor (Evoral::Parameter (atype)), + alist, name) , _route (r) { +} + +Route::SoloControllable::SoloControllable (std::string name, boost::shared_ptr<Route> r) + : RouteAutomationControl (name, SoloAutomation, boost::shared_ptr<AutomationList>(), r) +{ boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(SoloAutomation))); gl->set_interpolation(Evoral::ControlList::Discrete); set_list (gl); } void -Route::SoloControllable::set_value (double val) +Route::SoloControllable::set_value (double val, PBD::Controllable::GroupControlDisposition /* group_override */) { if (writable()) { set_value_unchecked (val); @@ -3942,11 +4001,7 @@ Route::SoloControllable::get_value () const } Route::MuteControllable::MuteControllable (std::string name, boost::shared_ptr<Route> r) - : AutomationControl (r->session(), - Evoral::Parameter (MuteAutomation), - ParameterDescriptor (Evoral::Parameter (MuteAutomation)), - boost::shared_ptr<AutomationList>(), - name) + : RouteAutomationControl (name, MuteAutomation, boost::shared_ptr<AutomationList>(), r) , _route (r) { boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(MuteAutomation))); @@ -3979,7 +4034,7 @@ Route::MuteControllable::set_superficial_value(bool muted) } void -Route::MuteControllable::set_value (double val) +Route::MuteControllable::set_value (double val, PBD::Controllable::GroupControlDisposition /* group_override */) { if (writable()) { set_value_unchecked (val); @@ -4022,42 +4077,8 @@ Route::MuteControllable::get_value () const return (r && r->muted()) ? GAIN_COEFF_UNITY : GAIN_COEFF_ZERO; } -Route::GroupGainControllable::GroupGainControllable (std::string name, boost::shared_ptr<Route> r) - : AutomationControl (r->session(), - Evoral::Parameter (GainAutomation), - ParameterDescriptor (Evoral::Parameter (GainAutomation)), - boost::shared_ptr<AutomationList>(), - name) - , _route (r) -{ - boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(GainAutomation))); - gl->set_interpolation(Evoral::ControlList::Discrete); - set_list (gl); -} - -void -Route::GroupGainControllable::set_value (double val) -{ - boost::shared_ptr<Route> r = _route.lock (); - // I am not sure why I need the * .5 to make this work - float normalized_position = r->gain_control()->interface_to_internal (val * 0.5); - r->set_gain ((gain_t)normalized_position, this); -} - -double -Route::GroupGainControllable::get_value () const -{ - boost::shared_ptr<Route> r = _route.lock (); - return 2.0 * r->gain_control()->internal_to_interface (r->gain_control()->get_value ()); -} - Route::PhaseControllable::PhaseControllable (std::string name, boost::shared_ptr<Route> r) - : AutomationControl (r->session(), - Evoral::Parameter (PhaseAutomation), - ParameterDescriptor (Evoral::Parameter (PhaseAutomation)), - boost::shared_ptr<AutomationList>(), - name) - , _route (r) + : RouteAutomationControl (name, PhaseAutomation, boost::shared_ptr<AutomationList>(), r) { boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(PhaseAutomation))); gl->set_interpolation(Evoral::ControlList::Discrete); @@ -4065,7 +4086,7 @@ Route::PhaseControllable::PhaseControllable (std::string name, boost::shared_ptr } void -Route::PhaseControllable::set_value (double v) +Route::PhaseControllable::set_value (double v, PBD::Controllable::GroupControlDisposition /* group_override */) { boost::shared_ptr<Route> r = _route.lock (); if (r->phase_invert().size()) { diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 1c7410002d..2e93d5d167 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -3335,7 +3335,7 @@ Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest) for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { if ((s = (*i)->internal_send_for (dest)) != 0) { - s->amp()->gain_control()->set_value (GAIN_COEFF_ZERO); + s->amp()->gain_control()->set_value (GAIN_COEFF_ZERO, Controllable::NoGroup); } } } @@ -3348,7 +3348,7 @@ Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest) for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { if ((s = (*i)->internal_send_for (dest)) != 0) { - s->amp()->gain_control()->set_value (GAIN_COEFF_UNITY); + s->amp()->gain_control()->set_value (GAIN_COEFF_UNITY, Controllable::NoGroup); } } } @@ -3361,7 +3361,7 @@ Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest) for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { if ((s = (*i)->internal_send_for (dest)) != 0) { - s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value()); + s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value(), Controllable::NoGroup); } } } diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc index c4c82808bd..21256b09ce 100644 --- a/libs/ardour/track.cc +++ b/libs/ardour/track.cc @@ -190,7 +190,7 @@ Track::RecEnableControl::RecEnableControl (boost::shared_ptr<Track> t) } void -Track::RecEnableControl::set_value (double val) +Track::RecEnableControl::set_value (double val, Controllable::GroupControlDisposition /* group_override */) { if (writable()) { set_value_unchecked (val); diff --git a/libs/gtkmm2ext/motionfeedback.cc b/libs/gtkmm2ext/motionfeedback.cc index 0c1a325bb7..0dccdabc2f 100644 --- a/libs/gtkmm2ext/motionfeedback.cc +++ b/libs/gtkmm2ext/motionfeedback.cc @@ -46,6 +46,7 @@ using namespace Gtkmm2ext; using namespace sigc; using PBD::error; +using PBD::Controllable; Gdk::Color* MotionFeedback::base_color; @@ -191,11 +192,11 @@ MotionFeedback::pixwin_button_release_event (GdkEventButton *ev) } if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) { /* shift click back to the default */ - _controllable->set_value (default_value); + _controllable->set_value (default_value, Controllable::NoGroup); return true; } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { /* ctrl click back to the minimum value */ - _controllable->set_value (_controllable->lower ()); + _controllable->set_value (_controllable->lower (), Controllable::NoGroup); } break; @@ -246,7 +247,7 @@ MotionFeedback::pixwin_motion_notify_event (GdkEventMotion *ev) y_delta *= multiplier; y_delta /= 10; - _controllable->set_value (adjust ((grab_is_fine ? step_inc : page_inc) * y_delta)); + _controllable->set_value (adjust ((grab_is_fine ? step_inc : page_inc) * y_delta), Controllable::NoGroup); } else if (ev->state & Gdk::BUTTON2_MASK) { @@ -263,7 +264,7 @@ MotionFeedback::pixwin_motion_notify_event (GdkEventMotion *ev) angle = -(2.0/3.0) * (angle - 1.25); angle *= multiplier; - _controllable->set_value (to_control_value (angle)); + _controllable->set_value (to_control_value (angle), Controllable::NoGroup); } @@ -301,32 +302,32 @@ MotionFeedback::pixwin_key_press_event (GdkEventKey *ev) switch (ev->keyval) { case GDK_Page_Up: retval = true; - _controllable->set_value (adjust (multiplier * page_inc)); + _controllable->set_value (adjust (multiplier * page_inc), Controllable::NoGroup); break; case GDK_Page_Down: retval = true; - _controllable->set_value (adjust (-multiplier * page_inc)); + _controllable->set_value (adjust (-multiplier * page_inc), Controllable::NoGroup); break; case GDK_Up: retval = true; - _controllable->set_value (adjust (multiplier * step_inc)); + _controllable->set_value (adjust (multiplier * step_inc), Controllable::NoGroup); break; case GDK_Down: retval = true; - _controllable->set_value (adjust (-multiplier * step_inc)); + _controllable->set_value (adjust (-multiplier * step_inc), Controllable::NoGroup); break; case GDK_Home: retval = true; - _controllable->set_value (_controllable->lower()); + _controllable->set_value (_controllable->lower(), Controllable::NoGroup); break; case GDK_End: retval = true; - _controllable->set_value (_controllable->upper()); + _controllable->set_value (_controllable->upper(), Controllable::NoGroup); break; } @@ -406,12 +407,12 @@ MotionFeedback::pixwin_scroll_event (GdkEventScroll* ev) switch (ev->direction) { case GDK_SCROLL_UP: case GDK_SCROLL_RIGHT: - _controllable->set_value (adjust (scale * page_inc)); + _controllable->set_value (adjust (scale * page_inc), Controllable::NoGroup); break; case GDK_SCROLL_DOWN: case GDK_SCROLL_LEFT: - _controllable->set_value (adjust (-scale * page_inc)); + _controllable->set_value (adjust (-scale * page_inc), Controllable::NoGroup); break; } diff --git a/libs/panners/1in2out/panner_1in2out.cc b/libs/panners/1in2out/panner_1in2out.cc index 022f4d680c..b522d65054 100644 --- a/libs/panners/1in2out/panner_1in2out.cc +++ b/libs/panners/1in2out/panner_1in2out.cc @@ -76,7 +76,7 @@ Panner1in2out::Panner1in2out (boost::shared_ptr<Pannable> p) { if (!Profile->get_trx () ) { if (!_pannable->has_state ()) { - _pannable->pan_azimuth_control->set_value (0.5); + _pannable->pan_azimuth_control->set_value (0.5, Controllable::NoGroup); } } @@ -112,7 +112,7 @@ void Panner1in2out::set_position (double p) { if (clamp_position (p)) { - _pannable->pan_azimuth_control->set_value (p); + _pannable->pan_azimuth_control->set_value (p, Controllable::NoGroup); } } diff --git a/libs/panners/2in2out/panner_2in2out.cc b/libs/panners/2in2out/panner_2in2out.cc index 611f13db9a..d8a7428c4c 100644 --- a/libs/panners/2in2out/panner_2in2out.cc +++ b/libs/panners/2in2out/panner_2in2out.cc @@ -74,8 +74,8 @@ Panner2in2out::Panner2in2out (boost::shared_ptr<Pannable> p) : Panner (p) { if (!_pannable->has_state()) { - _pannable->pan_azimuth_control->set_value (0.5); - _pannable->pan_width_control->set_value (1.0); + _pannable->pan_azimuth_control->set_value (0.5, Controllable::NoGroup); + _pannable->pan_width_control->set_value (1.0, Controllable::NoGroup); } double const w = width(); @@ -119,7 +119,7 @@ void Panner2in2out::set_position (double p) { if (clamp_position (p)) { - _pannable->pan_azimuth_control->set_value (p); + _pannable->pan_azimuth_control->set_value (p, Controllable::NoGroup); } } @@ -127,7 +127,7 @@ void Panner2in2out::set_width (double p) { if (clamp_width (p)) { - _pannable->pan_width_control->set_value (p); + _pannable->pan_width_control->set_value (p, Controllable::NoGroup); } } diff --git a/libs/panners/stereobalance/panner_balance.cc b/libs/panners/stereobalance/panner_balance.cc index 281ea4b272..b2efb0f150 100644 --- a/libs/panners/stereobalance/panner_balance.cc +++ b/libs/panners/stereobalance/panner_balance.cc @@ -75,7 +75,7 @@ Pannerbalance::Pannerbalance (boost::shared_ptr<Pannable> p) : Panner (p) { if (!_pannable->has_state()) { - _pannable->pan_azimuth_control->set_value (0.5); + _pannable->pan_azimuth_control->set_value (0.5, Controllable::NoGroup); } update (); @@ -102,7 +102,7 @@ Pannerbalance::position () const Pannerbalance::set_position (double p) { if (clamp_position (p)) { - _pannable->pan_azimuth_control->set_value (p); + _pannable->pan_azimuth_control->set_value (p, Controllable::NoGroup); } } diff --git a/libs/panners/vbap/vbap.cc b/libs/panners/vbap/vbap.cc index f890b50324..df34ddd514 100644 --- a/libs/panners/vbap/vbap.cc +++ b/libs/panners/vbap/vbap.cc @@ -463,19 +463,19 @@ VBAPanner::set_position (double p) int over = p; over -= (p >= 0) ? 0 : 1; p -= (double)over; - _pannable->pan_azimuth_control->set_value (p); + _pannable->pan_azimuth_control->set_value (p, Controllable::NoGroup); } void VBAPanner::set_width (double w) { - _pannable->pan_width_control->set_value (min (1.0, max (-1.0, w))); + _pannable->pan_width_control->set_value (min (1.0, max (-1.0, w)), Controllable::NoGroup); } void VBAPanner::set_elevation (double e) { - _pannable->pan_elevation_control->set_value (min (1.0, max (0.0, e))); + _pannable->pan_elevation_control->set_value (min (1.0, max (0.0, e)), Controllable::NoGroup); } void diff --git a/libs/pbd/controllable.cc b/libs/pbd/controllable.cc index 17b81334f0..58ae731fbe 100644 --- a/libs/pbd/controllable.cc +++ b/libs/pbd/controllable.cc @@ -143,7 +143,7 @@ Controllable::set_state (const XMLNode& node, int /*version*/) float val; if (sscanf (prop->value().c_str(), "%f", &val) == 1) { - set_value (val); + set_value (val, NoGroup); } } diff --git a/libs/pbd/pbd/controllable.h b/libs/pbd/pbd/controllable.h index a0cffdfcd6..727153a277 100644 --- a/libs/pbd/pbd/controllable.h +++ b/libs/pbd/pbd/controllable.h @@ -47,6 +47,7 @@ namespace PBD { * * Without overriding upper() and lower(), a derived class will function * as a control whose value can range between 0 and 1.0. + * */ class LIBPBD_API Controllable : public PBD::StatefulDestructible { @@ -75,8 +76,27 @@ class LIBPBD_API Controllable : public PBD::StatefulDestructible { * but passed to the processor as a linear quantity. */ - /** Get and Set `internal' value */ - virtual void set_value (double) = 0; + /* Within an application, various Controllables might be considered to + * be "grouped" in a way that implies that setting 1 of them also + * modifies others in the group. + */ + + enum GroupControlDisposition { + WholeGroup, /* set all controls in the same "group" as this one */ + NoGroup, /* set only this control */ + UseGroup /* use group settings to decide which group controls are altered */ + }; + + /** Get and Set `internal' value + * + * All derived classes must implement this. + * + * Basic derived classes will ignore @param group_override, + * but more sophisticated children, notably those that + * proxy the value setting logic via an object that is aware of group + * relationships between this control and others, will find it useful. + */ + virtual void set_value (double, GroupControlDisposition group_override) = 0; virtual double get_value (void) const = 0; /** Conversions between `internal', 'interface', and 'user' values */ @@ -87,11 +107,11 @@ class LIBPBD_API Controllable : public PBD::StatefulDestructible { /** Get and Set `interface' value (typically, fraction of knob travel) */ virtual float get_interface() const { return (internal_to_interface(get_value())); } - virtual void set_interface (float fraction) { fraction = min( max(0.0f, fraction), 1.0f); set_value(interface_to_internal(fraction)); } + virtual void set_interface (float fraction) { fraction = min( max(0.0f, fraction), 1.0f); set_value(interface_to_internal(fraction), NoGroup); } /** Get and Set `user' value ( dB or milliseconds, etc. This MIGHT be the same as the internal value, but in a few cases it is not ) */ virtual float get_user() const { return (internal_to_user(get_value())); } - virtual void set_user (float user_v) { set_value(user_to_internal(user_v)); } + virtual void set_user (float user_v) { set_value(user_to_internal(user_v), NoGroup); } virtual std::string get_user_string() const { return std::string(); } PBD::Signal0<void> LearningFinished; @@ -126,6 +146,7 @@ class LIBPBD_API Controllable : public PBD::StatefulDestructible { static Controllable* by_id (const PBD::ID&); static Controllable* by_name (const std::string&); static const std::string xml_node_name; + private: std::string _name; std::string _units; @@ -150,7 +171,7 @@ class LIBPBD_API IgnorableControllable : public Controllable IgnorableControllable () : PBD::Controllable ("ignoreMe") {} ~IgnorableControllable () {} - void set_value (double /*v*/) {} + void set_value (double /*v*/, PBD::Controllable::GroupControlDisposition /* group_override */) {} double get_value () const { return 0.0; } }; diff --git a/libs/surfaces/faderport/operations.cc b/libs/surfaces/faderport/operations.cc index e7f8284527..1fed68566f 100644 --- a/libs/surfaces/faderport/operations.cc +++ b/libs/surfaces/faderport/operations.cc @@ -30,6 +30,7 @@ using namespace ARDOUR; using namespace ArdourSurface; +using namespace PBD; /* this value is chosen to given smooth motion from 0..1.0 in about 270 degrees * of encoder rotation. @@ -232,7 +233,7 @@ FaderPort::ardour_pan_azimuth (int delta) return; } - azimuth->set_value (azimuth->interface_to_internal (azimuth->internal_to_interface (azimuth->get_value()) + (delta / encoder_divider))); + azimuth->set_value (azimuth->interface_to_internal (azimuth->internal_to_interface (azimuth->get_value()) + (delta / encoder_divider)), Controllable::NoGroup); } @@ -255,7 +256,7 @@ FaderPort::ardour_pan_width(int delta) return; } - width->set_value (width->interface_to_internal (width->internal_to_interface (width->get_value()) + (delta / encoder_divider))); + width->set_value (width->interface_to_internal (width->internal_to_interface (width->get_value()) + (delta / encoder_divider)), Controllable::NoGroup); } void diff --git a/libs/surfaces/generic_midi/midicontrollable.cc b/libs/surfaces/generic_midi/midicontrollable.cc index f4025b591f..8945463e97 100644 --- a/libs/surfaces/generic_midi/midicontrollable.cc +++ b/libs/surfaces/generic_midi/midicontrollable.cc @@ -280,13 +280,13 @@ MIDIControllable::midi_sense_note (Parser &, EventTwoBytes *msg, bool /*is_on*/) if (!controllable->is_toggle()) { if (control_additional == msg->note_number) { - controllable->set_value (midi_to_control (msg->velocity)); + controllable->set_value (midi_to_control (msg->velocity), Controllable::NoGroup); DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("Note %1 value %2 %3\n", (int) msg->note_number, (float) midi_to_control (msg->velocity), current_uri() )); } } else { if (control_additional == msg->note_number) { float new_value = controllable->get_value() > 0.5f ? 0.0f : 1.0f; - controllable->set_value (new_value); + controllable->set_value (new_value, Controllable::NoGroup); DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("Note %1 Value %2 %3\n", (int) msg->note_number, (float) new_value, current_uri())); } } @@ -331,7 +331,7 @@ MIDIControllable::midi_sense_controller (Parser &, EventTwoBytes *msg) */ if (in_sync || _surface->motorised ()) { - controllable->set_value (midi_to_control (new_value)); + controllable->set_value (midi_to_control (new_value), Controllable::NoGroup); } DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("MIDI CC %1 value %2 %3\n", (int) msg->controller_number, (float) midi_to_control(new_value), current_uri() )); @@ -341,30 +341,30 @@ MIDIControllable::midi_sense_controller (Parser &, EventTwoBytes *msg) switch (get_encoder()) { case Enc_L: if (msg->value > 0x40) { - controllable->set_value (midi_to_control (last_value - offset + 1)); + controllable->set_value (midi_to_control (last_value - offset + 1), Controllable::NoGroup); } else { - controllable->set_value (midi_to_control (last_value + offset + 1)); + controllable->set_value (midi_to_control (last_value + offset + 1), Controllable::NoGroup); } break; case Enc_R: if (msg->value > 0x40) { - controllable->set_value (midi_to_control (last_value + offset + 1)); + controllable->set_value (midi_to_control (last_value + offset + 1), Controllable::NoGroup); } else { - controllable->set_value (midi_to_control (last_value - offset + 1)); + controllable->set_value (midi_to_control (last_value - offset + 1), Controllable::NoGroup); } break; case Enc_2: if (msg->value > 0x40) { - controllable->set_value (midi_to_control (last_value - (0x7f - msg->value) + 1)); + controllable->set_value (midi_to_control (last_value - (0x7f - msg->value) + 1), Controllable::NoGroup); } else { - controllable->set_value (midi_to_control (last_value + offset + 1)); + controllable->set_value (midi_to_control (last_value + offset + 1), Controllable::NoGroup); } break; case Enc_B: if (msg->value > 0x40) { - controllable->set_value (midi_to_control (last_value + offset + 1)); + controllable->set_value (midi_to_control (last_value + offset + 1), Controllable::NoGroup); } else { - controllable->set_value (midi_to_control (last_value - (0x40 - offset))); + controllable->set_value (midi_to_control (last_value - (0x40 - offset)), Controllable::NoGroup); } break; default: @@ -375,10 +375,10 @@ MIDIControllable::midi_sense_controller (Parser &, EventTwoBytes *msg) } } else { if (msg->value > 64.0f) { - controllable->set_value (1); + controllable->set_value (1, Controllable::NoGroup); DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("Midi CC %1 value 1 %2\n", (int) msg->controller_number, current_uri())); } else { - controllable->set_value (0); + controllable->set_value (0, Controllable::NoGroup); DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("Midi CC %1 value 0 %2\n", (int) msg->controller_number, current_uri())); } } @@ -398,11 +398,11 @@ MIDIControllable::midi_sense_program_change (Parser &, MIDI::byte msg) if (msg == control_additional) { if (!controllable->is_toggle()) { - controllable->set_value (1.0); + controllable->set_value (1.0, Controllable::NoGroup); DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("MIDI program %1 value 1.0 %3\n", (int) msg, current_uri() )); } else { float new_value = controllable->get_value() > 0.5f ? 0.0f : 1.0f; - controllable->set_value (new_value); + controllable->set_value (new_value, Controllable::NoGroup); DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("MIDI program %1 value %2 %3\n", (int) msg, (float) new_value, current_uri())); } } @@ -420,14 +420,14 @@ MIDIControllable::midi_sense_pitchbend (Parser &, pitchbend_t pb) } if (!controllable->is_toggle()) { - controllable->set_value (midi_to_control (pb)); + controllable->set_value (midi_to_control (pb), Controllable::NoGroup); DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("MIDI pitchbend %1 value %2 %3\n", (int) control_channel, (float) midi_to_control (pb), current_uri() )); } else { if (pb > 8065.0f) { - controllable->set_value (1); + controllable->set_value (1, Controllable::NoGroup); DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("Midi pitchbend %1 value 1 %2\n", (int) control_channel, current_uri())); } else { - controllable->set_value (0); + controllable->set_value (0, Controllable::NoGroup); DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("Midi pitchbend %1 value 0 %2\n", (int) control_channel, current_uri())); } } @@ -457,7 +457,7 @@ MIDIControllable::rpn_value_change (Parser&, uint16_t rpn, float val) { if (control_rpn == rpn) { if (controllable) { - controllable->set_value (val); + controllable->set_value (val, Controllable::NoGroup); } } } @@ -467,7 +467,7 @@ MIDIControllable::nrpn_value_change (Parser&, uint16_t nrpn, float val) { if (control_nrpn == nrpn) { if (controllable) { - controllable->set_value (val); + controllable->set_value (val, Controllable::NoGroup); } } } diff --git a/libs/surfaces/mackie/controls.cc b/libs/surfaces/mackie/controls.cc index bbe1029f30..8ed0bad311 100644 --- a/libs/surfaces/mackie/controls.cc +++ b/libs/surfaces/mackie/controls.cc @@ -81,7 +81,7 @@ void Control::set_value (float val) { if (normal_ac) { - normal_ac->set_value (normal_ac->interface_to_internal (val)); + normal_ac->set_value (normal_ac->interface_to_internal (val), PBD::Controllable::NoGroup); } } diff --git a/libs/surfaces/mackie/strip.cc b/libs/surfaces/mackie/strip.cc index 59d99fb711..f2c56d80de 100644 --- a/libs/surfaces/mackie/strip.cc +++ b/libs/surfaces/mackie/strip.cc @@ -756,7 +756,7 @@ Strip::select_event (Button&, ButtonState bs) /* reset to default */ boost::shared_ptr<AutomationControl> ac = _fader->control (); if (ac) { - ac->set_value (ac->normal()); + ac->set_value (ac->normal(), Controllable::NoGroup); } return; } @@ -789,7 +789,7 @@ Strip::vselect_event (Button&, ButtonState bs) if (control->toggled()) { if (control->toggled()) { - control->set_value (!control->get_value()); + control->set_value (!control->get_value(), Controllable::NoGroup); } } @@ -807,7 +807,7 @@ Strip::vselect_event (Button&, ButtonState bs) if (ac) { /* reset to default/normal value */ - ac->set_value (ac->normal()); + ac->set_value (ac->normal(), Controllable::NoGroup); } } else { @@ -830,7 +830,7 @@ Strip::fader_touch_event (Button&, ButtonState bs) if (_surface->mcp().main_modifier_state() & MackieControlProtocol::MODIFIER_SHIFT) { if (ac) { - ac->set_value (ac->normal()); + ac->set_value (ac->normal(), Controllable::NoGroup); } } else { @@ -907,7 +907,7 @@ Strip::handle_button (Button& button, ButtonState bs) /* apply change */ for (MackieControlProtocol::ControlList::iterator c = controls.begin(); c != controls.end(); ++c) { - (*c)->set_value (new_value); + (*c)->set_value (new_value, Controllable::NoGroup); } } else { @@ -1778,7 +1778,7 @@ Strip::set_vpot_parameter (AutomationType p) _pan_mode = PanAzimuthAutomation; if (_surface->mcp().flip_mode() != MackieControlProtocol::Normal) { /* gain to vpot, pan azi to fader */ - _vpot->set_control (_route->group_gain_control()); + _vpot->set_control (_route->gain_control()); vpot_parameter = GainAutomation; control_by_parameter[GainAutomation] = _vpot; _fader->set_control (pan_control); @@ -1790,7 +1790,7 @@ Strip::set_vpot_parameter (AutomationType p) } else { /* gain to fader, pan azi to vpot */ vpot_parameter = PanAzimuthAutomation; - _fader->set_control (_route->group_gain_control()); + _fader->set_control (_route->gain_control()); control_by_parameter[GainAutomation] = _fader; _vpot->set_control (pan_control); control_by_parameter[PanAzimuthAutomation] = _vpot; @@ -1807,7 +1807,7 @@ Strip::set_vpot_parameter (AutomationType p) _pan_mode = PanWidthAutomation; if (_surface->mcp().flip_mode() != MackieControlProtocol::Normal) { /* gain to vpot, pan width to fader */ - _vpot->set_control (_route->group_gain_control()); + _vpot->set_control (_route->gain_control()); vpot_parameter = GainAutomation; control_by_parameter[GainAutomation] = _vpot; _fader->set_control (pan_control); @@ -1819,7 +1819,7 @@ Strip::set_vpot_parameter (AutomationType p) } else { /* gain to fader, pan width to vpot */ vpot_parameter = PanWidthAutomation; - _fader->set_control (_route->group_gain_control()); + _fader->set_control (_route->gain_control()); control_by_parameter[GainAutomation] = _fader; _vpot->set_control (pan_control); control_by_parameter[PanWidthAutomation] = _vpot; @@ -1841,7 +1841,7 @@ Strip::set_vpot_parameter (AutomationType p) vpot_parameter = TrimAutomation; if (_surface->mcp().flip_mode() != MackieControlProtocol::Normal) { /* gain to vpot, trim to fader */ - _vpot->set_control (_route->group_gain_control()); + _vpot->set_control (_route->gain_control()); control_by_parameter[GainAutomation] = _vpot; if (_route->trim() && route()->trim()->active()) { _fader->set_control (_route->trim_control()); @@ -1852,7 +1852,7 @@ Strip::set_vpot_parameter (AutomationType p) } } else { /* gain to fader, trim to vpot */ - _fader->set_control (_route->group_gain_control()); + _fader->set_control (_route->gain_control()); control_by_parameter[GainAutomation] = _fader; if (_route->trim() && route()->trim()->active()) { _vpot->set_control (_route->trim_control()); @@ -1868,7 +1868,7 @@ Strip::set_vpot_parameter (AutomationType p) vpot_parameter = PhaseAutomation; if (_surface->mcp().flip_mode() != MackieControlProtocol::Normal) { /* gain to vpot, phase to fader */ - _vpot->set_control (_route->group_gain_control()); + _vpot->set_control (_route->gain_control()); control_by_parameter[GainAutomation] = _vpot; if (_route->phase_invert().size()) { _fader->set_control (_route->phase_control()); @@ -1879,7 +1879,7 @@ Strip::set_vpot_parameter (AutomationType p) } } else { /* gain to fader, phase to vpot */ - _fader->set_control (_route->group_gain_control()); + _fader->set_control (_route->gain_control()); control_by_parameter[GainAutomation] = _fader; if (_route->phase_invert().size()) { _vpot->set_control (_route->phase_control()); @@ -1894,7 +1894,7 @@ Strip::set_vpot_parameter (AutomationType p) if (!Profile->get_mixbus()) { if (_surface->mcp().flip_mode() != MackieControlProtocol::Normal) { // gain to vpot, send to fader - _vpot->set_control (_route->group_gain_control()); + _vpot->set_control (_route->gain_control()); control_by_parameter[GainAutomation] = _vpot; // test for send to control boost::shared_ptr<Processor> p = _route->nth_send (_current_send); @@ -1912,7 +1912,7 @@ Strip::set_vpot_parameter (AutomationType p) } } else { // gain to fader, send to vpot - _fader->set_control (_route->group_gain_control()); + _fader->set_control (_route->gain_control()); control_by_parameter[GainAutomation] = _fader; boost::shared_ptr<Processor> p = _route->nth_send (_current_send); if (p && p->name() != "Monitor 1") { @@ -1925,7 +1925,7 @@ Strip::set_vpot_parameter (AutomationType p) control_by_parameter[SendAutomation] = _vpot; } else { // gain to fader, send to vpot - _fader->set_control (_route->group_gain_control()); + _fader->set_control (_route->gain_control()); control_by_parameter[GainAutomation] = _fader; boost::shared_ptr<Processor> p = _route->nth_send (_current_send); if (p && p->name() != "Monitor 1") { diff --git a/libs/surfaces/osc/osc.cc b/libs/surfaces/osc/osc.cc index 49c8bcc57c..c29469667c 100644 --- a/libs/surfaces/osc/osc.cc +++ b/libs/surfaces/osc/osc.cc @@ -1108,7 +1108,7 @@ OSC::route_plugin_parameter (int rid, int piid, int par, float val) boost::shared_ptr<AutomationControl> c = pi->automation_control (Evoral::Parameter(PluginAutomation, 0, controlid)); // cerr << "parameter:" << redi->describe_parameter(controlid) << " val:" << val << "\n"; - c->set_value (val); + c->set_value (val, PBD::Controllable::NoGroup); } else { PBD::warning << "OSC: Parameter # " << par << " for plugin # " << piid << " on RID '" << rid << "' is out of range" << endmsg; PBD::info << "OSC: Valid range min=" << pd.lower << " max=" << pd.upper << endmsg; |