From 5db598fb0ad46b061f68b32bbb04adc503c8b12b Mon Sep 17 00:00:00 2001 From: Hoger Dehnhardt Date: Mon, 13 Nov 2023 21:56:57 +0100 Subject: [PATCH 1/7] c1: Add GUI for plugin mappings --- libs/surfaces/console1/c1_gui.cc | 166 +++++++++++++++++- libs/surfaces/console1/c1_gui.h | 68 ++++++- .../surfaces/console1/c1_plugin_operations.cc | 79 ++++++++- libs/surfaces/console1/console1.cc | 13 +- libs/surfaces/console1/console1.h | 46 +++-- 5 files changed, 340 insertions(+), 32 deletions(-) diff --git a/libs/surfaces/console1/c1_gui.cc b/libs/surfaces/console1/c1_gui.cc index ae37d3e0ac9..c1977e3a343 100644 --- a/libs/surfaces/console1/c1_gui.cc +++ b/libs/surfaces/console1/c1_gui.cc @@ -22,6 +22,7 @@ #include #include +#include #include "pbd/file_utils.h" #include "pbd/i18n.h" #include "pbd/strsplit.h" @@ -32,6 +33,7 @@ #include "ardour/filesystem_paths.h" #include "ardour/parameter_descriptor.h" #include "console1.h" +#include "gtkmm2ext/action_model.h" #include "gtkmm2ext/bindings.h" #include "gtkmm2ext/gui_thread.h" #include "gtkmm2ext/utils.h" @@ -49,7 +51,7 @@ Console1::get_gui () const if (!gui) { const_cast (this)->build_gui (); } - static_cast (gui)->show_all (); + static_cast (gui)->show_all (); return gui; } @@ -57,7 +59,7 @@ void Console1::tear_down_gui () { if (gui) { - Gtk::Widget* w = static_cast (gui)->get_parent (); + Gtk::Widget* w = static_cast (gui)->get_parent (); if (w) { w->hide (); delete w; @@ -167,10 +169,44 @@ C1GUI::C1GUI (Console1& p) row++; hpacker.pack_start (table, true, true); + append_page (hpacker, _("Device Setup")); + hpacker.show_all(); + + // Create the page for plugin mappings + p.load_mappings (); + + VBox* plugconfig_packer = manage (new VBox); + HBox* plugselect_packer = manage (new HBox); + + l = manage (new Gtk::Label (_("Select Plugin"))); + plugselect_packer->pack_start (*l, false, false); + + plugconfig_packer->pack_start (*plugselect_packer, false, false); + + Glib::RefPtr plugin_store_model = ListStore::create (plugin_columns); + TreeModel::Row plugin_combo_row; + for( const auto &pm : c1.getPluginMappingMap() ){ + plugin_combo_row = *(plugin_store_model->append ()); + plugin_combo_row[plugin_columns.plugin_name] = pm.second.name; + plugin_combo_row[plugin_columns.plugin_id] = pm.first; + DEBUG_TRACE (DEBUG::Console1, string_compose ("Add Plugin: name %1 / %2\n", pm.second.name, pm.first)); + } + plugins_combo.pack_start (plugin_columns.plugin_name); + plugins_combo.signal_changed ().connect ( + sigc::bind (sigc::mem_fun (*this, &C1GUI::active_plugin_changed), &plugins_combo)); + plugins_combo.set_model (plugin_store_model); + + plugselect_packer->pack_start (plugins_combo, true, true); + plugin_mapping_scroller.property_shadow_type() = Gtk::SHADOW_NONE; + plugin_mapping_scroller.set_policy(Gtk::PolicyType::POLICY_AUTOMATIC, Gtk::PolicyType::POLICY_AUTOMATIC); + + plugin_mapping_scroller.add (plugin_assignment_editor); + plugconfig_packer->pack_start (plugin_mapping_scroller, true, true, 20); - set_spacing (12); + build_plugin_assignment_editor (); - pack_start (hpacker, false, false); + append_page (*plugconfig_packer, _ ("Plugin Mappings")); + plugconfig_packer->show_all (); /* update the port connection combos */ @@ -186,7 +222,9 @@ C1GUI::C1GUI (Console1& p) _port_connections, invalidator (*this), std::bind (&C1GUI::connection_handler, this), gui_context ()); } -C1GUI::~C1GUI () {} +C1GUI::~C1GUI () { + write_plugin_assignment(); +} void C1GUI::set_swap_solo_mute () @@ -287,7 +325,7 @@ C1GUI::build_midi_port_list (vector const& ports, bool for_input) row = *store->append (); row[midi_port_columns.full_name] = string (); - row[midi_port_columns.short_name] = _ ("Disconnected"); + row[midi_port_columns.short_name] = _("Disconnected"); for (vector::const_iterator p = ports.begin (); p != ports.end (); ++p) { row = *store->append (); @@ -334,3 +372,119 @@ C1GUI::active_port_changed (Gtk::ComboBox* combo, bool for_input) } } } + +void +C1GUI::change_controller (const Glib::ustring &sPath, const TreeModel::iterator &iter) +{ + Gtk::TreePath path(sPath); + Gtk::TreeModel::iterator row = plugin_assignment_store->get_iter(path); + int index = *path.begin (); + if (row) { + + string controllerName = (*iter)[c1.plugin_controller_columns.controllerName]; + int controllerId = (*iter)[c1.plugin_controller_columns.controllerId]; + pc.parameters[index].controllerId = ArdourSurface::Console1::ControllerID (controllerId); + (*row).set_value (plugin_assignment_editor_columns.controllerName, controllerName); + DEBUG_TRACE (DEBUG::Console1, + string_compose ("Column Name: Controller, index %1, name %2 \n", index, controllerName)); + assignement_changed = true; + } +} + +void C1GUI::toggle_shift( const Glib::ustring& s){ + int index = atoi (s.c_str()); + Gtk::TreeModel::iterator row = plugin_assignment_store->get_iter (s); + if( row ) + { + bool value = !pc.parameters[index].shift; + pc.parameters[index].shift = value; + (*row).set_value (plugin_assignment_editor_columns.shift, value); + DEBUG_TRACE (DEBUG::Console1, string_compose ("Column Name: Shift, value %1\n", value)); + assignement_changed = true; + } +} + +CellRendererCombo* +C1GUI::make_action_renderer (Glib::RefPtr model, Gtk::TreeModelColumnBase column) +{ + CellRendererCombo* renderer = manage (new CellRendererCombo); + renderer->property_model() = model; + renderer->property_editable() = true; + renderer->property_text_column () = 0; + renderer->property_has_entry () = false; + renderer->signal_changed().connect (sigc::mem_fun(*this, &C1GUI::change_controller)); + + return renderer; +} + +void +C1GUI::build_plugin_assignment_editor () +{ + plugin_assignment_editor.append_column (_("Key"), plugin_assignment_editor_columns.index); + plugin_assignment_editor.append_column (_("Name"), plugin_assignment_editor_columns.name); + plugin_assignment_editor.append_column (_("Switch"), plugin_assignment_editor_columns.is_switch); + + TreeViewColumn* col; + CellRendererCombo* renderer; + + CellRendererToggle* boolRenderer = manage (new CellRendererToggle); + boolRenderer->set_active (); + boolRenderer->property_activatable() = true; + col = manage (new TreeViewColumn (_ ("Shift"), *boolRenderer)); + col->add_attribute (boolRenderer->property_active (), plugin_assignment_editor_columns.shift); + boolRenderer->signal_toggled().connect (sigc::mem_fun(*this, &C1GUI::toggle_shift)); + plugin_assignment_editor.append_column (*col); + + + renderer = make_action_renderer (c1.getPluginControllerModel(), plugin_assignment_editor_columns.controllerName); + col = manage (new TreeViewColumn (_("Control"), *renderer)); + col->add_attribute (renderer->property_text(), plugin_assignment_editor_columns.controllerName); + plugin_assignment_editor.append_column (*col); + + plugin_assignment_store = ListStore::create (plugin_assignment_editor_columns); + plugin_assignment_editor.set_model (plugin_assignment_store); +} + + +void +C1GUI::active_plugin_changed(Gtk::ComboBox* combo ){ + DEBUG_TRACE (DEBUG::Console1, "C1GUI active_plugin_changed\n"); + + write_plugin_assignment (); + + plugin_assignment_editor.set_model (Glib::RefPtr()); + plugin_assignment_store->clear (); + + TreeModel::iterator active = combo->get_active (); + TreeModel::Row plugin_assignment_row; + + string new_plugin_name = (*active)[plugin_columns.plugin_name]; + string new_plugin_id = (*active)[plugin_columns.plugin_id]; + DEBUG_TRACE (DEBUG::Console1, string_compose ("Plugin: selected %1 / %2\n", new_plugin_name, new_plugin_id)); + pc = c1.getPluginMappingMap ()[new_plugin_id]; + + for( auto &parm : pc.parameters ){ + plugin_assignment_row = *(plugin_assignment_store->append ()); + plugin_assignment_row[plugin_assignment_editor_columns.index] = parm.first; + plugin_assignment_row[plugin_assignment_editor_columns.name] = parm.second.name; + plugin_assignment_row[plugin_assignment_editor_columns.controllerName] = c1.findControllerNameById(parm.second.controllerId); + plugin_assignment_row[plugin_assignment_editor_columns.is_switch] = parm.second.is_switch; + plugin_assignment_row[plugin_assignment_editor_columns.shift] = parm.second.shift; + + DEBUG_TRACE (DEBUG::Console1, string_compose ("Parameter Name %1 \n", parm.second.name)); + DEBUG_TRACE (DEBUG::Console1, string_compose ("Parameter Index: %1 - index %2 \n", parm.first, parm.second.paramIndex)); + DEBUG_TRACE (DEBUG::Console1, string_compose ("ControllerId: %1 \n", parm.second.controllerId)); + DEBUG_TRACE (DEBUG::Console1, string_compose ("is switch? %1 \n", parm.second.is_switch)); + DEBUG_TRACE (DEBUG::Console1, string_compose ("is shift? %1 \n", parm.second.shift)); + } + plugin_assignment_editor.set_model (plugin_assignment_store); + +} + +void C1GUI::write_plugin_assignment(){ + DEBUG_TRACE (DEBUG::Console1, "write_plugin_assignment\n"); + if( !assignement_changed ) + return; + c1.write_plugin_mapping (pc); + assignement_changed = false; +} diff --git a/libs/surfaces/console1/c1_gui.h b/libs/surfaces/console1/c1_gui.h index e5408f82c13..45c66cd144e 100644 --- a/libs/surfaces/console1/c1_gui.h +++ b/libs/surfaces/console1/c1_gui.h @@ -30,19 +30,32 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include namespace Gtk { class CellRendererCombo; class ListStore; } +namespace ActionManager { + class ActionModel; +} + #include "ardour/mode.h" #include "console1.h" namespace ArdourSurface { -class C1GUI : public Gtk::VBox +class C1GUI : public Gtk::Notebook { public: C1GUI (Console1&); @@ -55,16 +68,24 @@ class C1GUI : public Gtk::VBox Gtk::Table table; Gtk::ComboBox input_combo; Gtk::ComboBox output_combo; + Gtk::ComboBox plugins_combo; + Gtk::ScrolledWindow plugin_mapping_scroller; Gtk::Image image; Gtk::CheckButton swap_solo_mute_cb; Gtk::CheckButton band_q_as_send_cb; Gtk::CheckButton create_plugin_stubs_btn; + Gtk::TreeView plugin_assignment_editor; + + Gtk::VBox plugin_packer; + + bool assignement_changed = false; + void update_port_combos (); PBD::ScopedConnection connection_change_connection; void connection_handler (); PBD::ScopedConnectionList _port_connections; - + struct MidiPortColumns : public Gtk::TreeModel::ColumnRecord { MidiPortColumns() { add (short_name); @@ -74,17 +95,54 @@ class C1GUI : public Gtk::VBox Gtk::TreeModelColumn full_name; }; + struct PluginColumns : public Gtk::TreeModel::ColumnRecord { + PluginColumns() { + add (plugin_name); + add (plugin_id); + } + Gtk::TreeModelColumn plugin_name; + Gtk::TreeModelColumn plugin_id; + }; + + struct PluginAssignamentEditorColumns : public Gtk::TreeModel::ColumnRecord { + PluginAssignamentEditorColumns() { + add (index); + add (name); + add (is_switch); + add (controllerName); + add (shift); + }; + Gtk::TreeModelColumn index; // parameter index + Gtk::TreeModelColumn name; // readable name of the parameter + Gtk::TreeModelColumn is_switch; + Gtk::TreeModelColumn controllerName; // enum Button::ID + Gtk::TreeModelColumn shift; + }; + MidiPortColumns midi_port_columns; + PluginColumns plugin_columns; + PluginAssignamentEditorColumns plugin_assignment_editor_columns; + Glib::RefPtr plugin_assignment_store; + bool ignore_active_change; Glib::RefPtr build_midi_port_list (std::vector const & ports, bool for_input); - void active_port_changed (Gtk::ComboBox*,bool for_input); + + ArdourSurface::Console1::PluginMapping pc; + Gtk::CellRendererCombo* make_action_renderer (Glib::RefPtr model, Gtk::TreeModelColumnBase column); + void build_plugin_assignment_editor (); + + void change_controller (const Glib::ustring &, const Gtk::TreeIter&); + void toggle_shift ( const Glib::ustring& ); + + void active_port_changed (Gtk::ComboBox*, bool for_input); void set_swap_solo_mute (); void set_band_q_as_send(); - void set_create_mapping_stubs(); + void set_create_mapping_stubs (); + void active_plugin_changed (Gtk::ComboBox* combo); + void write_plugin_assignment (); }; - } #endif /* __ardour_console1_gui_h__ */ diff --git a/libs/surfaces/console1/c1_plugin_operations.cc b/libs/surfaces/console1/c1_plugin_operations.cc index 6fd1d5ef48a..a22252706b2 100644 --- a/libs/surfaces/console1/c1_plugin_operations.cc +++ b/libs/surfaces/console1/c1_plugin_operations.cc @@ -57,6 +57,9 @@ Console1::ensure_config_dir () uint32_t Console1::load_mappings () { + if( mappings_loaded ) + return pluginMappingMap.size (); + uint32_t i = 0; if (!ensure_config_dir ()) return 1; @@ -89,7 +92,9 @@ Console1::load_mappings () ++i; } DEBUG_TRACE (DEBUG::Console1, string_compose ("Console1::load_mappings - found %1 mapping files\n", i)); + DEBUG_TRACE (DEBUG::Console1, string_compose ("Console1::load_mappings - loaded %1 mapping files\n", pluginMappingMap.size())); g_dir_close (gdir); + mappings_loaded = true; return i; } @@ -118,26 +123,32 @@ Console1::load_mapping (XMLNode* mapping_xml) const XMLNodeList& plist = (*i)->children (); XMLNodeConstIterator j; + PluginParameterMapping parmap; for (j = plist.begin (); j != plist.end (); ++j) { if ((*j)->name () == "name") { param_name = (*j)->child_content (); } else if ((*j)->name () == "mapping") { param_mapping = (*j)->child_content (); + (*j)->get_property ("shift", parmap.shift); } } + parmap.paramIndex = index; + parmap.name = param_name; + parmap.is_switch = (param_type == "switch"); if (!param_mapping.empty ()) { - PluginParameterMapping parmap; - parmap.paramIndex = index; - parmap.name = param_name; ControllerMap::const_iterator m = controllerMap.find (param_mapping); - if (m == controllerMap.end ()) - continue; - parmap.controllerId = m->second; - parmap.is_switch = (param_type == "switch"); - pm.parameters[index] = std::move (parmap); - pluginMappingMap[pm.id] = pm; + if (m != controllerMap.end ()) + { + parmap.controllerId = m->second; + } } + else{ + pm.configured = false; + parmap.controllerId = CONTROLLER_NONE; + } + pm.parameters[index] = std::move (parmap); } + pluginMappingMap[pm.id] = pm; return true; } @@ -182,6 +193,44 @@ Console1::create_mapping (const std::shared_ptr proc, const std::shar tree->write (); } +void +Console1::write_plugin_mapping (PluginMapping &mapping) +{ + DEBUG_TRACE (DEBUG::Console1, "write_plugin_mapping \n"); + XMLTree* tree = new XMLTree (); + XMLNode node = XMLNode ("c1plugin-mapping"); + node.set_property ("ID", mapping.id); + node.set_property ("NAME", mapping.name); + + for (const auto& plugin_param : mapping.parameters ) { + DEBUG_TRACE (DEBUG::Console1, string_compose ("Plugin parameter %1: %2\n",plugin_param.first ,plugin_param.second.name)); + XMLNode param = XMLNode ("param-mapping"); + param.set_property ("id", plugin_param.second.paramIndex); + XMLNode name = XMLNode ("name"); + XMLNode c = XMLNode ("c", plugin_param.second.name ); + name.add_child_copy (c); + XMLNode mapping = XMLNode ("mapping"); + mapping.set_property ("shift", plugin_param.second.shift); + XMLNode controller = XMLNode ("c", findControllerNameById(plugin_param.second.controllerId) ); + mapping.add_child_copy (controller); + param.add_child_copy (name); + param.add_child_copy (mapping); + node.add_child_copy (param); + } + + tree->set_root (&node); + + if (!ensure_config_dir ()) + return; + + std::string filename = Glib::build_filename ( + user_config_directory (), config_dir_name, string_compose ("%1.%2", mapping.id, "xml")); + + tree->set_filename (filename); + tree->write (); + load_mapping (&node); +} + bool Console1::select_plugin (const int32_t plugin_index) { @@ -444,4 +493,16 @@ Console1::spill_plugins (const int32_t plugin_index) return true; } +Glib::RefPtr Console1::getPluginControllerModel() +{ + plugin_controller_model = Gtk::ListStore::create (plugin_controller_columns); + Gtk::TreeModel::Row plugin_controller_combo_row; + for( const auto &controller : controllerMap ){ + plugin_controller_combo_row = *(plugin_controller_model->append ()); + plugin_controller_combo_row[plugin_controller_columns.controllerId] = controller.second; + plugin_controller_combo_row[plugin_controller_columns.controllerName] = X_(controller.first); + } + return plugin_controller_model; +} + } diff --git a/libs/surfaces/console1/console1.cc b/libs/surfaces/console1/console1.cc index 64d4b0d89ec..c4ad5f57fc2 100644 --- a/libs/surfaces/console1/console1.cc +++ b/libs/surfaces/console1/console1.cc @@ -181,7 +181,7 @@ Console1::begin_using_device () f0 7d 20 00 00 00 01 00 7f 49 6f 6c 73 00 f7 */ - load_mappings (); + load_mappings (); setup_controls (); /* Connection to the blink-timer */ @@ -532,7 +532,7 @@ Console1::notify_transport_state_changed () void Console1::stripable_selection_changed () { - DEBUG_TRACE (DEBUG::Console1, "stripable_selection_changed \n"); + DEBUG_TRACE (DEBUG::Console1, "stripable_selection_changed \n"); if (!_in_use) return; @@ -1261,3 +1261,12 @@ Console1::master_monitor_has_changed () DEBUG_TRACE (DEBUG::Console1, string_compose ("master_monitor_has_changed - monitor active %1\n", monitor_active)); create_strip_inventory (); } + +const std::string Console1::findControllerNameById (const ControllerID id){ + for( const auto &controller : controllerMap ){ + if( controller.second == id ){ + return controller.first; + } + } + return std::string(); +} \ No newline at end of file diff --git a/libs/surfaces/console1/console1.h b/libs/surfaces/console1/console1.h index 58cd9b3b947..e4cc90fbfc3 100644 --- a/libs/surfaces/console1/console1.h +++ b/libs/surfaces/console1/console1.h @@ -23,6 +23,11 @@ #include #include +#include +#include + +#include + #define ABSTRACT_UI_EXPORTS #include "pbd/abstract_ui.h" @@ -109,6 +114,7 @@ class Console1 : public MIDISurface std::string input_port_name () const override; std::string output_port_name () const override; + uint32_t load_mappings (); XMLNode& get_state () const override; int set_state (const XMLNode&, int version) override; @@ -293,12 +299,27 @@ class Console1 : public MIDISurface { "TRACK_COPY", ControllerID::TRACK_COPY }, { "TRACK_GROUP", ControllerID::TRACK_GROUP } }; -private: + struct PluginControllerColumns : public Gtk::TreeModel::ColumnRecord { + PluginControllerColumns () { + add (controllerName); + add (controllerId); + } + Gtk::TreeModelColumn controllerName; + Gtk::TreeModelColumn controllerId; + }; + PluginControllerColumns plugin_controller_columns; + Glib::RefPtr plugin_controller_model; + const std::string findControllerNameById (const ControllerID id); + + private: std::string config_dir_name = "c1mappings"; /* GUI */ mutable C1GUI* gui; void build_gui (); + bool mappings_loaded = false; + bool controls_model_loaded = false; + /* Configuration */ const uint32_t bank_size = 20; @@ -630,16 +651,8 @@ class Console1 : public MIDISurface using ParameterMap = std::map; - struct PluginMapping - { - std::string id; - std::string name; - ParameterMap parameters; - }; - /* plugin handling */ bool ensure_config_dir (); - uint32_t load_mappings (); bool load_mapping (XMLNode* fin); void create_mapping (const std::shared_ptr proc, const std::shared_ptr plugin); @@ -654,8 +667,21 @@ class Console1 : public MIDISurface void eqBandQChangeMapping (bool mapValues); - using PluginMappingMap = std::map; + + public: + struct PluginMapping + { + std::string id; + std::string name; + bool configured; + ParameterMap parameters; + }; + using PluginMappingMap = std::map; PluginMappingMap pluginMappingMap; + + PluginMappingMap getPluginMappingMap () { return pluginMappingMap; } + Glib::RefPtr getPluginControllerModel(); + void write_plugin_mapping (PluginMapping &mapping); }; } #endif /* ardour_surface_console1_h */ From 8f23994808c718f4286e74f18e359c4a9cb07df4 Mon Sep 17 00:00:00 2001 From: Hoger Dehnhardt Date: Wed, 16 Jul 2025 14:43:56 +0200 Subject: [PATCH 2/7] Enable SSL-EQ Q Control --- libs/surfaces/console1/c1_gui.h | 1 + libs/surfaces/console1/c1_operations.cc | 90 ++++++++++++++++++++++++- libs/surfaces/console1/console1.h | 12 ++-- libs/surfaces/console1/wscript | 9 ++- 4 files changed, 103 insertions(+), 9 deletions(-) diff --git a/libs/surfaces/console1/c1_gui.h b/libs/surfaces/console1/c1_gui.h index 45c66cd144e..3d048d447e4 100644 --- a/libs/surfaces/console1/c1_gui.h +++ b/libs/surfaces/console1/c1_gui.h @@ -73,6 +73,7 @@ class C1GUI : public Gtk::Notebook Gtk::Image image; Gtk::CheckButton swap_solo_mute_cb; Gtk::CheckButton band_q_as_send_cb; + Gtk::CheckButton band_q_as_send_cb; Gtk::CheckButton create_plugin_stubs_btn; Gtk::TreeView plugin_assignment_editor; diff --git a/libs/surfaces/console1/c1_operations.cc b/libs/surfaces/console1/c1_operations.cc index 32f08265c50..1d0dce9524b 100644 --- a/libs/surfaces/console1/c1_operations.cc +++ b/libs/surfaces/console1/c1_operations.cc @@ -417,6 +417,17 @@ Console1::eq_band_q (const uint32_t band, uint32_t value) session->set_control (control, freq, PBD::Controllable::UseGroup); } +void +Console1::eq_band_q (const uint32_t band, uint32_t value) +{ + if (!_current_stripable || !_current_stripable->mapped_control (EQ_BandQ, band)) { + return; + } + std::shared_ptr control = _current_stripable->mapped_control (EQ_BandQ, band); + double freq = midi_to_control (control, value); + session->set_control (control, freq, PBD::Controllable::UseGroup); +} + // The Mixbus-Sends are in the EQ section // Without Shift: // LowMid Shape is Send 11 @@ -920,6 +931,42 @@ Console1::map_eq () } } +void +Console1::map_eq_mode (){ +#ifdef MIXBUS + DEBUG_TRACE (DEBUG::Console1, "Enter map_eq_mode()\n"); + if (!_current_stripable) + return; + std::shared_ptr rt = std::dynamic_pointer_cast( _current_stripable ); + if (!rt) + return; + EQ_MODE current_eq_mode = EQ_MODE (rt->eq_mode_control() ? rt->eq_mode_control()->get_value() : -1); + DEBUG_TRACE (DEBUG::Console1, string_compose ("map_eq_mode() - mode: %1\n", current_eq_mode)); + if (current_eq_mode != strip_eq_mode) + { + strip_eq_mode = current_eq_mode; + EQBandQBindingChange(); + } +#endif +} + + +void +Console1::map_eq_band_q (const uint32_t band) +{ + DEBUG_TRACE (DEBUG::Console1, string_compose( "map_eq_band_q band: %1 \n", band)); + if (shift_state || switch_eq_q_dials) { + DEBUG_TRACE (DEBUG::Console1, "Exit map_eq_band_q 1\n"); + return; + } + ControllerID controllerID = eq_q_controller_for_band (band); + if (map_encoder (controllerID)) { + std::shared_ptr control = _current_stripable->mapped_control (EQ_BandQ, band); + map_encoder (controllerID, control); + } +} + + void Console1::map_eq_mode () { @@ -1034,6 +1081,7 @@ Console1::map_drive () } } +// Sends // Sends void Console1::map_mb_send_level (const uint32_t n) @@ -1045,15 +1093,22 @@ Console1::map_mb_send_level (const uint32_t n) } #endif // Theese two sends are available in non-shift state - if (n_offset > 9 && shift_state) { + if (n_offset > 9 && shift_state) + { + return; + } else if (n_offset < 10 && !shift_state) // while the rest needs the shift state + { return; } + else if( !shift_state && !switch_eq_q_dials ) + { + } else if (n_offset < 10 && !shift_state) { // while the rest needs the shift state return; } else if(!shift_state && !switch_eq_q_dials) { return; - } + } ControllerID controllerID = get_send_controllerid (n_offset); if (map_encoder (controllerID)) { std::shared_ptr control = _current_stripable->send_level_controllable (n); @@ -1153,6 +1208,37 @@ Console1::map_comp_emph () } } +void Console1::eqBandQChangeMapping(){ + + DEBUG_TRACE(DEBUG::Console1, string_compose("eqBandQChangeMapping(): band_q_as_send = %1, strip_eq_mode = %2\n", band_q_as_send, strip_eq_mode)); + Encoder* lme = get_encoder (LOW_MID_SHAPE); + Encoder* hme = get_encoder (HIGH_MID_SHAPE); + switch_eq_q_dials = band_q_as_send || (strip_eq_mode == EQM_HARRISON ); + + if (!lme || !hme) + { + DEBUG_TRACE (DEBUG::Console1, "eqBandQChangeMapping: Controller not found \n"); + return; + } + + if ( switch_eq_q_dials ) + { + DEBUG_TRACE (DEBUG::Console1, "eqBandQChangeMapping() set harrison or send mode\n"); + lme->set_action(std::function (std::bind (&Console1::mb_send_level, this, 10, _1))); + hme->set_action(std::function (std::bind (&Console1::mb_send_level, this, 11, _1))); + map_mb_send_level (10); + map_mb_send_level (11); + } + else + { + DEBUG_TRACE (DEBUG::Console1, "eqBandQChangeMapping() set ssl q mode\n"); + lme->set_action(std::function (std::bind (&Console1::eq_band_q, this, 1, _1))); + hme->set_action(std::function (std::bind (&Console1::eq_band_q, this, 2, _1))); + map_eq_band_q (1); + map_eq_band_q (2); + } +} + void Console1::eqBandQChangeMapping (bool mapValues) { DEBUG_TRACE(DEBUG::Console1, string_compose("eqBandQChangeMapping(): band_q_as_send = %1, strip_eq_mode = %2, mapValues = %3 \n", band_q_as_send, strip_eq_mode, mapValues)); diff --git a/libs/surfaces/console1/console1.h b/libs/surfaces/console1/console1.h index e4cc90fbfc3..ebd44e19693 100644 --- a/libs/surfaces/console1/console1.h +++ b/libs/surfaces/console1/console1.h @@ -128,7 +128,7 @@ class Console1 : public MIDISurface return _in_use; } - PBD::Signal ConnectionChange; + PBD::Signal ConnectionChange; /* Timer Events */ PBD::Signal BlinkIt; @@ -224,7 +224,7 @@ class Console1 : public MIDISurface EQM_SSL = 1 }; - using ControllerMap = std::map; + using ControllerMap = std::map; ControllerMap controllerMap{ { "CONTROLLER_NONE", ControllerID::CONTROLLER_NONE }, { "VOLUME", ControllerID::VOLUME }, @@ -332,7 +332,7 @@ class Console1 : public MIDISurface // Selected EQ EQ_MODE strip_eq_mode = EQM_UNDEFINED; - bool rolling = false; + bool rolling = false; uint32_t current_bank = 0; uint32_t current_strippable_index = 0; @@ -451,7 +451,7 @@ class Console1 : public MIDISurface void drop_current_stripable (); /*void use_master (); void use_monitor ();*/ - void stripable_selection_changed () override; + void stripable_selection_changed () override; /*PBD::ScopedConnection selection_connection;*/ PBD::ScopedConnectionList stripable_connections; PBD::ScopedConnectionList console1_connections; @@ -462,7 +462,7 @@ class Console1 : public MIDISurface void notify_parameter_changed (std::string) override; void band_q_usage_changed (); - /* operations (defined in c1_operations.cc) */ + /* operations (defined in c1_operations.cc) */ void bank (bool up); void drive (uint32_t value); @@ -665,6 +665,8 @@ class Console1 : public MIDISurface bool map_select_plugin (const int32_t plugin_index); + void eqBandQChangeMapping(); + void eqBandQChangeMapping (bool mapValues); diff --git a/libs/surfaces/console1/wscript b/libs/surfaces/console1/wscript index 5668b9cee52..ac26bf386f2 100644 --- a/libs/surfaces/console1/wscript +++ b/libs/surfaces/console1/wscript @@ -22,6 +22,11 @@ def build(bld): obj.includes = [ '.', './console1'] obj.name = 'libardour_console1' obj.target = 'ardour_console1' - obj.uselib = 'SIGCPP XML OSX GLIBMM GIOMM PANGOMM' - obj.use = 'libardour libardour_cp libardour_midisurface libgtkmm2ext libpbd libevoral libtemporal libytkmm' + obj.uselib = 'SIGCPP XML OSX' + obj.use = 'libardour libardour_cp libardour_midisurface libgtkmm2ext libpbd libevoral libtemporal' obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces') + if bld.is_defined('YTK'): + obj.use += ' libytkmm' + obj.uselib += ' GLIBMM GIOMM PANGOMM' + else: + obj.uselib += ' GTKMM' From 67ac10116e3b2df9a018e0f4984182cd456b02ce Mon Sep 17 00:00:00 2001 From: Hoger Dehnhardt Date: Tue, 22 Jul 2025 18:06:36 +0200 Subject: [PATCH 3/7] Split spill plugins method --- libs/surfaces/console1/c1_gui.cc | 2 +- libs/surfaces/console1/c1_gui.h | 7 +- .../surfaces/console1/c1_plugin_operations.cc | 336 ++++++++++-------- libs/surfaces/console1/console1.h | 34 +- 4 files changed, 231 insertions(+), 148 deletions(-) diff --git a/libs/surfaces/console1/c1_gui.cc b/libs/surfaces/console1/c1_gui.cc index c1977e3a343..c8c20a5a97d 100644 --- a/libs/surfaces/console1/c1_gui.cc +++ b/libs/surfaces/console1/c1_gui.cc @@ -19,10 +19,10 @@ #include "c1_gui.h" #include +#include #include #include -#include #include "pbd/file_utils.h" #include "pbd/i18n.h" #include "pbd/strsplit.h" diff --git a/libs/surfaces/console1/c1_gui.h b/libs/surfaces/console1/c1_gui.h index 3d048d447e4..a981a082859 100644 --- a/libs/surfaces/console1/c1_gui.h +++ b/libs/surfaces/console1/c1_gui.h @@ -23,11 +23,13 @@ #include #include -#include #include +#include +#include #include #include #include +#include #include #include #include @@ -41,8 +43,7 @@ #include namespace Gtk { - class CellRendererCombo; - class ListStore; + class ListStore; } namespace ActionManager { diff --git a/libs/surfaces/console1/c1_plugin_operations.cc b/libs/surfaces/console1/c1_plugin_operations.cc index a22252706b2..2db7bad4d1e 100644 --- a/libs/surfaces/console1/c1_plugin_operations.cc +++ b/libs/surfaces/console1/c1_plugin_operations.cc @@ -153,8 +153,9 @@ Console1::load_mapping (XMLNode* mapping_xml) } void -Console1::create_mapping (const std::shared_ptr proc, const std::shared_ptr plugin) +Console1::create_plugin_mapping_stubs (const std::shared_ptr proc, const std::shared_ptr plugin) { + DEBUG_TRACE (DEBUG::Console1, "create_plugin_mapping_stubs \n"); XMLTree* tree = new XMLTree (); XMLNode node = XMLNode ("c1plugin-mapping"); node.set_property ("ID", plugin->unique_id ()); @@ -165,7 +166,7 @@ Console1::create_mapping (const std::shared_ptr proc, const std::shar for (set::iterator j = p.begin (); j != p.end (); ++j) { ++n_controls; std::string n = proc->describe_parameter (*j); - DEBUG_TRACE (DEBUG::Console1, string_compose ("Plugin parameter %1: %2\n", n_controls, n)); + DEBUG_TRACE (DEBUG::Console1, string_compose ("create_plugin_mapping_stubs: Plugin parameter %1: %2\n", n_controls, n)); if (n == "hidden") { continue; } @@ -203,7 +204,7 @@ Console1::write_plugin_mapping (PluginMapping &mapping) node.set_property ("NAME", mapping.name); for (const auto& plugin_param : mapping.parameters ) { - DEBUG_TRACE (DEBUG::Console1, string_compose ("Plugin parameter %1: %2\n",plugin_param.first ,plugin_param.second.name)); + DEBUG_TRACE (DEBUG::Console1, string_compose ("write_plugin_mapping: Plugin parameter %1: %2\n",plugin_param.first ,plugin_param.second.name)); XMLNode param = XMLNode ("param-mapping"); param.set_property ("id", plugin_param.second.paramIndex); XMLNode name = XMLNode ("name"); @@ -350,147 +351,204 @@ Console1::find_plugin (const int32_t plugin_index) } bool -Console1::spill_plugins (const int32_t plugin_index) +Console1::setup_plugin_mute_button(const std::shared_ptr& plugin_insert) { - bool mapping_found = false; - - remove_plugin_operations (); - - std::shared_ptr proc = find_plugin (plugin_index); - if (!proc) - return false; - - int32_t n_controls = -1; - DEBUG_TRACE (DEBUG::Console1, string_compose ("Found plugin %1\n", proc->name ())); - std::shared_ptr plugin_insert = std::dynamic_pointer_cast (proc); - if (!plugin_insert) - return false; - - std::shared_ptr plugin = plugin_insert->plugin (); - if (!plugin) - return false; - - DEBUG_TRACE (DEBUG::Console1, string_compose ("Found plugin id %1\n", plugin->unique_id ())); - - try { - ControllerButton* cb = get_button (ControllerID::MUTE); - std::function plugin_mapping = [=] () -> void { cb->set_led_state (!plugin_insert->enabled ()); }; - cb->set_plugin_action ([=] (uint32_t val) { - plugin_insert->enable (val == 0); - DEBUG_TRACE (DEBUG::Console1, - string_compose ("ControllerButton Plugin parameter %1: %2 \n", n_controls, val)); - }); - - plugin_insert->ActiveChanged.connect ( - plugin_connections, MISSING_INVALIDATOR, std::bind (plugin_mapping), this); - plugin_insert->ActiveChanged (); - } catch (ControlNotFoundException const&) { - DEBUG_TRACE (DEBUG::Console1, string_compose ("No ControllerButton found %1\n", n_controls)); - } - PluginMappingMap::iterator pmmit = pluginMappingMap.find (plugin->unique_id ()); - mapping_found = (pmmit != pluginMappingMap.end ()); - - if (!mapping_found) { - if (create_mapping_stubs) { - create_mapping (proc, plugin); - } - return true; - } + int32_t n_controls = -1; + try { + ControllerButton* cb = get_button (ControllerID::MUTE); + std::function plugin_mapping = [=] () -> void { cb->set_led_state (!plugin_insert->enabled ()); }; + cb->set_plugin_action ([=] (uint32_t val) { + plugin_insert->enable (val == 0); + DEBUG_TRACE (DEBUG::Console1, + string_compose ("ControllerButton Plugin parameter %1: %2 \n", n_controls, val)); + }); + + plugin_insert->ActiveChanged.connect ( + plugin_connections, MISSING_INVALIDATOR, std::bind (plugin_mapping), this); + plugin_insert->ActiveChanged (); + return true; + } catch (ControlNotFoundException const&) { + DEBUG_TRACE (DEBUG::Console1, string_compose ("No ControllerButton found %1\n", n_controls)); + return false; + } +} - PluginMapping pluginMapping = pmmit->second; +bool +Console1::setup_plugin_encoder(const PluginParameterMapping& ppm, int32_t n_controls, + const ParameterDescriptor& parameterDescriptor, + const std::shared_ptr& c) +{ + try { + Encoder* e = get_encoder (ppm.controllerId); + std::function plugin_mapping = + [=](bool b, PBD::Controllable::GroupControlDisposition d) -> void { + double origin = c->get_value(); + double v = parameterDescriptor.to_interface(origin, true); + e->set_value (v * 127); + DEBUG_TRACE ( + DEBUG::Console1, + string_compose ("to: <-Encoder Plugin parameter %1: origin %2 translated %3 - %4\n", n_controls, origin, v , v * 127)); + }; + if( !ppm.shift ) + e->set_plugin_action ([=] (uint32_t val) { + double v = val / 127.f; + double translated = parameterDescriptor.from_interface(v, true); + c->set_value( translated, + PBD::Controllable::GroupControlDisposition::UseGroup); + DEBUG_TRACE ( + DEBUG::Console1, + string_compose ("from: ->Encoder Plugin parameter %1: origin %2 calculated %3 translated %4\n", n_controls, val, v, translated )); + }); + else + e->set_plugin_shift_action ([=] (uint32_t val) { + double v = val / 127.f; + double translated = parameterDescriptor.from_interface(v, true); + c->set_value( translated, + PBD::Controllable::GroupControlDisposition::UseGroup); + DEBUG_TRACE ( + DEBUG::Console1, + string_compose ("from: ->Encoder Plugin shift-parameter %1: origin %2 calculated %3 translated %4\n", n_controls, val, v, translated )); + }); + c->Changed.connect ( + plugin_connections, MISSING_INVALIDATOR, std::bind (plugin_mapping, _1, _2), this); + c->Changed (true, PBD::Controllable::GroupControlDisposition::UseGroup); + return true; + } catch (ControlNotFoundException const&) { + DEBUG_TRACE (DEBUG::Console1, string_compose ("No Encoder found %1\n", n_controls)); + return false; + } +} - DEBUG_TRACE (DEBUG::Console1, - string_compose ("Plugin mapping found for id %1, name %2\n", pluginMapping.id, pluginMapping.name)); +bool +Console1::setup_plugin_button(const PluginParameterMapping& ppm, int32_t n_controls, + const ParameterDescriptor& parameterDescriptor, + const std::shared_ptr& c) +{ + try { + ControllerButton* cb = get_button (ppm.controllerId); + std::function plugin_mapping = + [=] (bool b, PBD::Controllable::GroupControlDisposition d) -> void { + cb->set_led_state (c->get_value ()); + DEBUG_TRACE (DEBUG::Console1, + string_compose ("<-ControllerButton Plugin parameter %1: %2 \n", + n_controls, + c->get_value ())); + }; + cb->set_plugin_action ([=] (uint32_t val) { + double v = val / 127.f; + c->set_value (parameterDescriptor.from_interface (v, true), + PBD::Controllable::GroupControlDisposition::UseGroup); + DEBUG_TRACE ( + DEBUG::Console1, + string_compose ("->ControllerButton Plugin parameter %1: %2 - %3\n", n_controls, val, v)); + }); + + c->Changed.connect ( + plugin_connections, MISSING_INVALIDATOR, std::bind (plugin_mapping, _1, _2), this); + c->Changed (true, PBD::Controllable::GroupControlDisposition::UseGroup); + return true; + } catch (ControlNotFoundException const&) { + DEBUG_TRACE (DEBUG::Console1, string_compose ("No ControllerButton found %1\n", n_controls)); + return false; + } +} - set p = proc->what_can_be_automated (); +bool +Console1::handle_plugin_parameter(const PluginParameterMapping& ppm, int32_t n_controls, + const ParameterDescriptor& parameterDescriptor, + const std::shared_ptr& c) +{ + bool swtch = false; + if (parameterDescriptor.integer_step && parameterDescriptor.upper == 1) { + swtch = true; + } else if (ppm.is_switch) { + swtch = true; + } + if (!swtch) { + return setup_plugin_encoder(ppm, n_controls, parameterDescriptor, c); + } else { + return setup_plugin_button(ppm, n_controls, parameterDescriptor, c); + } +} - for (set::iterator j = p.begin (); j != p.end (); ++j) { - ++n_controls; - std::string n = proc->describe_parameter (*j); - DEBUG_TRACE (DEBUG::Console1, string_compose ("Plugin parameter %1: %2\n", n_controls, n)); - if (n == "hidden") { - continue; - } - ParameterDescriptor parameterDescriptor; - plugin->get_parameter_descriptor (n_controls, parameterDescriptor); - if (plugin->parameter_is_control (n_controls)) { - DEBUG_TRACE (DEBUG::Console1, "parameter is control\n"); - } - if (plugin->parameter_is_output (n_controls)) { - DEBUG_TRACE (DEBUG::Console1, "parameter is output\n"); - } - if (plugin->parameter_is_audio (n_controls)) { - DEBUG_TRACE (DEBUG::Console1, "parameter is audio\n"); - } - if (plugin->parameter_is_input (n_controls)) { - std::shared_ptr c = - plugin_insert->automation_control (Evoral::Parameter (PluginAutomation, 0, n_controls)); - if (c) { - PluginParameterMapping ppm = pluginMapping.parameters[n_controls]; - bool swtch = false; - if (parameterDescriptor.integer_step && parameterDescriptor.upper == 1) { - swtch = true; - } else if (ppm.is_switch) { - swtch = true; - } - if (!swtch) { - try { - Encoder* e = get_encoder (ppm.controllerId); - std::function plugin_mapping = - [=] (bool b, PBD::Controllable::GroupControlDisposition d) -> void { - double v = parameterDescriptor.to_interface (c->get_value (), true); - e->set_value (v * 127); - DEBUG_TRACE ( - DEBUG::Console1, - string_compose ("<-Encoder Plugin parameter %1: %2 - %3\n", n_controls, v * 127, v)); - }; - e->set_plugin_action ([=] (uint32_t val) { - double v = val / 127.f; - c->set_value (parameterDescriptor.from_interface (v, true), - PBD::Controllable::GroupControlDisposition::UseGroup); - DEBUG_TRACE ( - DEBUG::Console1, - string_compose ("->Encoder Plugin parameter %1: %2 - %3\n", n_controls, val, v)); - }); - c->Changed.connect ( - plugin_connections, MISSING_INVALIDATOR, std::bind (plugin_mapping, _1, _2), this); - c->Changed (true, PBD::Controllable::GroupControlDisposition::UseGroup); - continue; - } catch (ControlNotFoundException const&) { - DEBUG_TRACE (DEBUG::Console1, string_compose ("No Encoder found %1\n", n_controls)); - } - } else { - try { - ControllerButton* cb = get_button (ppm.controllerId); - std::function plugin_mapping = - [=] (bool b, PBD::Controllable::GroupControlDisposition d) -> void { - cb->set_led_state (c->get_value ()); - DEBUG_TRACE (DEBUG::Console1, - string_compose ("<-ControllerButton Plugin parameter %1: %2 \n", - n_controls, - c->get_value ())); - }; - cb->set_plugin_action ([=] (uint32_t val) { - double v = val / 127.f; - c->set_value (parameterDescriptor.from_interface (v, true), - PBD::Controllable::GroupControlDisposition::UseGroup); - DEBUG_TRACE ( - DEBUG::Console1, - string_compose ("->ControllerButton Plugin parameter %1: %2 - %3\n", n_controls, val, v)); - }); - - c->Changed.connect ( - plugin_connections, MISSING_INVALIDATOR, std::bind (plugin_mapping, _1, _2), this); - c->Changed (true, PBD::Controllable::GroupControlDisposition::UseGroup); - continue; - } catch (ControlNotFoundException const&) { - DEBUG_TRACE (DEBUG::Console1, string_compose ("No ControllerButton found %1\n", n_controls)); - } - } - } - } - } - return true; +bool +Console1::spill_plugins (const int32_t plugin_index) +{ + bool mapping_found = false; + + remove_plugin_operations (); + + std::shared_ptr proc = find_plugin (plugin_index); + if (!proc) + return false; + + int32_t n_controls = -1; + DEBUG_TRACE (DEBUG::Console1, string_compose ("Found plugin %1\n", proc->name ())); + std::shared_ptr plugin_insert = std::dynamic_pointer_cast (proc); + if (!plugin_insert) + return false; + + std::shared_ptr plugin = plugin_insert->plugin (); + if (!plugin) + return false; + + DEBUG_TRACE (DEBUG::Console1, string_compose ("Found plugin id %1\n", plugin->unique_id ())); + + // Setup mute button + setup_plugin_mute_button(plugin_insert); + + PluginMappingMap::iterator pmmit = pluginMappingMap.find (plugin->unique_id ()); + mapping_found = (pmmit != pluginMappingMap.end ()); + + if (!mapping_found) { + if (create_mapping_stubs) { + create_plugin_mapping_stubs (proc, plugin); + } + return true; + } + + PluginMapping pluginMapping = pmmit->second; + + DEBUG_TRACE (DEBUG::Console1, + string_compose ("Plugin mapping found for id %1, name %2\n", pluginMapping.id, pluginMapping.name)); + + set p = proc->what_can_be_automated (); + + for (set::iterator j = p.begin (); j != p.end (); ++j) { + ++n_controls; + std::string n = proc->describe_parameter (*j); + DEBUG_TRACE (DEBUG::Console1, string_compose ("Plugin parameter %1: %2\n", n_controls, n)); + if (n == "hidden") { + continue; + } + ParameterDescriptor parameterDescriptor; + plugin->get_parameter_descriptor (n_controls, parameterDescriptor); + if (plugin->parameter_is_control (n_controls)) { + DEBUG_TRACE (DEBUG::Console1, "parameter is control\n"); + DEBUG_TRACE (DEBUG::Console1, string_compose("normal: %1, lower %2, upper %3, toogled %4, log %5, num steps %6\n", + parameterDescriptor.normal, + parameterDescriptor.lower, + parameterDescriptor.upper, + parameterDescriptor.toggled, + parameterDescriptor.logarithmic, + parameterDescriptor.rangesteps ) ) + } + if (plugin->parameter_is_output (n_controls)) { + DEBUG_TRACE (DEBUG::Console1, "parameter is output\n"); + } + if (plugin->parameter_is_audio (n_controls)) { + DEBUG_TRACE (DEBUG::Console1, "parameter is audio\n"); + } + if (plugin->parameter_is_input (n_controls)) { + std::shared_ptr c = + plugin_insert->automation_control (Evoral::Parameter (PluginAutomation, 0, n_controls)); + if (c) { + PluginParameterMapping ppm = pluginMapping.parameters[n_controls]; + handle_plugin_parameter(ppm, n_controls, parameterDescriptor, c); + } + } + } + return true; } Glib::RefPtr Console1::getPluginControllerModel() diff --git a/libs/surfaces/console1/console1.h b/libs/surfaces/console1/console1.h index ebd44e19693..48a2fcfbd4b 100644 --- a/libs/surfaces/console1/console1.h +++ b/libs/surfaces/console1/console1.h @@ -23,14 +23,15 @@ #include #include -#include -#include +#include +#include #include #define ABSTRACT_UI_EXPORTS #include "pbd/abstract_ui.h" +#include "ardour/parameter_descriptor.h" #include "ardour/presentation_info.h" #include "control_protocol/control_protocol.h" @@ -654,11 +655,34 @@ class Console1 : public MIDISurface /* plugin handling */ bool ensure_config_dir (); bool load_mapping (XMLNode* fin); - void create_mapping (const std::shared_ptr proc, const std::shared_ptr plugin); + + /** + * @brief Creates mapping stubs for a given plugin processor. + * + * This function sets up the necessary mapping stubs to associate the specified + * plugin with its processor, enabling control surface integration or automation. + * + * @param proc Shared pointer to the ARDOUR::Processor instance to be mapped. + * @param plugin Shared pointer to the ARDOUR::Plugin instance for which mapping stubs are created. + */ + void create_plugin_mapping_stubs (const std::shared_ptr proc, const std::shared_ptr plugin); bool spill_plugins (const int32_t plugin_index); - - /* plugin operations */ + bool setup_plugin_mute_button (const std::shared_ptr &plugin_insert); + + bool setup_plugin_encoder (const PluginParameterMapping &ppm, int32_t n_controls, + const ARDOUR::ParameterDescriptor ¶meterDescriptor, + const std::shared_ptr &c); + + bool setup_plugin_button (const PluginParameterMapping &ppm, int32_t n_controls, + const ARDOUR::ParameterDescriptor ¶meterDescriptor, + const std::shared_ptr &c); + + bool handle_plugin_parameter (const PluginParameterMapping &ppm, int32_t n_controls, + const ARDOUR::ParameterDescriptor ¶meterDescriptor, + const std::shared_ptr &c); + + /* plugin operations */ void remove_plugin_operations (); std::shared_ptr find_plugin (const int32_t plugin_index); bool select_plugin (const int32_t plugin_index); From 28c89ef3d6c1056e38d7fc8e885c7198151276df Mon Sep 17 00:00:00 2001 From: Hoger Dehnhardt Date: Wed, 23 Jul 2025 08:51:01 +0200 Subject: [PATCH 4/7] Merge... --- libs/surfaces/console1/c1_gui.h | 10 ---- libs/surfaces/console1/c1_operations.cc | 77 ------------------------- libs/surfaces/console1/console1.h | 2 - 3 files changed, 89 deletions(-) diff --git a/libs/surfaces/console1/c1_gui.h b/libs/surfaces/console1/c1_gui.h index a981a082859..9a6217ba164 100644 --- a/libs/surfaces/console1/c1_gui.h +++ b/libs/surfaces/console1/c1_gui.h @@ -32,15 +32,6 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include namespace Gtk { class ListStore; @@ -74,7 +65,6 @@ class C1GUI : public Gtk::Notebook Gtk::Image image; Gtk::CheckButton swap_solo_mute_cb; Gtk::CheckButton band_q_as_send_cb; - Gtk::CheckButton band_q_as_send_cb; Gtk::CheckButton create_plugin_stubs_btn; Gtk::TreeView plugin_assignment_editor; diff --git a/libs/surfaces/console1/c1_operations.cc b/libs/surfaces/console1/c1_operations.cc index 1d0dce9524b..097408d894d 100644 --- a/libs/surfaces/console1/c1_operations.cc +++ b/libs/surfaces/console1/c1_operations.cc @@ -417,17 +417,6 @@ Console1::eq_band_q (const uint32_t band, uint32_t value) session->set_control (control, freq, PBD::Controllable::UseGroup); } -void -Console1::eq_band_q (const uint32_t band, uint32_t value) -{ - if (!_current_stripable || !_current_stripable->mapped_control (EQ_BandQ, band)) { - return; - } - std::shared_ptr control = _current_stripable->mapped_control (EQ_BandQ, band); - double freq = midi_to_control (control, value); - session->set_control (control, freq, PBD::Controllable::UseGroup); -} - // The Mixbus-Sends are in the EQ section // Without Shift: // LowMid Shape is Send 11 @@ -931,42 +920,6 @@ Console1::map_eq () } } -void -Console1::map_eq_mode (){ -#ifdef MIXBUS - DEBUG_TRACE (DEBUG::Console1, "Enter map_eq_mode()\n"); - if (!_current_stripable) - return; - std::shared_ptr rt = std::dynamic_pointer_cast( _current_stripable ); - if (!rt) - return; - EQ_MODE current_eq_mode = EQ_MODE (rt->eq_mode_control() ? rt->eq_mode_control()->get_value() : -1); - DEBUG_TRACE (DEBUG::Console1, string_compose ("map_eq_mode() - mode: %1\n", current_eq_mode)); - if (current_eq_mode != strip_eq_mode) - { - strip_eq_mode = current_eq_mode; - EQBandQBindingChange(); - } -#endif -} - - -void -Console1::map_eq_band_q (const uint32_t band) -{ - DEBUG_TRACE (DEBUG::Console1, string_compose( "map_eq_band_q band: %1 \n", band)); - if (shift_state || switch_eq_q_dials) { - DEBUG_TRACE (DEBUG::Console1, "Exit map_eq_band_q 1\n"); - return; - } - ControllerID controllerID = eq_q_controller_for_band (band); - if (map_encoder (controllerID)) { - std::shared_ptr control = _current_stripable->mapped_control (EQ_BandQ, band); - map_encoder (controllerID, control); - } -} - - void Console1::map_eq_mode () { @@ -1208,36 +1161,6 @@ Console1::map_comp_emph () } } -void Console1::eqBandQChangeMapping(){ - - DEBUG_TRACE(DEBUG::Console1, string_compose("eqBandQChangeMapping(): band_q_as_send = %1, strip_eq_mode = %2\n", band_q_as_send, strip_eq_mode)); - Encoder* lme = get_encoder (LOW_MID_SHAPE); - Encoder* hme = get_encoder (HIGH_MID_SHAPE); - switch_eq_q_dials = band_q_as_send || (strip_eq_mode == EQM_HARRISON ); - - if (!lme || !hme) - { - DEBUG_TRACE (DEBUG::Console1, "eqBandQChangeMapping: Controller not found \n"); - return; - } - - if ( switch_eq_q_dials ) - { - DEBUG_TRACE (DEBUG::Console1, "eqBandQChangeMapping() set harrison or send mode\n"); - lme->set_action(std::function (std::bind (&Console1::mb_send_level, this, 10, _1))); - hme->set_action(std::function (std::bind (&Console1::mb_send_level, this, 11, _1))); - map_mb_send_level (10); - map_mb_send_level (11); - } - else - { - DEBUG_TRACE (DEBUG::Console1, "eqBandQChangeMapping() set ssl q mode\n"); - lme->set_action(std::function (std::bind (&Console1::eq_band_q, this, 1, _1))); - hme->set_action(std::function (std::bind (&Console1::eq_band_q, this, 2, _1))); - map_eq_band_q (1); - map_eq_band_q (2); - } -} void Console1::eqBandQChangeMapping (bool mapValues) { diff --git a/libs/surfaces/console1/console1.h b/libs/surfaces/console1/console1.h index 48a2fcfbd4b..ea654dd80c9 100644 --- a/libs/surfaces/console1/console1.h +++ b/libs/surfaces/console1/console1.h @@ -689,8 +689,6 @@ class Console1 : public MIDISurface bool map_select_plugin (const int32_t plugin_index); - void eqBandQChangeMapping(); - void eqBandQChangeMapping (bool mapValues); From fbf640095588119129336b3698286a5dda3b19e1 Mon Sep 17 00:00:00 2001 From: Hoger Dehnhardt Date: Fri, 25 Jul 2025 17:09:12 +0200 Subject: [PATCH 5/7] use a single controller list --- libs/surfaces/console1/c1_control.h | 262 ++++++++++-------- libs/surfaces/console1/c1_gui.cc | 8 +- libs/surfaces/console1/c1_gui.h | 6 +- libs/surfaces/console1/c1_operations.cc | 16 +- .../surfaces/console1/c1_plugin_operations.cc | 58 ++-- libs/surfaces/console1/console1.cc | 168 ++++++----- libs/surfaces/console1/console1.h | 241 ++++++++-------- libs/surfaces/console1/console1_interface.cc | 5 +- 8 files changed, 394 insertions(+), 370 deletions(-) diff --git a/libs/surfaces/console1/c1_control.h b/libs/surfaces/console1/c1_control.h index 2629c03e924..e1f377ecf1f 100644 --- a/libs/surfaces/console1/c1_control.h +++ b/libs/surfaces/console1/c1_control.h @@ -4,66 +4,146 @@ #include "ardour/debug.h" #include "console1.h" -namespace ArdourSurface { +namespace Console1 +{ using ControllerID = Console1::ControllerID; class Controller { - public: - enum ControllerType - { - CONTROLLER, - CONTROLLER_BUTTON, - MULTISTATE_BUTTON, - ENCODER, - METER - }; +public: Controller (Console1* console1, ControllerID id) - : console1 (console1) - , _id (id) + : console1 (console1) + , _id (id) + { + } + + Controller (Console1* console1, + ControllerID id, + std::function action, + std::function shift_action = 0, + std::function plugin_action = 0, + std::function plugin_shift_action = 0) + : console1 (console1) + , _id (id) + , action (action) + , shift_action (shift_action) + , plugin_action (plugin_action) + , plugin_shift_action (plugin_shift_action) + { + } + + virtual ~Controller () + { + } + + Console1* console1; + ControllerID id () const + { + return _id; + } + + virtual void clear_value() {} + + virtual ControllerType get_type () + { + return CONTROLLER; + } + + void set_action (std::function new_action) { + action = new_action; } - virtual ~Controller () {} + void set_plugin_action (std::function new_action) + { + plugin_action = new_action; + } + + void set_plugin_shift_action (std::function new_action) + { + plugin_shift_action = new_action; + } + std::function get_action (){ + return action; + } + std::function get_shift_action () + { + return shift_action; + } + + std::function get_plugin_action () + { + return plugin_action; + } + + std::function get_plugin_shift_action () + { + return plugin_shift_action; + } + +protected: + ControllerID _id; + std::function action; + std::function shift_action; + std::function plugin_action; + std::function plugin_shift_action; +}; + +class Encoder : public Controller +{ +public: + Encoder (Console1* console1, + ControllerID id, + std::function action, + std::function shift_action = 0, + std::function plugin_action = 0, + std::function plugin_shift_action = 0) + : Controller (console1, id, action, shift_action, plugin_action, plugin_shift_action) + { + console1->controllerMap.insert (std::make_pair (id, this)); + } + + ControllerType get_type () + { + return ENCODER; + } - Console1* console1; - ControllerID id () const { return _id; } + virtual void set_value (uint32_t value) + { + MIDI::byte buf[3]; + buf[0] = 0xB0; + buf[1] = _id; + buf[2] = value; - virtual ControllerType get_type () { return CONTROLLER; } + console1->write (buf, 3); + } - protected: - ControllerID _id; + PBD::Signal* plugin_signal; }; class ControllerButton : public Controller { - public: - ControllerButton (Console1* console1, - ControllerID id, +public: + ControllerButton (Console1* console1, + ControllerID id, std::function action, - std::function shift_action = 0, - std::function plugin_action = 0, - std::function plugin_shift_action = 0 ) - : Controller (console1, id) - , action (action) - , shift_action (shift_action) - , plugin_action (plugin_action) - , plugin_shift_action (plugin_shift_action) + std::function shift_action = 0, + std::function plugin_action = 0, + std::function plugin_shift_action = 0) + : Controller (console1, id, action, shift_action, plugin_action, plugin_shift_action) { - console1->buttons.insert (std::make_pair (id, this)); + console1->controllerMap.insert (std::make_pair (id, this)); } - ControllerType get_type () { return CONTROLLER_BUTTON; } - - void set_action (std::function new_action) { action = new_action; } - void set_plugin_action (std::function new_action) { plugin_action = new_action; } - void set_plugin_shift_action (std::function new_action) { plugin_shift_action = new_action; } + ControllerType get_type () + { + return CONTROLLER_BUTTON; + } virtual void set_led_state (bool onoff) { - // DEBUG_TRACE(DEBUG::Console1, "ControllerButton::set_led_state ...\n"); MIDI::byte buf[3]; buf[0] = 0xB0; buf[1] = _id; @@ -74,7 +154,6 @@ class ControllerButton : public Controller virtual void set_led_value (uint32_t val) { - // DEBUG_TRACE(DEBUG::Console1, "ControllerButton::set_led_state ...\n"); MIDI::byte buf[3]; buf[0] = 0xB0; buf[1] = _id; @@ -82,34 +161,28 @@ class ControllerButton : public Controller console1->write (buf, 3); } - std::function action; - std::function shift_action; - std::function plugin_action; - std::function plugin_shift_action; }; class MultiStateButton : public Controller { - public: - MultiStateButton (Console1* console1, - ControllerID id, - std::vector state_values, +public: + MultiStateButton (Console1* console1, + ControllerID id, + std::vector state_values, std::function action, - std::function shift_action = 0, - std::function plugin_action = 0, - std::function plugin_shift_action = 0 - ) - : Controller (console1, id) - , action (action) - , shift_action (shift_action) - , plugin_action (action) - , plugin_shift_action (shift_action) - , state_values (state_values) + std::function shift_action = 0, + std::function plugin_action = 0, + std::function plugin_shift_action = 0) + : Controller (console1, id, action, shift_action, plugin_action, plugin_shift_action) + , state_values (state_values) { - console1->multi_buttons.insert (std::make_pair (id, this)); + console1->controllerMap.insert (std::make_pair (id, this)); } - ControllerType get_type () { return MULTISTATE_BUTTON; } + ControllerType get_type () + { + return MULTISTATE_BUTTON; + } virtual void set_led_state (uint32_t state) { @@ -123,36 +196,33 @@ class MultiStateButton : public Controller console1->write (buf, 3); } - void set_action (std::function new_action) { action = new_action; } - void set_plugin_action (std::function new_action) { plugin_action = new_action; } - void set_plugin_shift_action (std::function new_action) { plugin_shift_action = new_action; } - - uint32_t state_count () { return state_values.size (); } - - std::function action; - std::function shift_action; - std::function plugin_action; - std::function plugin_shift_action; + uint32_t state_count () + { + return state_values.size (); + } - private: +private: std::vector state_values; }; class Meter : public Controller { - public: - Meter (Console1* console1, - ControllerID id, +public: + Meter (Console1* console1, + ControllerID id, std::function action, std::function shift_action = 0) - : Controller (console1, id) - , action (action) - , shift_action (shift_action) + : Controller (console1, id) + , action (action) + , shift_action (shift_action) { console1->meters.insert (std::make_pair (id, this)); } - ControllerType get_type () { return METER; } + ControllerType get_type () + { + return METER; + } virtual void set_value (uint32_t value) { @@ -167,46 +237,6 @@ class Meter : public Controller std::function shift_action; }; -class Encoder : public Controller -{ - public: - Encoder (Console1* console1, - ControllerID id, - std::function action, - std::function shift_action = 0, - std::function plugin_action = 0, - std::function plugin_shift_action = 0) - : Controller (console1, id) - , action (action) - , shift_action (shift_action) - , plugin_action (plugin_action) - , plugin_shift_action (plugin_action) - { - console1->encoders.insert (std::make_pair (id, this)); - } - - ControllerType get_type () { return ENCODER; } - - void set_action (std::function new_action) { action = new_action; } - void set_plugin_action (std::function new_action) { plugin_action = new_action; } - void set_plugin_shift_action (std::function new_action) { plugin_shift_action = new_action; } - - virtual void set_value (uint32_t value) - { - MIDI::byte buf[3]; - buf[0] = 0xB0; - buf[1] = _id; - buf[2] = value; - - console1->write (buf, 3); - } - std::function action; - std::function shift_action; - std::function plugin_action; - std::function plugin_shift_action; - - PBD::Signal* plugin_signal; -}; +} // namespace Console1 -} #endif // ardour_surface_console1_button_h diff --git a/libs/surfaces/console1/c1_gui.cc b/libs/surfaces/console1/c1_gui.cc index c8c20a5a97d..9214b0ba3c5 100644 --- a/libs/surfaces/console1/c1_gui.cc +++ b/libs/surfaces/console1/c1_gui.cc @@ -40,11 +40,13 @@ using namespace PBD; using namespace ARDOUR; -using namespace ArdourSurface; using namespace std; using namespace Gtk; using namespace Gtkmm2ext; +namespace Console1 +{ + void* Console1::get_gui () const { @@ -383,7 +385,7 @@ C1GUI::change_controller (const Glib::ustring &sPath, const TreeModel::iterator string controllerName = (*iter)[c1.plugin_controller_columns.controllerName]; int controllerId = (*iter)[c1.plugin_controller_columns.controllerId]; - pc.parameters[index].controllerId = ArdourSurface::Console1::ControllerID (controllerId); + pc.parameters[index].controllerId = Console1::ControllerID (controllerId); (*row).set_value (plugin_assignment_editor_columns.controllerName, controllerName); DEBUG_TRACE (DEBUG::Console1, string_compose ("Column Name: Controller, index %1, name %2 \n", index, controllerName)); @@ -488,3 +490,5 @@ void C1GUI::write_plugin_assignment(){ c1.write_plugin_mapping (pc); assignement_changed = false; } + +} // namespace Console1 \ No newline at end of file diff --git a/libs/surfaces/console1/c1_gui.h b/libs/surfaces/console1/c1_gui.h index 9a6217ba164..3594d6a7a61 100644 --- a/libs/surfaces/console1/c1_gui.h +++ b/libs/surfaces/console1/c1_gui.h @@ -45,7 +45,7 @@ namespace ActionManager { #include "console1.h" -namespace ArdourSurface { +namespace Console1 { class C1GUI : public Gtk::Notebook { @@ -120,7 +120,7 @@ class C1GUI : public Gtk::Notebook Glib::RefPtr build_midi_port_list (std::vector const & ports, bool for_input); - ArdourSurface::Console1::PluginMapping pc; + Console1::PluginMapping pc; Gtk::CellRendererCombo* make_action_renderer (Glib::RefPtr model, Gtk::TreeModelColumnBase column); void build_plugin_assignment_editor (); @@ -135,6 +135,6 @@ class C1GUI : public Gtk::Notebook void active_plugin_changed (Gtk::ComboBox* combo); void write_plugin_assignment (); }; -} +} // namespace Console1 #endif /* __ardour_console1_gui_h__ */ diff --git a/libs/surfaces/console1/c1_operations.cc b/libs/surfaces/console1/c1_operations.cc index 097408d894d..4c95eae1b74 100644 --- a/libs/surfaces/console1/c1_operations.cc +++ b/libs/surfaces/console1/c1_operations.cc @@ -27,13 +27,15 @@ #include "console1.h" using namespace ARDOUR; -using namespace ArdourSurface; using namespace PBD; using namespace Glib; using namespace std; /* Operations */ +namespace Console1 +{ + void Console1::bank (bool up) { @@ -145,7 +147,7 @@ Console1::select (const uint32_t i) void Console1::shift (const uint32_t val) { - DEBUG_TRACE (DEBUG::Console1, "shift()\n"); + DEBUG_TRACE (DEBUG::Console1, string_compose( "shift (%1)\n", val )); shift_state = !shift_state; ShiftChange (val); } @@ -674,7 +676,7 @@ Console1::map_select () void Console1::map_shift (bool shift) { - DEBUG_TRACE (DEBUG::Console1, "map_shift()\n"); + DEBUG_TRACE (DEBUG::Console1, string_compose ("map_shift(%1)\n", shift)); try { ControllerButton* controllerButton = get_button (PRESET); controllerButton->set_led_state (shift); @@ -687,7 +689,7 @@ Console1::map_shift (bool shift) void Console1::map_plugin_state (bool plugin_state) { - DEBUG_TRACE (DEBUG::Console1, "map_plugin_state()\n"); + DEBUG_TRACE (DEBUG::Console1, string_compose ("map_plugin_state(%1)\n", plugin_state) ); try { ControllerButton* controllerButton = get_button (TRACK_GROUP); controllerButton->set_led_state (in_plugin_state); @@ -699,10 +701,6 @@ Console1::map_plugin_state (bool plugin_state) stop_blinking (ControllerID (FOCUS1 + i)); } map_stripable_state (); - } else { - // I don't plan shift functionality with plugins... - shift (0); - // map all plugin related operations } } @@ -1237,3 +1235,5 @@ Console1::map_encoder (ControllerID controllerID, std::shared_ptrsecond; } @@ -289,24 +289,23 @@ Console1::remove_plugin_operations () { plugin_connections.drop_connections (); - for (auto& e : encoders) { - e.second->set_plugin_action (0); - e.second->set_plugin_shift_action (0); - e.second->set_value (0); - } - for (auto& b : buttons) { - if (b.first == ControllerID::TRACK_GROUP) + for (auto& c : controllerMap) { + if (c.first == ControllerID::TRACK_GROUP) continue; - if (b.first >= ControllerID::FOCUS1 && b.first <= ControllerID::FOCUS20) + if (c.first >= ControllerID::FOCUS1 && c.first <= ControllerID::FOCUS20) continue; - b.second->set_plugin_action (0); - b.second->set_plugin_shift_action (0); - b.second->set_led_state (false); - } - for (auto& m : multi_buttons) { - m.second->set_plugin_action (0); - m.second->set_plugin_shift_action (0); - m.second->set_led_state (false); + c.second->set_plugin_action (0); + c.second->set_plugin_shift_action (0); + c.second->clear_value (); + if( c.second->get_type() == ControllerType::CONTROLLER_BUTTON ) + { + ControllerButton* b = dynamic_cast (c.second); + b->set_led_state (false); + } else if (c.second->get_type () == ControllerType::MULTISTATE_BUTTON ) + { + MultiStateButton* b = dynamic_cast (c.second); + b->set_led_state (false); + } } } @@ -326,12 +325,15 @@ Console1::find_plugin (const int32_t plugin_index) while ((ext_plugin_index < plugin_index) && (int_plugin_index < (int)bank_size)) { ++int_plugin_index; + DEBUG_TRACE (DEBUG::Console1, string_compose ("find_plugin: int index %1, ext index %2\n", int_plugin_index, ext_plugin_index)); proc = r->nth_plugin (int_plugin_index); if (!proc) { + DEBUG_TRACE (DEBUG::Console1, "find_plugin: plugin not found\n"); continue; - ; } + DEBUG_TRACE (DEBUG::Console1, "find_plugin: plugin found\n"); if (!proc->display_to_user ()) { + DEBUG_TRACE (DEBUG::Console1, "find_plugin: display to user failed\n"); continue; } @@ -483,7 +485,7 @@ Console1::spill_plugins (const int32_t plugin_index) return false; int32_t n_controls = -1; - DEBUG_TRACE (DEBUG::Console1, string_compose ("Found plugin %1\n", proc->name ())); + DEBUG_TRACE (DEBUG::Console1, string_compose ("spill_plugins: Found plugin %1\n", proc->name ())); std::shared_ptr plugin_insert = std::dynamic_pointer_cast (proc); if (!plugin_insert) return false; @@ -492,7 +494,7 @@ Console1::spill_plugins (const int32_t plugin_index) if (!plugin) return false; - DEBUG_TRACE (DEBUG::Console1, string_compose ("Found plugin id %1\n", plugin->unique_id ())); + DEBUG_TRACE (DEBUG::Console1, string_compose ("spill_plugins: Found plugin id %1\n", plugin->unique_id ())); // Setup mute button setup_plugin_mute_button(plugin_insert); @@ -510,15 +512,15 @@ Console1::spill_plugins (const int32_t plugin_index) PluginMapping pluginMapping = pmmit->second; DEBUG_TRACE (DEBUG::Console1, - string_compose ("Plugin mapping found for id %1, name %2\n", pluginMapping.id, pluginMapping.name)); + string_compose ("spill_plugins: Plugin mapping found for id %1, name %2\n", pluginMapping.id, pluginMapping.name)); set p = proc->what_can_be_automated (); for (set::iterator j = p.begin (); j != p.end (); ++j) { ++n_controls; std::string n = proc->describe_parameter (*j); - DEBUG_TRACE (DEBUG::Console1, string_compose ("Plugin parameter %1: %2\n", n_controls, n)); - if (n == "hidden") { + DEBUG_TRACE (DEBUG::Console1, string_compose ("spill_plugins: Plugin parameter %1: %2\n", n_controls, n)); + if (n == "hidden") { continue; } ParameterDescriptor parameterDescriptor; @@ -555,7 +557,7 @@ Glib::RefPtr Console1::getPluginControllerModel() { plugin_controller_model = Gtk::ListStore::create (plugin_controller_columns); Gtk::TreeModel::Row plugin_controller_combo_row; - for( const auto &controller : controllerMap ){ + for( const auto &controller : controllerNameIdMap ){ plugin_controller_combo_row = *(plugin_controller_model->append ()); plugin_controller_combo_row[plugin_controller_columns.controllerId] = controller.second; plugin_controller_combo_row[plugin_controller_columns.controllerName] = X_(controller.first); @@ -563,4 +565,4 @@ Glib::RefPtr Console1::getPluginControllerModel() return plugin_controller_model; } -} +} // namespace Console1 diff --git a/libs/surfaces/console1/console1.cc b/libs/surfaces/console1/console1.cc index c4ad5f57fc2..023a65027da 100644 --- a/libs/surfaces/console1/console1.cc +++ b/libs/surfaces/console1/console1.cc @@ -41,12 +41,16 @@ #include "c1_control.h" #include "c1_gui.h" + + using namespace ARDOUR; -using namespace ArdourSurface; using namespace PBD; using namespace Glib; using namespace std; +namespace Console1 +{ + Console1::Console1 (Session& s) : MIDISurface (s, X_ ("Softube Console1"), X_ ("Console1"), false) , gui (0) @@ -66,25 +70,17 @@ Console1::~Console1 () stop_event_loop (); MIDISurface::drop (); - for (const auto& b : buttons) { - delete b.second; - } - for (const auto& e : encoders) { - delete e.second; - } - for (const auto& m : meters) { - delete m.second; - } - for (const auto& mb : multi_buttons) { - delete mb.second; + for (const auto& c : controllerMap) { + delete c.second; } } void Console1::all_lights_out () { - for (ButtonMap::iterator b = buttons.begin (); b != buttons.end (); ++b) { - b->second->set_led_state (false); + for (ControllerMap::iterator b = controllerMap.begin (); b != controllerMap.end (); ++b) { + if( b->second->get_type() == ControllerType::CONTROLLER_BUTTON ) + (dynamic_cast(b->second))->set_led_state (false); } } @@ -277,18 +273,22 @@ Console1::setup_controls () for (uint32_t i = 0; i < 20; ++i) { new ControllerButton (this, - ControllerID (FOCUS1 + i), - std::function (std::bind (&Console1::select, this, i)), - 0, - std::function (std::bind (&Console1::select_plugin, this, i))); + ControllerID (FOCUS1 + i), + std::function (std::bind (&Console1::select, this, i)), + std::function (std::bind (&Console1::select, this, i)), + std::function (std::bind (&Console1::select_plugin, this, i)), + std::function (std::bind (&Console1::select_plugin, this, i))); } new ControllerButton ( this, ControllerID::PRESET, std::function (std::bind (&Console1::shift, this, _1))); new ControllerButton (this, - ControllerID::TRACK_GROUP, - std::function (std::bind (&Console1::plugin_state, this, _1))); + ControllerID::TRACK_GROUP, + std::function (std::bind (&Console1::plugin_state, this, _1)), + std::function (std::bind (&Console1::plugin_state, this, _1)), + std::function (std::bind (&Console1::plugin_state, this, _1)), + std::function (std::bind (&Console1::plugin_state, this, _1))); new ControllerButton ( this, ControllerID::DISPLAY_ON, std::function (std::bind (&Console1::rude_solo, this, _1))); @@ -438,60 +438,38 @@ void Console1::handle_midi_controller_message (MIDI::Parser&, MIDI::EventTwoBytes* tb) { uint32_t controller_number = static_cast (tb->controller_number); - uint32_t value = static_cast (tb->value); -DEBUG_TRACE (DEBUG::Console1, + uint32_t value = static_cast (tb->value); + DEBUG_TRACE (DEBUG::Console1, string_compose ("handle_midi_controller_message cn: '%1' val: '%2'\n", controller_number, value)); - try { - Encoder* e = get_encoder (ControllerID (controller_number)); - if (in_plugin_state && e->plugin_action) { - e->plugin_action (value); - } else if (shift_state && e->shift_action) { - e->shift_action (value); - } else { - e->action (value); - } - return; - } catch (ControlNotFoundException const&) { - DEBUG_TRACE (DEBUG::Console1, - string_compose ("handle_midi_controller_message: encoder not found cn: " - "'%1' val: '%2'\n", - controller_number, - value)); - } - - try { - ControllerButton* b = get_button (ControllerID (controller_number)); - if (in_plugin_state && b->plugin_action) { - DEBUG_TRACE (DEBUG::Console1, "Executing plugin_action\n"); - b->plugin_action (value); - } else if (shift_state && b->shift_action) { - DEBUG_TRACE (DEBUG::Console1, "Executing shift_action\n"); - b->shift_action (value); - } else { - DEBUG_TRACE (DEBUG::Console1, "Executing action\n"); - b->action (value); - } - return; - } catch (ControlNotFoundException const&) { - DEBUG_TRACE (DEBUG::Console1, - string_compose ("handle_midi_controller_message: button not found cn: " - "'%1' val: '%2'\n", - controller_number, - value)); - } + DEBUG_TRACE (DEBUG::Console1, + string_compose ("handle_midi_controller_message shift state: '%1' plugin state: '%2'\n", shift_state, in_plugin_state)); try { - MultiStateButton* mb = get_mbutton (ControllerID (controller_number)); - if (shift_state && mb->shift_action) { - mb->shift_action (value); - } else { - mb->action (value); + Controller* controller = controllerMap[ControllerID (controller_number)]; + if (controller ) { + DEBUG_TRACE (DEBUG::Console1, "handle_midi_controller_message; Controller Found'\n"); + if (shift_state && in_plugin_state && controller->get_plugin_shift_action ()) { + controller->get_plugin_shift_action () (value); + DEBUG_TRACE (DEBUG::Console1, "handle_midi_controller_message: plugin_shift_action'\n" ); + } else if (in_plugin_state && controller->get_plugin_action ()) { + controller->get_plugin_action () (value); + DEBUG_TRACE (DEBUG::Console1, "handle_midi_controller_message: plugin_action'\n"); + } else if (shift_state && controller->get_shift_action ()) { + controller->get_shift_action () (value); + DEBUG_TRACE (DEBUG::Console1, "handle_midi_controller_message: shift_action'\n"); + } else { + controller->get_action () (value); + DEBUG_TRACE (DEBUG::Console1, "handle_midi_controller_message: action'\n"); + } + return; } - - return; - } catch (ControlNotFoundException const&) { + else { + DEBUG_TRACE (DEBUG::Console1, "handle_midi_controller_message: Controller not found'\n"); + } + } + catch (ControlNotFoundException const&) { DEBUG_TRACE (DEBUG::Console1, - string_compose ("handle_midi_controller_message: mbutton not found cn: " + string_compose ("handle_midi_controller_message: encoder not found cn: " "'%1' val: '%2'\n", controller_number, value)); @@ -955,15 +933,6 @@ Console1::blinker () return true; } -ControllerButton* -Console1::get_button (ControllerID id) const -{ - ButtonMap::const_iterator b = buttons.find (id); - if (b == buttons.end ()) - throw (ControlNotFoundException ()); - return const_cast (b->second); -} - Meter* Console1::get_meter (ControllerID id) const { @@ -973,22 +942,42 @@ Console1::get_meter (ControllerID id) const return const_cast (m->second); } +Controller* +Console1::get_controller (ControllerID id) const +{ + ControllerMap::const_iterator c = controllerMap.find (id); + if (c == controllerMap.end ()) + throw (ControlNotFoundException ()); + return (c->second); +} + +Controller* +Console1::get_controller (ControllerID id, ControllerType controllerType) const +{ + ControllerMap::const_iterator c = controllerMap.find (id); + if ((c == controllerMap.end ()) || (c->second->get_type () != controllerType)) + throw (ControlNotFoundException ()); + return (c->second); +} + Encoder* Console1::get_encoder (ControllerID id) const { - EncoderMap::const_iterator m = encoders.find (id); - if (m == encoders.end ()) - throw (ControlNotFoundException ()); - return const_cast (m->second); + return dynamic_cast (get_controller (id, ControllerType::ENCODER)); +} + +ControllerButton* +Console1::get_button (ControllerID id) const +{ + return dynamic_cast (get_controller (id, ControllerType::CONTROLLER_BUTTON)); } + + MultiStateButton* Console1::get_mbutton (ControllerID id) const { - MultiStateButtonMap::const_iterator m = multi_buttons.find (id); - if (m == multi_buttons.end ()) - throw (ControlNotFoundException ()); - return const_cast (m->second); + return dynamic_cast (get_controller (id, ControllerType::MULTISTATE_BUTTON)); } ControllerID @@ -1263,10 +1252,11 @@ Console1::master_monitor_has_changed () } const std::string Console1::findControllerNameById (const ControllerID id){ - for( const auto &controller : controllerMap ){ + for( const auto &controller : controllerNameIdMap ){ if( controller.second == id ){ return controller.first; - } + } } return std::string(); -} \ No newline at end of file +} +} // namespace Console1 \ No newline at end of file diff --git a/libs/surfaces/console1/console1.h b/libs/surfaces/console1/console1.h index ea654dd80c9..c7bb5626c80 100644 --- a/libs/surfaces/console1/console1.h +++ b/libs/surfaces/console1/console1.h @@ -61,20 +61,15 @@ namespace PBD { class Controllable; } +namespace Console1 +{ + class MIDIControllable; class MIDIFunction; class MIDIAction; -namespace ArdourSurface { - class C1GUI; -// XXX TODO: these classes should not be in the ArdourSurface namespace -// which is shared with all other ctrl surfaces. -// -// ArdourSurface::Meter etc may cause conflicts. -// best add a C1 prefix, or additional namespace - class Controller; class ControllerButton; class MultiStateButton; @@ -92,6 +87,14 @@ class ControlNotFoundException : public std::exception ControlNotFoundException () {} }; +enum ControllerType { + CONTROLLER, + CONTROLLER_BUTTON, + MULTISTATE_BUTTON, + ENCODER, + METER +}; + class Console1 : public MIDISurface { @@ -141,18 +144,17 @@ class Console1 : public MIDISurface PBD::Signal PluginStateChange; PBD::Signal EQBandQBindingChange; - enum ControllerID - { - CONTROLLER_NONE = 0, - VOLUME = 7, - PAN = 10, - MUTE = 12, - SOLO = 13, - ORDER = 14, - DRIVE = 15, + enum ControllerID { + CONTROLLER_NONE = 0, + VOLUME = 7, + PAN = 10, + MUTE = 12, + SOLO = 13, + ORDER = 14, + DRIVE = 15, EXTERNAL_SIDECHAIN = 17, - CHARACTER = 18, - FOCUS1 = 21, + CHARACTER = 18, + FOCUS1 = 21, FOCUS2, FOCUS3, FOCUS4, @@ -171,63 +173,62 @@ class Console1 : public MIDISurface FOCUS17, FOCUS18, FOCUS19, - FOCUS20 = 40, - COMP = 46, - COMP_THRESH = 47, - COMP_RELEASE = 48, - COMP_RATIO = 49, - COMP_PAR = 50, - COMP_ATTACK = 51, - SHAPE = 53, - SHAPE_GATE = 54, - SHAPE_SUSTAIN = 55, - SHAPE_RELEASE = 56, - SHAPE_PUNCH = 57, - PRESET = 58, - HARD_GATE = 59, + FOCUS20 = 40, + COMP = 46, + COMP_THRESH = 47, + COMP_RELEASE = 48, + COMP_RATIO = 49, + COMP_PAR = 50, + COMP_ATTACK = 51, + SHAPE = 53, + SHAPE_GATE = 54, + SHAPE_SUSTAIN = 55, + SHAPE_RELEASE = 56, + SHAPE_PUNCH = 57, + PRESET = 58, + HARD_GATE = 59, FILTER_TO_COMPRESSORS = 61, - HIGH_SHAPE = 65, - EQ = 80, - HIGH_GAIN = 82, - HIGH_FREQ = 83, - HIGH_MID_GAIN = 85, - HIGH_MID_FREQ = 86, - HIGH_MID_SHAPE = 87, - LOW_MID_GAIN = 88, - LOW_MID_FREQ = 89, - LOW_MID_SHAPE = 90, - LOW_GAIN = 91, - LOW_FREQ = 92, - LOW_SHAPE = 93, - PAGE_UP = 96, - PAGE_DOWN = 97, - DISPLAY_ON = 102, - LOW_CUT = 103, - MODE = 104, - HIGH_CUT = 105, - GAIN = 107, - PHASE_INV = 108, - INPUT_METER_L = 110, - INPUT_METER_R = 111, - OUTPUT_METER_L = 112, - OUTPUT_METER_R = 113, - SHAPE_METER = 114, - COMP_METER = 115, - TRACK_COPY = 120, - TRACK_GROUP = 123, + HIGH_SHAPE = 65, + EQ = 80, + HIGH_GAIN = 82, + HIGH_FREQ = 83, + HIGH_MID_GAIN = 85, + HIGH_MID_FREQ = 86, + HIGH_MID_SHAPE = 87, + LOW_MID_GAIN = 88, + LOW_MID_FREQ = 89, + LOW_MID_SHAPE = 90, + LOW_GAIN = 91, + LOW_FREQ = 92, + LOW_SHAPE = 93, + PAGE_UP = 96, + PAGE_DOWN = 97, + DISPLAY_ON = 102, + LOW_CUT = 103, + MODE = 104, + HIGH_CUT = 105, + GAIN = 107, + PHASE_INV = 108, + INPUT_METER_L = 110, + INPUT_METER_R = 111, + OUTPUT_METER_L = 112, + OUTPUT_METER_R = 113, + SHAPE_METER = 114, + COMP_METER = 115, + TRACK_COPY = 120, + TRACK_GROUP = 123, }; - enum EQ_MODE - { - EQM_UNDEFINED = -1, - EQM_HARRISON = 0, - EQM_SSL = 1 - }; + enum EQ_MODE { + EQM_UNDEFINED = -1, + EQM_HARRISON = 0, + EQM_SSL = 1 + }; - using ControllerMap = std::map; + using ControllerNameIdMap = std::map; - ControllerMap controllerMap{ { "CONTROLLER_NONE", ControllerID::CONTROLLER_NONE }, + ControllerNameIdMap controllerNameIdMap{ { "CONTROLLER_NONE", ControllerID::CONTROLLER_NONE }, { "VOLUME", ControllerID::VOLUME }, { "PAN", ControllerID::PAN }, { "MUTE", ControllerID::MUTE }, @@ -394,74 +395,72 @@ class Console1 : public MIDISurface void select_rid_by_index (const uint32_t index); /* Controller Maps*/ - typedef std::map ButtonMap; - typedef std::map MultiStateButtonMap; - typedef std::map MeterMap; - typedef std::map EncoderMap; + typedef std::map MeterMap; - ButtonMap buttons; - ControllerButton* get_button (ControllerID) const; + typedef std::map ControllerMap; - MultiStateButtonMap multi_buttons; - MultiStateButton* get_mbutton (ControllerID id) const; + MeterMap meters; + Meter* get_meter (ControllerID) const; + ControllerButton* get_button (ControllerID) const; - MeterMap meters; - Meter* get_meter (ControllerID) const; + MultiStateButton* get_mbutton (ControllerID id) const; - EncoderMap encoders; - Encoder* get_encoder (ControllerID) const; + Encoder* get_encoder (ControllerID) const; - typedef std::map SendControllerMap; - SendControllerMap send_controllers{ { 0, LOW_FREQ }, { 1, LOW_MID_FREQ }, { 2, HIGH_MID_FREQ }, - { 3, HIGH_FREQ }, { 4, LOW_GAIN }, { 5, LOW_MID_GAIN }, - { 6, HIGH_MID_GAIN }, { 7, HIGH_GAIN }, { 8, LOW_MID_SHAPE }, - { 9, HIGH_MID_SHAPE }, { 10, LOW_MID_SHAPE }, { 11, HIGH_MID_SHAPE } }; + ControllerMap controllerMap; + Controller* get_controller (ControllerID id) const; + Controller* get_controller (ControllerID id, ControllerType controllerType) const; - ControllerID get_send_controllerid (uint32_t); + typedef std::map SendControllerMap; + SendControllerMap send_controllers{ { 0, LOW_FREQ }, { 1, LOW_MID_FREQ }, { 2, HIGH_MID_FREQ }, { 3, HIGH_FREQ }, + { 4, LOW_GAIN }, { 5, LOW_MID_GAIN }, { 6, HIGH_MID_GAIN }, { 7, HIGH_GAIN }, + { 8, LOW_MID_SHAPE }, { 9, HIGH_MID_SHAPE }, { 10, LOW_MID_SHAPE }, { 11, HIGH_MID_SHAPE } }; - /* */ - void all_lights_out (); + ControllerID get_send_controllerid (uint32_t); - void notify_transport_state_changed () override; - void notify_solo_active_changed (bool) override; + /* */ + void all_lights_out (); - sigc::connection periodic_connection; + void notify_transport_state_changed () override; + void notify_solo_active_changed (bool) override; - bool periodic (); - void periodic_update_meter (); + sigc::connection periodic_connection; - // Meter Handlig - uint32_t last_output_meter_l = 0; - uint32_t last_output_meter_r = 0; + bool periodic (); + void periodic_update_meter (); - std::shared_ptr gate_redux_meter = 0; - uint32_t last_gate_meter = 0; + // Meter Handlig + uint32_t last_output_meter_l = 0; + uint32_t last_output_meter_r = 0; - std::shared_ptr comp_redux_meter = 0; - uint32_t last_comp_redux = 0; + std::shared_ptr gate_redux_meter = 0; + uint32_t last_gate_meter = 0; - sigc::connection blink_connection; - typedef std::list Blinkers; - Blinkers blinkers; - bool blink_state; - bool blinker (); - void start_blinking (ControllerID); - void stop_blinking (ControllerID); + std::shared_ptr comp_redux_meter = 0; + uint32_t last_comp_redux = 0; - void set_current_stripable (std::shared_ptr); - void drop_current_stripable (); - /*void use_master (); - void use_monitor ();*/ + sigc::connection blink_connection; + typedef std::list Blinkers; + Blinkers blinkers; + bool blink_state; + bool blinker (); + void start_blinking (ControllerID); + void stop_blinking (ControllerID); + + void set_current_stripable (std::shared_ptr); + void drop_current_stripable (); + /*void use_master (); + void use_monitor ();*/ void stripable_selection_changed () override; - /*PBD::ScopedConnection selection_connection;*/ - PBD::ScopedConnectionList stripable_connections; - PBD::ScopedConnectionList console1_connections; - PBD::ScopedConnectionList plugin_connections; + /*PBD::ScopedConnection selection_connection;*/ + PBD::ScopedConnectionList stripable_connections; + PBD::ScopedConnectionList console1_connections; + PBD::ScopedConnectionList plugin_connections; - void map_stripable_state (); + void map_stripable_state (); - void notify_parameter_changed (std::string) override; - void band_q_usage_changed (); + void notify_parameter_changed (std::string) override; + void band_q_usage_changed (); /* operations (defined in c1_operations.cc) */ @@ -707,5 +706,5 @@ class Console1 : public MIDISurface Glib::RefPtr getPluginControllerModel(); void write_plugin_mapping (PluginMapping &mapping); }; -} +} // namespace Console1 #endif /* ardour_surface_console1_h */ diff --git a/libs/surfaces/console1/console1_interface.cc b/libs/surfaces/console1/console1_interface.cc index 0b04edc0bd7..636ec2c6f37 100644 --- a/libs/surfaces/console1/console1_interface.cc +++ b/libs/surfaces/console1/console1_interface.cc @@ -22,15 +22,14 @@ #include "console1.h" using namespace ARDOUR; -using namespace ArdourSurface; static ControlProtocol* new_console1 (Session* s) { - Console1* console1 = 0; + Console1::Console1* console1 = 0; try { - console1 = new Console1 (*s); + console1 = new Console1::Console1 (*s); } catch (failed_constructor& err) { delete console1; console1 = 0; From be0debf66a96fc014880cbb4cb7a9dc3e0d1281c Mon Sep 17 00:00:00 2001 From: Hoger Dehnhardt Date: Tue, 29 Jul 2025 21:44:22 +0200 Subject: [PATCH 6/7] enable assignment with MIDI separate plugin assignment gui from other config --- libs/surfaces/console1/c1_gui.cc | 170 ++----------- libs/surfaces/console1/c1_gui.h | 40 +-- .../console1/c1_plugin_control_assignment.cc | 231 ++++++++++++++++++ .../surfaces/console1/c1_plugin_operations.cc | 2 +- libs/surfaces/console1/console1.cc | 8 +- libs/surfaces/console1/console1.h | 171 ++++++------- libs/surfaces/console1/wscript | 1 + 7 files changed, 364 insertions(+), 259 deletions(-) create mode 100644 libs/surfaces/console1/c1_plugin_control_assignment.cc diff --git a/libs/surfaces/console1/c1_gui.cc b/libs/surfaces/console1/c1_gui.cc index 9214b0ba3c5..2b7810b2447 100644 --- a/libs/surfaces/console1/c1_gui.cc +++ b/libs/surfaces/console1/c1_gui.cc @@ -177,55 +177,28 @@ C1GUI::C1GUI (Console1& p) // Create the page for plugin mappings p.load_mappings (); - VBox* plugconfig_packer = manage (new VBox); - HBox* plugselect_packer = manage (new HBox); - - l = manage (new Gtk::Label (_("Select Plugin"))); - plugselect_packer->pack_start (*l, false, false); - - plugconfig_packer->pack_start (*plugselect_packer, false, false); - - Glib::RefPtr plugin_store_model = ListStore::create (plugin_columns); - TreeModel::Row plugin_combo_row; - for( const auto &pm : c1.getPluginMappingMap() ){ - plugin_combo_row = *(plugin_store_model->append ()); - plugin_combo_row[plugin_columns.plugin_name] = pm.second.name; - plugin_combo_row[plugin_columns.plugin_id] = pm.first; - DEBUG_TRACE (DEBUG::Console1, string_compose ("Add Plugin: name %1 / %2\n", pm.second.name, pm.first)); - } - plugins_combo.pack_start (plugin_columns.plugin_name); - plugins_combo.signal_changed ().connect ( - sigc::bind (sigc::mem_fun (*this, &C1GUI::active_plugin_changed), &plugins_combo)); - plugins_combo.set_model (plugin_store_model); - - plugselect_packer->pack_start (plugins_combo, true, true); - plugin_mapping_scroller.property_shadow_type() = Gtk::SHADOW_NONE; - plugin_mapping_scroller.set_policy(Gtk::PolicyType::POLICY_AUTOMATIC, Gtk::PolicyType::POLICY_AUTOMATIC); - - plugin_mapping_scroller.add (plugin_assignment_editor); - plugconfig_packer->pack_start (plugin_mapping_scroller, true, true, 20); + VBox* plugconfig_packer = build_plugin_assignment_page(); - build_plugin_assignment_editor (); + append_page (*plugconfig_packer, _ ("Plugin Mappings")); + plugconfig_packer->show_all (); - append_page (*plugconfig_packer, _ ("Plugin Mappings")); - plugconfig_packer->show_all (); + /* update the port connection combos */ - /* update the port connection combos */ - - update_port_combos (); + update_port_combos (); - /* catch future changes to connection state */ + /* catch future changes to connection state */ - ARDOUR::AudioEngine::instance ()->PortRegisteredOrUnregistered.connect ( - _port_connections, invalidator (*this), std::bind (&C1GUI::connection_handler, this), gui_context ()); - ARDOUR::AudioEngine::instance ()->PortPrettyNameChanged.connect ( - _port_connections, invalidator (*this), std::bind (&C1GUI::connection_handler, this), gui_context ()); - c1.ConnectionChange.connect ( - _port_connections, invalidator (*this), std::bind (&C1GUI::connection_handler, this), gui_context ()); + ARDOUR::AudioEngine::instance ()->PortRegisteredOrUnregistered.connect ( + _port_connections, invalidator (*this), std::bind (&C1GUI::connection_handler, this), gui_context ()); + ARDOUR::AudioEngine::instance ()->PortPrettyNameChanged.connect ( + _port_connections, invalidator (*this), std::bind (&C1GUI::connection_handler, this), gui_context ()); + c1.ConnectionChange.connect ( + _port_connections, invalidator (*this), std::bind (&C1GUI::connection_handler, this), gui_context ()); } C1GUI::~C1GUI () { - write_plugin_assignment(); + DEBUG_TRACE (DEBUG::Console1, "1GUI::~C1GUI ()\n"); + c1.midi_assign_mode = false; } void @@ -375,120 +348,5 @@ C1GUI::active_port_changed (Gtk::ComboBox* combo, bool for_input) } } -void -C1GUI::change_controller (const Glib::ustring &sPath, const TreeModel::iterator &iter) -{ - Gtk::TreePath path(sPath); - Gtk::TreeModel::iterator row = plugin_assignment_store->get_iter(path); - int index = *path.begin (); - if (row) { - - string controllerName = (*iter)[c1.plugin_controller_columns.controllerName]; - int controllerId = (*iter)[c1.plugin_controller_columns.controllerId]; - pc.parameters[index].controllerId = Console1::ControllerID (controllerId); - (*row).set_value (plugin_assignment_editor_columns.controllerName, controllerName); - DEBUG_TRACE (DEBUG::Console1, - string_compose ("Column Name: Controller, index %1, name %2 \n", index, controllerName)); - assignement_changed = true; - } -} - -void C1GUI::toggle_shift( const Glib::ustring& s){ - int index = atoi (s.c_str()); - Gtk::TreeModel::iterator row = plugin_assignment_store->get_iter (s); - if( row ) - { - bool value = !pc.parameters[index].shift; - pc.parameters[index].shift = value; - (*row).set_value (plugin_assignment_editor_columns.shift, value); - DEBUG_TRACE (DEBUG::Console1, string_compose ("Column Name: Shift, value %1\n", value)); - assignement_changed = true; - } -} - -CellRendererCombo* -C1GUI::make_action_renderer (Glib::RefPtr model, Gtk::TreeModelColumnBase column) -{ - CellRendererCombo* renderer = manage (new CellRendererCombo); - renderer->property_model() = model; - renderer->property_editable() = true; - renderer->property_text_column () = 0; - renderer->property_has_entry () = false; - renderer->signal_changed().connect (sigc::mem_fun(*this, &C1GUI::change_controller)); - - return renderer; -} - -void -C1GUI::build_plugin_assignment_editor () -{ - plugin_assignment_editor.append_column (_("Key"), plugin_assignment_editor_columns.index); - plugin_assignment_editor.append_column (_("Name"), plugin_assignment_editor_columns.name); - plugin_assignment_editor.append_column (_("Switch"), plugin_assignment_editor_columns.is_switch); - - TreeViewColumn* col; - CellRendererCombo* renderer; - - CellRendererToggle* boolRenderer = manage (new CellRendererToggle); - boolRenderer->set_active (); - boolRenderer->property_activatable() = true; - col = manage (new TreeViewColumn (_ ("Shift"), *boolRenderer)); - col->add_attribute (boolRenderer->property_active (), plugin_assignment_editor_columns.shift); - boolRenderer->signal_toggled().connect (sigc::mem_fun(*this, &C1GUI::toggle_shift)); - plugin_assignment_editor.append_column (*col); - - - renderer = make_action_renderer (c1.getPluginControllerModel(), plugin_assignment_editor_columns.controllerName); - col = manage (new TreeViewColumn (_("Control"), *renderer)); - col->add_attribute (renderer->property_text(), plugin_assignment_editor_columns.controllerName); - plugin_assignment_editor.append_column (*col); - - plugin_assignment_store = ListStore::create (plugin_assignment_editor_columns); - plugin_assignment_editor.set_model (plugin_assignment_store); -} - - -void -C1GUI::active_plugin_changed(Gtk::ComboBox* combo ){ - DEBUG_TRACE (DEBUG::Console1, "C1GUI active_plugin_changed\n"); - - write_plugin_assignment (); - - plugin_assignment_editor.set_model (Glib::RefPtr()); - plugin_assignment_store->clear (); - - TreeModel::iterator active = combo->get_active (); - TreeModel::Row plugin_assignment_row; - - string new_plugin_name = (*active)[plugin_columns.plugin_name]; - string new_plugin_id = (*active)[plugin_columns.plugin_id]; - DEBUG_TRACE (DEBUG::Console1, string_compose ("Plugin: selected %1 / %2\n", new_plugin_name, new_plugin_id)); - pc = c1.getPluginMappingMap ()[new_plugin_id]; - - for( auto &parm : pc.parameters ){ - plugin_assignment_row = *(plugin_assignment_store->append ()); - plugin_assignment_row[plugin_assignment_editor_columns.index] = parm.first; - plugin_assignment_row[plugin_assignment_editor_columns.name] = parm.second.name; - plugin_assignment_row[plugin_assignment_editor_columns.controllerName] = c1.findControllerNameById(parm.second.controllerId); - plugin_assignment_row[plugin_assignment_editor_columns.is_switch] = parm.second.is_switch; - plugin_assignment_row[plugin_assignment_editor_columns.shift] = parm.second.shift; - - DEBUG_TRACE (DEBUG::Console1, string_compose ("Parameter Name %1 \n", parm.second.name)); - DEBUG_TRACE (DEBUG::Console1, string_compose ("Parameter Index: %1 - index %2 \n", parm.first, parm.second.paramIndex)); - DEBUG_TRACE (DEBUG::Console1, string_compose ("ControllerId: %1 \n", parm.second.controllerId)); - DEBUG_TRACE (DEBUG::Console1, string_compose ("is switch? %1 \n", parm.second.is_switch)); - DEBUG_TRACE (DEBUG::Console1, string_compose ("is shift? %1 \n", parm.second.shift)); - } - plugin_assignment_editor.set_model (plugin_assignment_store); - -} - -void C1GUI::write_plugin_assignment(){ - DEBUG_TRACE (DEBUG::Console1, "write_plugin_assignment\n"); - if( !assignement_changed ) - return; - c1.write_plugin_mapping (pc); - assignement_changed = false; -} } // namespace Console1 \ No newline at end of file diff --git a/libs/surfaces/console1/c1_gui.h b/libs/surfaces/console1/c1_gui.h index 3594d6a7a61..47ad79f0935 100644 --- a/libs/surfaces/console1/c1_gui.h +++ b/libs/surfaces/console1/c1_gui.h @@ -56,22 +56,23 @@ class C1GUI : public Gtk::Notebook private: Console1& c1; PBD::ScopedConnectionList lcxl_connections; - Gtk::VBox hpacker; - Gtk::Table table; - Gtk::ComboBox input_combo; - Gtk::ComboBox output_combo; - Gtk::ComboBox plugins_combo; - Gtk::ScrolledWindow plugin_mapping_scroller; - Gtk::Image image; + Gtk::VBox hpacker; + Gtk::Table table; + Gtk::ComboBox input_combo; + Gtk::ComboBox output_combo; + + Gtk::Image image; Gtk::CheckButton swap_solo_mute_cb; Gtk::CheckButton band_q_as_send_cb; Gtk::CheckButton create_plugin_stubs_btn; - Gtk::TreeView plugin_assignment_editor; - - Gtk::VBox plugin_packer; + Gtk::ScrolledWindow plugin_mapping_scroller; + Gtk::ComboBox plugins_combo; + Gtk::TreeView plugin_assignment_editor; + Gtk::ToggleButton* midi_assign_button; + Gtk::VBox plugin_packer; - bool assignement_changed = false; + sigc::signal plugin_assignment_changed; void update_port_combos (); PBD::ScopedConnection connection_change_connection; @@ -120,17 +121,20 @@ class C1GUI : public Gtk::Notebook Glib::RefPtr build_midi_port_list (std::vector const & ports, bool for_input); + Console1::PluginMapping pc; + Gtk::VBox* build_plugin_assignment_page (); Gtk::CellRendererCombo* make_action_renderer (Glib::RefPtr model, Gtk::TreeModelColumnBase column); - void build_plugin_assignment_editor (); - - void change_controller (const Glib::ustring &, const Gtk::TreeIter&); - void toggle_shift ( const Glib::ustring& ); - - void active_port_changed (Gtk::ComboBox*, bool for_input); + void build_plugin_assignment_editor (); + void plugin_assignment_editor_selection_changed (); + void change_controller_number (int controllerNumber, bool shiftState); + void midi_assign_button_toggled (Gtk::ToggleButton* b); + void change_controller (const Glib::ustring&, const Gtk::TreeIter&); + void toggle_shift (const Glib::ustring&); + void active_port_changed (Gtk::ComboBox*, bool for_input); void set_swap_solo_mute (); - void set_band_q_as_send(); + void set_band_q_as_send (); void set_create_mapping_stubs (); void active_plugin_changed (Gtk::ComboBox* combo); void write_plugin_assignment (); diff --git a/libs/surfaces/console1/c1_plugin_control_assignment.cc b/libs/surfaces/console1/c1_plugin_control_assignment.cc new file mode 100644 index 00000000000..268dbcc8bbc --- /dev/null +++ b/libs/surfaces/console1/c1_plugin_control_assignment.cc @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2023 Holger Dehnhardt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "c1_gui.h" + +#include "ardour/debug.h" +#include "console1.h" + +#include "pbd/i18n.h" + +using namespace PBD; +using namespace Gtk; +using namespace std; + + +namespace Console1 +{ + +VBox* +C1GUI::build_plugin_assignment_page () +{ + VBox* plugconfig_packer = manage (new VBox); + HBox* plugselect_packer = manage (new HBox); + + Gtk::Label* l; + l = manage (new Gtk::Label (_ ("Select Plugin"))); + plugselect_packer->pack_start (*l, false, false); + + plugconfig_packer->pack_start (*plugselect_packer, false, false); + + Glib::RefPtr plugin_store_model = ListStore::create (plugin_columns); + TreeModel::Row plugin_combo_row; + for (const auto& pm : c1.getPluginMappingMap ()) { + plugin_combo_row = *(plugin_store_model->append ()); + plugin_combo_row[plugin_columns.plugin_name] = pm.second.name; + plugin_combo_row[plugin_columns.plugin_id] = pm.first; + DEBUG_TRACE (DEBUG::Console1, string_compose ("Add Plugin: name %1 / %2\n", pm.second.name, pm.first)); + } + plugins_combo.pack_start (plugin_columns.plugin_name); + plugins_combo.signal_changed ().connect ( + sigc::bind (sigc::mem_fun (*this, &C1GUI::active_plugin_changed), &plugins_combo)); + plugins_combo.set_model (plugin_store_model); + + plugselect_packer->pack_start (plugins_combo, true, true); + plugin_mapping_scroller.property_shadow_type () = Gtk::SHADOW_NONE; + plugin_mapping_scroller.set_policy (Gtk::PolicyType::POLICY_AUTOMATIC, Gtk::PolicyType::POLICY_AUTOMATIC); + + plugin_mapping_scroller.add (plugin_assignment_editor); + plugconfig_packer->pack_start (plugin_mapping_scroller, true, true, 20); + + build_plugin_assignment_editor (); + + midi_assign_button = manage (new ToggleButton (_ ("assign Control per MIDI"))); + midi_assign_button->set_sensitive (false); + midi_assign_button->set_active (false); + midi_assign_button->signal_toggled ().connect (sigc::bind (sigc::mem_fun (*this, &C1GUI::midi_assign_button_toggled), midi_assign_button)); + plugconfig_packer->pack_start (*midi_assign_button, false, false); + plugin_assignment_changed.connect (sigc::mem_fun (*this, &C1GUI::write_plugin_assignment)); + return plugconfig_packer; +} + +void +C1GUI::build_plugin_assignment_editor () +{ + plugin_assignment_editor.append_column (_ ("Key"), plugin_assignment_editor_columns.index); + plugin_assignment_editor.append_column (_ ("Name"), plugin_assignment_editor_columns.name); + plugin_assignment_editor.append_column (_ ("Switch"), plugin_assignment_editor_columns.is_switch); + + TreeViewColumn* col; + CellRendererCombo* controlRenderer; + + CellRendererToggle* boolRenderer = manage (new CellRendererToggle); + boolRenderer->set_active (); + boolRenderer->property_activatable () = true; + col = manage (new TreeViewColumn (_ ("Shift"), *boolRenderer)); + col->add_attribute (boolRenderer->property_active (), plugin_assignment_editor_columns.shift); + boolRenderer->signal_toggled ().connect (sigc::mem_fun (*this, &C1GUI::toggle_shift)); + plugin_assignment_editor.append_column (*col); + + controlRenderer = make_action_renderer (c1.getPluginControllerModel (), plugin_assignment_editor_columns.controllerName); + col = manage (new TreeViewColumn (_ ("Control"), *controlRenderer)); + col->add_attribute (controlRenderer->property_text (), plugin_assignment_editor_columns.controllerName); + plugin_assignment_editor.append_column (*col); + + plugin_assignment_store = ListStore::create (plugin_assignment_editor_columns); + plugin_assignment_editor.set_model (plugin_assignment_store); +} + +void +C1GUI::active_plugin_changed (Gtk::ComboBox* combo) +{ + DEBUG_TRACE (DEBUG::Console1, "C1GUI active_plugin_changed\n"); + + write_plugin_assignment (); + + plugin_assignment_editor.set_model (Glib::RefPtr ()); + plugin_assignment_store->clear (); + + TreeModel::iterator active = combo->get_active (); + TreeModel::Row plugin_assignment_row; + + string new_plugin_name = (*active)[plugin_columns.plugin_name]; + string new_plugin_id = (*active)[plugin_columns.plugin_id]; + DEBUG_TRACE (DEBUG::Console1, string_compose ("Plugin: selected %1 / %2\n", new_plugin_name, new_plugin_id)); + pc = c1.getPluginMappingMap ()[new_plugin_id]; + + for (auto& parm : pc.parameters) { + plugin_assignment_row = *(plugin_assignment_store->append ()); + plugin_assignment_row[plugin_assignment_editor_columns.index] = parm.first; + plugin_assignment_row[plugin_assignment_editor_columns.name] = parm.second.name; + plugin_assignment_row[plugin_assignment_editor_columns.controllerName] = c1.findControllerNameById (parm.second.controllerId); + plugin_assignment_row[plugin_assignment_editor_columns.is_switch] = parm.second.is_switch; + plugin_assignment_row[plugin_assignment_editor_columns.shift] = parm.second.shift; + + DEBUG_TRACE (DEBUG::Console1, string_compose ("Parameter Name %1 \n", parm.second.name)); + DEBUG_TRACE (DEBUG::Console1, string_compose ("Parameter Index: %1 - index %2 \n", parm.first, parm.second.paramIndex)); + DEBUG_TRACE (DEBUG::Console1, string_compose ("ControllerId: %1 \n", parm.second.controllerId)); + DEBUG_TRACE (DEBUG::Console1, string_compose ("is switch? %1 \n", parm.second.is_switch)); + DEBUG_TRACE (DEBUG::Console1, string_compose ("is shift? %1 \n", parm.second.shift)); + } + plugin_assignment_editor.set_model (plugin_assignment_store); + plugin_assignment_editor.get_selection ()->set_mode (SELECTION_SINGLE); + plugin_assignment_editor.get_selection ()->signal_changed ().connect (sigc::mem_fun (*this, &C1GUI::plugin_assignment_editor_selection_changed)); + midi_assign_button->set_sensitive (false); + midi_assign_button->set_active (false); +} + +CellRendererCombo* +C1GUI::make_action_renderer (Glib::RefPtr model, Gtk::TreeModelColumnBase column) +{ + CellRendererCombo* renderer = manage (new CellRendererCombo); + renderer->property_model () = model; + renderer->property_editable () = true; + renderer->property_text_column () = 0; + renderer->property_has_entry () = false; + renderer->signal_changed ().connect (sigc::mem_fun (*this, &C1GUI::change_controller)); + + return renderer; +} + +void +C1GUI::change_controller (const Glib::ustring& sPath, const TreeModel::iterator& iter) +{ + Gtk::TreePath path (sPath); + Gtk::TreeModel::iterator row = plugin_assignment_store->get_iter (path); + int index = *path.begin (); + if (row) { + string controllerName = (*iter)[c1.plugin_controller_columns.controllerName]; + int controllerId = (*iter)[c1.plugin_controller_columns.controllerId]; + pc.parameters[index].controllerId = Console1::ControllerID (controllerId); + (*row).set_value (plugin_assignment_editor_columns.controllerName, controllerName); + DEBUG_TRACE (DEBUG::Console1, + string_compose ("Column Name: Controller, index %1, name %2 \n", index, controllerName)); + plugin_assignment_changed (); + } +} + +void +C1GUI::plugin_assignment_editor_selection_changed () +{ + if (plugin_assignment_editor.get_selection ()->count_selected_rows () != 1) { + midi_assign_button->set_sensitive (false); + } + midi_assign_button->set_sensitive (true); +} + +void +C1GUI::write_plugin_assignment () +{ + DEBUG_TRACE (DEBUG::Console1, "write_plugin_assignment\n"); + c1.write_plugin_mapping (pc); +} + +void +C1GUI::change_controller_number( int controllerNumber, bool shiftState ){ + DEBUG_TRACE (DEBUG::Console1, string_compose ("C1GUI::change_controller_number: received %1\n", controllerNumber)); + Gtk::TreeModel::iterator row = plugin_assignment_editor.get_selection ()->get_selected (); + + if (row) { + string name = c1.findControllerNameById (Console1::ControllerID(controllerNumber)); + (*row).set_value (plugin_assignment_editor_columns.controllerName, name); + (*row).set_value (plugin_assignment_editor_columns.shift, shiftState); + int index = (*row).get_value (plugin_assignment_editor_columns.index); + pc.parameters[index].controllerId = Console1::ControllerID (controllerNumber); + pc.parameters[index].shift = shiftState ? 1 : 0; + plugin_assignment_changed (); + } + midi_assign_button->set_active (false); + midi_assign_button->set_sensitive (false); +} + +void +C1GUI::midi_assign_button_toggled (Gtk::ToggleButton* b) +{ + DEBUG_TRACE (DEBUG::Console1, "C1GUI::midi_assign_button_changed() \n"); + bool en = b->get_active (); + c1.midi_assign_mode = en; + if( en ) + c1.SendControllerNumber.connect (std::bind ( &C1GUI::change_controller_number, this, _1, _2)); +} + +void +C1GUI::toggle_shift (const Glib::ustring& s) +{ + int index = atoi (s.c_str ()); + Gtk::TreeModel::iterator row = plugin_assignment_store->get_iter (s); + if (row) { + bool value = !pc.parameters[index].shift; + pc.parameters[index].shift = value; + (*row).set_value (plugin_assignment_editor_columns.shift, value); + DEBUG_TRACE (DEBUG::Console1, string_compose ("Column Name: Shift, value %1\n", value)); + plugin_assignment_changed (); + } +} + +} \ No newline at end of file diff --git a/libs/surfaces/console1/c1_plugin_operations.cc b/libs/surfaces/console1/c1_plugin_operations.cc index 83333ad5e27..bfb7ec84498 100644 --- a/libs/surfaces/console1/c1_plugin_operations.cc +++ b/libs/surfaces/console1/c1_plugin_operations.cc @@ -204,7 +204,7 @@ Console1::write_plugin_mapping (PluginMapping &mapping) node.set_property ("NAME", mapping.name); for (const auto& plugin_param : mapping.parameters ) { - DEBUG_TRACE (DEBUG::Console1, string_compose ("write_plugin_mapping: Plugin parameter %1: %2\n",plugin_param.first ,plugin_param.second.name)); + DEBUG_TRACE (DEBUG::Console1, string_compose ("write_plugin_mapping: Plugin parameter %1: %2 - shift: %3\n", plugin_param.first, plugin_param.second.name, plugin_param.second.shift)); XMLNode param = XMLNode ("param-mapping"); param.set_property ("id", plugin_param.second.paramIndex); XMLNode name = XMLNode ("name"); diff --git a/libs/surfaces/console1/console1.cc b/libs/surfaces/console1/console1.cc index 023a65027da..974391a3be9 100644 --- a/libs/surfaces/console1/console1.cc +++ b/libs/surfaces/console1/console1.cc @@ -439,11 +439,17 @@ Console1::handle_midi_controller_message (MIDI::Parser&, MIDI::EventTwoBytes* tb { uint32_t controller_number = static_cast (tb->controller_number); uint32_t value = static_cast (tb->value); - DEBUG_TRACE (DEBUG::Console1, + + DEBUG_TRACE (DEBUG::Console1, string_compose ("handle_midi_controller_message cn: '%1' val: '%2'\n", controller_number, value)); DEBUG_TRACE (DEBUG::Console1, string_compose ("handle_midi_controller_message shift state: '%1' plugin state: '%2'\n", shift_state, in_plugin_state)); + if (midi_assign_mode && (controller_number != ControllerID::PRESET)) { + SendControllerNumber (controller_number, shift_state); + return; + } + try { Controller* controller = controllerMap[ControllerID (controller_number)]; if (controller ) { diff --git a/libs/surfaces/console1/console1.h b/libs/surfaces/console1/console1.h index c7bb5626c80..66884248b22 100644 --- a/libs/surfaces/console1/console1.h +++ b/libs/surfaces/console1/console1.h @@ -23,6 +23,8 @@ #include #include +#include + #include #include @@ -128,6 +130,8 @@ class Console1 : public MIDISurface bool create_mapping_stubs; bool switch_eq_q_dials = true; + bool midi_assign_mode = false; + bool in_use(){ return _in_use; } @@ -135,90 +139,91 @@ class Console1 : public MIDISurface PBD::Signal ConnectionChange; /* Timer Events */ - PBD::Signal BlinkIt; - PBD::Signal Periodic; - - /* Local Signals */ - PBD::Signal BankChange; - PBD::Signal ShiftChange; - PBD::Signal PluginStateChange; - PBD::Signal EQBandQBindingChange; - - enum ControllerID { - CONTROLLER_NONE = 0, - VOLUME = 7, - PAN = 10, - MUTE = 12, - SOLO = 13, - ORDER = 14, - DRIVE = 15, - EXTERNAL_SIDECHAIN = 17, - CHARACTER = 18, - FOCUS1 = 21, - FOCUS2, - FOCUS3, - FOCUS4, - FOCUS5, - FOCUS6, - FOCUS7, - FOCUS8, - FOCUS9, - FOCUS10, - FOCUS11, - FOCUS12, - FOCUS13, - FOCUS14, - FOCUS15, - FOCUS16, - FOCUS17, - FOCUS18, - FOCUS19, - FOCUS20 = 40, - COMP = 46, - COMP_THRESH = 47, - COMP_RELEASE = 48, - COMP_RATIO = 49, - COMP_PAR = 50, - COMP_ATTACK = 51, - SHAPE = 53, - SHAPE_GATE = 54, - SHAPE_SUSTAIN = 55, - SHAPE_RELEASE = 56, - SHAPE_PUNCH = 57, - PRESET = 58, - HARD_GATE = 59, - FILTER_TO_COMPRESSORS = 61, - HIGH_SHAPE = 65, - EQ = 80, - HIGH_GAIN = 82, - HIGH_FREQ = 83, - HIGH_MID_GAIN = 85, - HIGH_MID_FREQ = 86, - HIGH_MID_SHAPE = 87, - LOW_MID_GAIN = 88, - LOW_MID_FREQ = 89, - LOW_MID_SHAPE = 90, - LOW_GAIN = 91, - LOW_FREQ = 92, - LOW_SHAPE = 93, - PAGE_UP = 96, - PAGE_DOWN = 97, - DISPLAY_ON = 102, - LOW_CUT = 103, - MODE = 104, - HIGH_CUT = 105, - GAIN = 107, - PHASE_INV = 108, - INPUT_METER_L = 110, - INPUT_METER_R = 111, - OUTPUT_METER_L = 112, - OUTPUT_METER_R = 113, - SHAPE_METER = 114, - COMP_METER = 115, - TRACK_COPY = 120, - TRACK_GROUP = 123, + PBD::Signal BlinkIt; + PBD::Signal Periodic; + + /* Local Signals */ + PBD::Signal BankChange; + PBD::Signal ShiftChange; + PBD::Signal PluginStateChange; + PBD::Signal EQBandQBindingChange; + sigc::signal2 SendControllerNumber; + + enum ControllerID { + CONTROLLER_NONE = 0, + VOLUME = 7, + PAN = 10, + MUTE = 12, + SOLO = 13, + ORDER = 14, + DRIVE = 15, + EXTERNAL_SIDECHAIN = 17, + CHARACTER = 18, + FOCUS1 = 21, + FOCUS2, + FOCUS3, + FOCUS4, + FOCUS5, + FOCUS6, + FOCUS7, + FOCUS8, + FOCUS9, + FOCUS10, + FOCUS11, + FOCUS12, + FOCUS13, + FOCUS14, + FOCUS15, + FOCUS16, + FOCUS17, + FOCUS18, + FOCUS19, + FOCUS20 = 40, + COMP = 46, + COMP_THRESH = 47, + COMP_RELEASE = 48, + COMP_RATIO = 49, + COMP_PAR = 50, + COMP_ATTACK = 51, + SHAPE = 53, + SHAPE_GATE = 54, + SHAPE_SUSTAIN = 55, + SHAPE_RELEASE = 56, + SHAPE_PUNCH = 57, + PRESET = 58, + HARD_GATE = 59, + FILTER_TO_COMPRESSORS = 61, + HIGH_SHAPE = 65, + EQ = 80, + HIGH_GAIN = 82, + HIGH_FREQ = 83, + HIGH_MID_GAIN = 85, + HIGH_MID_FREQ = 86, + HIGH_MID_SHAPE = 87, + LOW_MID_GAIN = 88, + LOW_MID_FREQ = 89, + LOW_MID_SHAPE = 90, + LOW_GAIN = 91, + LOW_FREQ = 92, + LOW_SHAPE = 93, + PAGE_UP = 96, + PAGE_DOWN = 97, + DISPLAY_ON = 102, + LOW_CUT = 103, + MODE = 104, + HIGH_CUT = 105, + GAIN = 107, + PHASE_INV = 108, + INPUT_METER_L = 110, + INPUT_METER_R = 111, + OUTPUT_METER_L = 112, + OUTPUT_METER_R = 113, + SHAPE_METER = 114, + COMP_METER = 115, + TRACK_COPY = 120, + TRACK_GROUP = 123, - }; + }; enum EQ_MODE { EQM_UNDEFINED = -1, diff --git a/libs/surfaces/console1/wscript b/libs/surfaces/console1/wscript index ac26bf386f2..b9af2156ca7 100644 --- a/libs/surfaces/console1/wscript +++ b/libs/surfaces/console1/wscript @@ -15,6 +15,7 @@ def build(bld): console1.cc c1_operations.cc c1_plugin_operations.cc + c1_plugin_control_assignment.cc c1_gui.cc ''' obj.defines = [ 'PACKAGE="ardour_console1"' ] From eec3195138415c7eb3434881f42da76432e9eac7 Mon Sep 17 00:00:00 2001 From: Hoger Dehnhardt Date: Thu, 7 Aug 2025 22:23:03 +0200 Subject: [PATCH 7/7] Finalized Plugin Operations --- libs/surfaces/console1/c1_gui.cc | 30 +- libs/surfaces/console1/c1_gui.h | 10 +- libs/surfaces/console1/c1_operations.cc | 5 +- .../console1/c1_plugin_control_assignment.cc | 85 ++--- .../surfaces/console1/c1_plugin_operations.cc | 317 +++++++++++------- libs/surfaces/console1/console1.cc | 8 + libs/surfaces/console1/console1.h | 50 +-- 7 files changed, 300 insertions(+), 205 deletions(-) diff --git a/libs/surfaces/console1/c1_gui.cc b/libs/surfaces/console1/c1_gui.cc index 2b7810b2447..61d85f0198f 100644 --- a/libs/surfaces/console1/c1_gui.cc +++ b/libs/surfaces/console1/c1_gui.cc @@ -117,19 +117,18 @@ C1GUI::C1GUI (Console1& p) // swap_solo_mute (_ ("Swap Solo and Mute")); swap_solo_mute_cb.set_tooltip_text ( - _ ("If checked Ardour the mute and solo buttons are swept so they have the same order as in the GUI.")); + _("If checked Ardour the mute and solo buttons are swept so they have the same order as in the GUI.")); swap_solo_mute_cb.set_active (p.swap_solo_mute); swap_solo_mute_cb.signal_toggled ().connect (sigc::mem_fun (*this, &C1GUI::set_swap_solo_mute)); #ifdef MIXBUS - // before the ssl strips, the q knobs for low- and high mids where alwas used as sends, now this can be toggled - band_q_as_send_cb.set_tooltip_text ( - _ ("If checked Ardour the Q-Factor knobs for Low and High are used as sends for Send 11 and send 12.")); + // before the ssl strips, the q knobs for low- and high mids where always used as sends, now this can be toggled + band_q_as_send_cb.set_tooltip_text ( + _("If checked Ardour the Q-Factor knobs for Low and High are used as sends for Send 11 and send 12.")); band_q_as_send_cb.set_active (p.band_q_as_send); band_q_as_send_cb.signal_toggled ().connect (sigc::mem_fun (*this, &C1GUI::set_band_q_as_send)); #endif - // create_plugin_stubs (_ ("Create Plugin Mapping Stubs")); - create_plugin_stubs_btn.set_tooltip_text (_ ("If checked a mapping stub is created for every unknown plugin.")); + create_plugin_stubs_btn.set_tooltip_text (_("If checked a mapping stub is created for every unknown plugin.")); create_plugin_stubs_btn.set_active (p.create_mapping_stubs); create_plugin_stubs_btn.signal_toggled ().connect (sigc::mem_fun (*this, &C1GUI::set_create_mapping_stubs)); @@ -141,14 +140,14 @@ C1GUI::C1GUI (Console1& p) row++; l = manage (new Gtk::Label); - l->set_markup (string_compose ("%1", _ ("Outgoing MIDI on:"))); + l->set_markup (string_compose ("%1", _("Outgoing MIDI on:"))); l->set_alignment (1.0, 0.5); table.attach (*l, 0, 1, row, row + 1, AttachOptions (FILL | EXPAND), AttachOptions (0)); table.attach (output_combo, 1, 2, row, row + 1, AttachOptions (FILL | EXPAND), AttachOptions (0), 0, 0); row++; l = manage (new Gtk::Label); - l->set_markup (string_compose ("%1", _ ("Swap Solo and Mute:"))); + l->set_markup (string_compose ("%1", _("Swap Solo and Mute:"))); l->set_alignment (1.0, 0.5); table.attach (*l, 0, 1, row, row + 1, AttachOptions (FILL | EXPAND), AttachOptions (0)); table.attach (swap_solo_mute_cb, 1, 2, row, row + 1); @@ -156,7 +155,7 @@ C1GUI::C1GUI (Console1& p) #ifdef MIXBUS l = manage (new Gtk::Label); - l->set_markup (string_compose ("%1", _ ("Use Mid-Q Buttons as send 11/12:"))); + l->set_markup (string_compose ("%1", _("Use Mid-Q Buttons as send 11/12:"))); l->set_alignment (1.0, 0.5); table.attach (*l, 0, 1, row, row + 1, AttachOptions (FILL | EXPAND), AttachOptions (0)); table.attach (band_q_as_send_cb, 1, 2, row, row + 1); @@ -164,7 +163,7 @@ C1GUI::C1GUI (Console1& p) #endif l = manage (new Gtk::Label); - l->set_markup (string_compose ("%1", _ ("Create Plugin Mapping Stubs:"))); + l->set_markup (string_compose ("%1", _("Create Plugin Mapping Stubs:"))); l->set_alignment (1.0, 0.5); table.attach (*l, 0, 1, row, row + 1, AttachOptions (FILL | EXPAND), AttachOptions (0)); table.attach (create_plugin_stubs_btn, 1, 2, row, row + 1); @@ -179,7 +178,7 @@ C1GUI::C1GUI (Console1& p) VBox* plugconfig_packer = build_plugin_assignment_page(); - append_page (*plugconfig_packer, _ ("Plugin Mappings")); + append_page (*plugconfig_packer, _("Plugin Mappings")); plugconfig_packer->show_all (); /* update the port connection combos */ @@ -189,11 +188,14 @@ C1GUI::C1GUI (Console1& p) /* catch future changes to connection state */ ARDOUR::AudioEngine::instance ()->PortRegisteredOrUnregistered.connect ( - _port_connections, invalidator (*this), std::bind (&C1GUI::connection_handler, this), gui_context ()); + port_connections, invalidator (*this), std::bind (&C1GUI::connection_handler, this), gui_context ()); ARDOUR::AudioEngine::instance ()->PortPrettyNameChanged.connect ( - _port_connections, invalidator (*this), std::bind (&C1GUI::connection_handler, this), gui_context ()); + port_connections, invalidator (*this), std::bind (&C1GUI::connection_handler, this), gui_context ()); c1.ConnectionChange.connect ( - _port_connections, invalidator (*this), std::bind (&C1GUI::connection_handler, this), gui_context ()); + port_connections, invalidator (*this), std::bind (&C1GUI::connection_handler, this), gui_context ()); + + c1.PluginStubAdded.connect ( + plugin_connections, invalidator (*this), std::bind (&C1GUI::load_plugin_combo_rows, this), gui_context ()); } C1GUI::~C1GUI () { diff --git a/libs/surfaces/console1/c1_gui.h b/libs/surfaces/console1/c1_gui.h index 47ad79f0935..9b1eb182397 100644 --- a/libs/surfaces/console1/c1_gui.h +++ b/libs/surfaces/console1/c1_gui.h @@ -54,7 +54,7 @@ class C1GUI : public Gtk::Notebook ~C1GUI (); private: - Console1& c1; + Console1& c1; PBD::ScopedConnectionList lcxl_connections; Gtk::VBox hpacker; Gtk::Table table; @@ -77,8 +77,9 @@ class C1GUI : public Gtk::Notebook void update_port_combos (); PBD::ScopedConnection connection_change_connection; void connection_handler (); - PBD::ScopedConnectionList _port_connections; - + PBD::ScopedConnectionList port_connections; + PBD::ScopedConnectionList plugin_connections; + struct MidiPortColumns : public Gtk::TreeModel::ColumnRecord { MidiPortColumns() { add (short_name); @@ -122,9 +123,10 @@ class C1GUI : public Gtk::Notebook Glib::RefPtr build_midi_port_list (std::vector const & ports, bool for_input); - Console1::PluginMapping pc; + Console1::PluginMapping plugin_mapping; Gtk::VBox* build_plugin_assignment_page (); Gtk::CellRendererCombo* make_action_renderer (Glib::RefPtr model, Gtk::TreeModelColumnBase column); + void load_plugin_combo_rows (); void build_plugin_assignment_editor (); void plugin_assignment_editor_selection_changed (); void change_controller_number (int controllerNumber, bool shiftState); diff --git a/libs/surfaces/console1/c1_operations.cc b/libs/surfaces/console1/c1_operations.cc index 4c95eae1b74..08e0e1d4540 100644 --- a/libs/surfaces/console1/c1_operations.cc +++ b/libs/surfaces/console1/c1_operations.cc @@ -680,7 +680,10 @@ Console1::map_shift (bool shift) try { ControllerButton* controllerButton = get_button (PRESET); controllerButton->set_led_state (shift); - map_stripable_state (); + if( in_plugin_state ) + remap_plugin_parameter (current_plugin_index); + else + map_stripable_state (); } catch (ControlNotFoundException const&) { DEBUG_TRACE (DEBUG::Console1, "Button not found\n"); } diff --git a/libs/surfaces/console1/c1_plugin_control_assignment.cc b/libs/surfaces/console1/c1_plugin_control_assignment.cc index 268dbcc8bbc..8e3eb7cc712 100644 --- a/libs/surfaces/console1/c1_plugin_control_assignment.cc +++ b/libs/surfaces/console1/c1_plugin_control_assignment.cc @@ -43,19 +43,7 @@ C1GUI::build_plugin_assignment_page () plugconfig_packer->pack_start (*plugselect_packer, false, false); - Glib::RefPtr plugin_store_model = ListStore::create (plugin_columns); - TreeModel::Row plugin_combo_row; - for (const auto& pm : c1.getPluginMappingMap ()) { - plugin_combo_row = *(plugin_store_model->append ()); - plugin_combo_row[plugin_columns.plugin_name] = pm.second.name; - plugin_combo_row[plugin_columns.plugin_id] = pm.first; - DEBUG_TRACE (DEBUG::Console1, string_compose ("Add Plugin: name %1 / %2\n", pm.second.name, pm.first)); - } - plugins_combo.pack_start (plugin_columns.plugin_name); - plugins_combo.signal_changed ().connect ( - sigc::bind (sigc::mem_fun (*this, &C1GUI::active_plugin_changed), &plugins_combo)); - plugins_combo.set_model (plugin_store_model); - + load_plugin_combo_rows (); plugselect_packer->pack_start (plugins_combo, true, true); plugin_mapping_scroller.property_shadow_type () = Gtk::SHADOW_NONE; plugin_mapping_scroller.set_policy (Gtk::PolicyType::POLICY_AUTOMATIC, Gtk::PolicyType::POLICY_AUTOMATIC); @@ -74,6 +62,23 @@ C1GUI::build_plugin_assignment_page () return plugconfig_packer; } +void C1GUI::load_plugin_combo_rows() +{ + Glib::RefPtr plugin_store_model = ListStore::create (plugin_columns); + TreeModel::Row plugin_combo_row; + + for (const auto& pm : c1.plugin_mapping_map) { + plugin_combo_row = *(plugin_store_model->append ()); + plugin_combo_row[plugin_columns.plugin_name] = pm.second.name; + plugin_combo_row[plugin_columns.plugin_id] = pm.first; + DEBUG_TRACE (DEBUG::Console1, string_compose ("Add Plugin: name %1 / %2\n", pm.second.name, pm.first)); + } + plugins_combo.pack_start (plugin_columns.plugin_name); + plugins_combo.signal_changed ().connect ( + sigc::bind (sigc::mem_fun (*this, &C1GUI::active_plugin_changed), &plugins_combo)); + plugins_combo.set_model (plugin_store_model); +} + void C1GUI::build_plugin_assignment_editor () { @@ -82,23 +87,23 @@ C1GUI::build_plugin_assignment_editor () plugin_assignment_editor.append_column (_ ("Switch"), plugin_assignment_editor_columns.is_switch); TreeViewColumn* col; - CellRendererCombo* controlRenderer; - - CellRendererToggle* boolRenderer = manage (new CellRendererToggle); - boolRenderer->set_active (); - boolRenderer->property_activatable () = true; - col = manage (new TreeViewColumn (_ ("Shift"), *boolRenderer)); - col->add_attribute (boolRenderer->property_active (), plugin_assignment_editor_columns.shift); - boolRenderer->signal_toggled ().connect (sigc::mem_fun (*this, &C1GUI::toggle_shift)); - plugin_assignment_editor.append_column (*col); - - controlRenderer = make_action_renderer (c1.getPluginControllerModel (), plugin_assignment_editor_columns.controllerName); - col = manage (new TreeViewColumn (_ ("Control"), *controlRenderer)); - col->add_attribute (controlRenderer->property_text (), plugin_assignment_editor_columns.controllerName); - plugin_assignment_editor.append_column (*col); - - plugin_assignment_store = ListStore::create (plugin_assignment_editor_columns); - plugin_assignment_editor.set_model (plugin_assignment_store); + CellRendererCombo* controlRenderer; + + CellRendererToggle* boolRendererShift = manage (new CellRendererToggle); + boolRendererShift->set_active (); + boolRendererShift->property_activatable () = true; + col = manage (new TreeViewColumn (_ ("Shift"), *boolRendererShift)); + col->add_attribute (boolRendererShift->property_active (), plugin_assignment_editor_columns.shift); + boolRendererShift->signal_toggled ().connect (sigc::mem_fun (*this, &C1GUI::toggle_shift)); + plugin_assignment_editor.append_column (*col); + + controlRenderer = make_action_renderer (c1.getPluginControllerModel (), plugin_assignment_editor_columns.controllerName); + col = manage (new TreeViewColumn (_ ("Control"), *controlRenderer)); + col->add_attribute (controlRenderer->property_text (), plugin_assignment_editor_columns.controllerName); + plugin_assignment_editor.append_column (*col); + + plugin_assignment_store = ListStore::create (plugin_assignment_editor_columns); + plugin_assignment_editor.set_model (plugin_assignment_store); } void @@ -117,9 +122,9 @@ C1GUI::active_plugin_changed (Gtk::ComboBox* combo) string new_plugin_name = (*active)[plugin_columns.plugin_name]; string new_plugin_id = (*active)[plugin_columns.plugin_id]; DEBUG_TRACE (DEBUG::Console1, string_compose ("Plugin: selected %1 / %2\n", new_plugin_name, new_plugin_id)); - pc = c1.getPluginMappingMap ()[new_plugin_id]; + plugin_mapping = c1.plugin_mapping_map[new_plugin_id]; - for (auto& parm : pc.parameters) { + for (auto& parm : plugin_mapping.parameters) { plugin_assignment_row = *(plugin_assignment_store->append ()); plugin_assignment_row[plugin_assignment_editor_columns.index] = parm.first; plugin_assignment_row[plugin_assignment_editor_columns.name] = parm.second.name; @@ -162,7 +167,7 @@ C1GUI::change_controller (const Glib::ustring& sPath, const TreeModel::iterator& if (row) { string controllerName = (*iter)[c1.plugin_controller_columns.controllerName]; int controllerId = (*iter)[c1.plugin_controller_columns.controllerId]; - pc.parameters[index].controllerId = Console1::ControllerID (controllerId); + plugin_mapping.parameters[index].controllerId = Console1::ControllerID (controllerId); (*row).set_value (plugin_assignment_editor_columns.controllerName, controllerName); DEBUG_TRACE (DEBUG::Console1, string_compose ("Column Name: Controller, index %1, name %2 \n", index, controllerName)); @@ -183,7 +188,8 @@ void C1GUI::write_plugin_assignment () { DEBUG_TRACE (DEBUG::Console1, "write_plugin_assignment\n"); - c1.write_plugin_mapping (pc); + c1.plugin_mapping_map[plugin_mapping.id] = plugin_mapping; + c1.write_plugin_mapping (plugin_mapping); } void @@ -196,12 +202,11 @@ C1GUI::change_controller_number( int controllerNumber, bool shiftState ){ (*row).set_value (plugin_assignment_editor_columns.controllerName, name); (*row).set_value (plugin_assignment_editor_columns.shift, shiftState); int index = (*row).get_value (plugin_assignment_editor_columns.index); - pc.parameters[index].controllerId = Console1::ControllerID (controllerNumber); - pc.parameters[index].shift = shiftState ? 1 : 0; + plugin_mapping.parameters[index].controllerId = Console1::ControllerID (controllerNumber); + plugin_mapping.parameters[index].shift = shiftState ? 1 : 0; plugin_assignment_changed (); } midi_assign_button->set_active (false); - midi_assign_button->set_sensitive (false); } void @@ -211,7 +216,9 @@ C1GUI::midi_assign_button_toggled (Gtk::ToggleButton* b) bool en = b->get_active (); c1.midi_assign_mode = en; if( en ) + { c1.SendControllerNumber.connect (std::bind ( &C1GUI::change_controller_number, this, _1, _2)); + } } void @@ -220,8 +227,8 @@ C1GUI::toggle_shift (const Glib::ustring& s) int index = atoi (s.c_str ()); Gtk::TreeModel::iterator row = plugin_assignment_store->get_iter (s); if (row) { - bool value = !pc.parameters[index].shift; - pc.parameters[index].shift = value; + bool value = !plugin_mapping.parameters[index].shift; + plugin_mapping.parameters[index].shift = value; (*row).set_value (plugin_assignment_editor_columns.shift, value); DEBUG_TRACE (DEBUG::Console1, string_compose ("Column Name: Shift, value %1\n", value)); plugin_assignment_changed (); diff --git a/libs/surfaces/console1/c1_plugin_operations.cc b/libs/surfaces/console1/c1_plugin_operations.cc index bfb7ec84498..f4d67d41f3e 100644 --- a/libs/surfaces/console1/c1_plugin_operations.cc +++ b/libs/surfaces/console1/c1_plugin_operations.cc @@ -58,7 +58,7 @@ uint32_t Console1::load_mappings () { if( mappings_loaded ) - return pluginMappingMap.size (); + return plugin_mapping_map.size (); uint32_t i = 0; if (!ensure_config_dir ()) @@ -92,7 +92,7 @@ Console1::load_mappings () ++i; } DEBUG_TRACE (DEBUG::Console1, string_compose ("Console1::load_mappings - found %1 mapping files\n", i)); - DEBUG_TRACE (DEBUG::Console1, string_compose ("Console1::load_mappings - loaded %1 mapping files\n", pluginMappingMap.size())); + DEBUG_TRACE (DEBUG::Console1, string_compose ("Console1::load_mappings - loaded %1 mapping files\n", plugin_mapping_map.size())); g_dir_close (gdir); mappings_loaded = true; return i; @@ -130,11 +130,11 @@ Console1::load_mapping (XMLNode* mapping_xml) } else if ((*j)->name () == "mapping") { param_mapping = (*j)->child_content (); (*j)->get_property ("shift", parmap.shift); + (*j)->get_property ("is_switch", parmap.is_switch); } } parmap.paramIndex = index; parmap.name = param_name; - parmap.is_switch = (param_type == "switch"); if (!param_mapping.empty ()) { ControllerNameIdMap::const_iterator m = controllerNameIdMap.find (param_mapping); if (m != controllerNameIdMap.end ()) @@ -148,7 +148,7 @@ Console1::load_mapping (XMLNode* mapping_xml) } pm.parameters[index] = std::move (parmap); } - pluginMappingMap[pm.id] = pm; + plugin_mapping_map[pm.id] = pm; return true; } @@ -158,28 +158,33 @@ Console1::create_plugin_mapping_stubs (const std::shared_ptr proc, co DEBUG_TRACE (DEBUG::Console1, "create_plugin_mapping_stubs \n"); XMLTree* tree = new XMLTree (); XMLNode node = XMLNode ("c1plugin-mapping"); - node.set_property ("ID", plugin->unique_id ()); - node.set_property ("NAME", plugin->name ()); - int32_t n_controls = -1; + if( plugin->unique_id() == "" ) + return; + node.set_property ("ID", plugin->unique_id ()); + node.set_property ("NAME", plugin->name ()); + int32_t n_controls = -1; - set p = proc->what_can_be_automated (); - for (set::iterator j = p.begin (); j != p.end (); ++j) { - ++n_controls; - std::string n = proc->describe_parameter (*j); - DEBUG_TRACE (DEBUG::Console1, string_compose ("create_plugin_mapping_stubs: Plugin parameter %1: %2\n", n_controls, n)); - if (n == "hidden") { - continue; - } - XMLNode param = XMLNode ("param-mapping"); - param.set_property ("id", n_controls); - XMLNode name = XMLNode ("name"); - XMLNode c = XMLNode ("c", plugin->parameter_label (n_controls).c_str ()); - name.add_child_copy (c); - XMLNode mapping = XMLNode ("mapping"); - mapping.set_property ("shift", "false"); - param.add_child_copy (name); - param.add_child_copy (mapping); - node.add_child_copy (param); + set p = proc->what_can_be_automated (); + for (set::iterator j = p.begin (); j != p.end (); ++j) { + ++n_controls; + std::string n = proc->describe_parameter (*j); + DEBUG_TRACE (DEBUG::Console1, string_compose ("create_plugin_mapping_stubs: Plugin parameter %1: %2\n", n_controls, n)); + if (n == "hidden") { + continue; + } + ParameterDescriptor parameterDescriptor; + plugin->get_parameter_descriptor (n_controls, parameterDescriptor); + XMLNode param = XMLNode ("param-mapping"); + param.set_property ("id", n_controls); + XMLNode name = XMLNode ("name"); + XMLNode c = XMLNode ("c", plugin->parameter_label (n_controls).c_str ()); + name.add_child_copy (c); + XMLNode mapping = XMLNode ("mapping"); + mapping.set_property ("shift", "false"); + mapping.set_property ("is_switch", parameterDescriptor.toggled ? 1 : 0); + param.add_child_copy (name); + param.add_child_copy (mapping); + node.add_child_copy (param); } tree->set_root (&node); @@ -192,6 +197,8 @@ Console1::create_plugin_mapping_stubs (const std::shared_ptr proc, co tree->set_filename (filename); tree->write (); + load_mapping (&node); + PluginStubAdded (); } void @@ -212,7 +219,8 @@ Console1::write_plugin_mapping (PluginMapping &mapping) name.add_child_copy (c); XMLNode mapping = XMLNode ("mapping"); mapping.set_property ("shift", plugin_param.second.shift); - XMLNode controller = XMLNode ("c", findControllerNameById(plugin_param.second.controllerId) ); + mapping.set_property ("is_switch", plugin_param.second.is_switch); + XMLNode controller = XMLNode ("c", findControllerNameById (plugin_param.second.controllerId)); mapping.add_child_copy (controller); param.add_child_copy (name); param.add_child_copy (mapping); @@ -236,6 +244,7 @@ bool Console1::select_plugin (const int32_t plugin_index) { DEBUG_TRACE (DEBUG::Console1, "Console1::select_plugin\n"); + midi_assign_mode = false; if (current_plugin_index == plugin_index) { std::shared_ptr r = std::dynamic_pointer_cast (_current_stripable); if (!r) { @@ -297,7 +306,7 @@ Console1::remove_plugin_operations () c.second->set_plugin_action (0); c.second->set_plugin_shift_action (0); c.second->clear_value (); - if( c.second->get_type() == ControllerType::CONTROLLER_BUTTON ) + if( c.second->get_type() == ControllerType::CONTROLLER_BUTTON && c.first != ControllerID::PRESET ) { ControllerButton* b = dynamic_cast (c.second); b->set_led_state (false); @@ -320,7 +329,6 @@ Console1::find_plugin (const int32_t plugin_index) if (!r) { return proc; } - remove_plugin_operations (); while ((ext_plugin_index < plugin_index) && (int_plugin_index < (int)bank_size)) { ++int_plugin_index; @@ -376,101 +384,170 @@ Console1::setup_plugin_mute_button(const std::shared_ptr& plugin_i } bool -Console1::setup_plugin_encoder(const PluginParameterMapping& ppm, int32_t n_controls, - const ParameterDescriptor& parameterDescriptor, - const std::shared_ptr& c) +Console1::setup_plugin_controller (const PluginParameterMapping& ppm, int32_t n_controls, + const ParameterDescriptor& parameterDescriptor, + const std::shared_ptr& ac) { - try { - Encoder* e = get_encoder (ppm.controllerId); - std::function plugin_mapping = - [=](bool b, PBD::Controllable::GroupControlDisposition d) -> void { - double origin = c->get_value(); - double v = parameterDescriptor.to_interface(origin, true); - e->set_value (v * 127); - DEBUG_TRACE ( - DEBUG::Console1, - string_compose ("to: <-Encoder Plugin parameter %1: origin %2 translated %3 - %4\n", n_controls, origin, v , v * 127)); - }; - if( !ppm.shift ) - e->set_plugin_action ([=] (uint32_t val) { - double v = val / 127.f; - double translated = parameterDescriptor.from_interface(v, true); - c->set_value( translated, - PBD::Controllable::GroupControlDisposition::UseGroup); - DEBUG_TRACE ( - DEBUG::Console1, - string_compose ("from: ->Encoder Plugin parameter %1: origin %2 calculated %3 translated %4\n", n_controls, val, v, translated )); - }); - else - e->set_plugin_shift_action ([=] (uint32_t val) { - double v = val / 127.f; - double translated = parameterDescriptor.from_interface(v, true); - c->set_value( translated, - PBD::Controllable::GroupControlDisposition::UseGroup); - DEBUG_TRACE ( - DEBUG::Console1, - string_compose ("from: ->Encoder Plugin shift-parameter %1: origin %2 calculated %3 translated %4\n", n_controls, val, v, translated )); - }); - c->Changed.connect ( - plugin_connections, MISSING_INVALIDATOR, std::bind (plugin_mapping, _1, _2), this); - c->Changed (true, PBD::Controllable::GroupControlDisposition::UseGroup); - return true; - } catch (ControlNotFoundException const&) { - DEBUG_TRACE (DEBUG::Console1, string_compose ("No Encoder found %1\n", n_controls)); - return false; - } + DEBUG_TRACE (DEBUG::Console1, "Console1::setup_plugin_controller"); + try { + Controller* controller = get_controller (ppm.controllerId); + if (!ppm.shift) + controller->set_plugin_action ([=] (uint32_t val) { + double v = val / 127.f; + double translated = parameterDescriptor.from_interface (v, true); + ac->set_value (translated, + PBD::Controllable::GroupControlDisposition::UseGroup); + DEBUG_TRACE ( + DEBUG::Console1, + string_compose ("from: ->Encoder Plugin parameter %1: origin %2 calculated %3 translated %4\n", n_controls, val, v, translated)); + }); + else + controller->set_plugin_shift_action ([=] (uint32_t val) { + double v = val / 127.f; + double translated = parameterDescriptor.from_interface (v, true); + ac->set_value (translated, + PBD::Controllable::GroupControlDisposition::UseGroup); + DEBUG_TRACE ( + DEBUG::Console1, + string_compose ("from: ->Encoder Plugin shift-parameter %1: origin %2 calculated %3 translated %4\n", n_controls, val, v, translated)); + }); + return set_plugin_receive_connection (controller, ac, parameterDescriptor, ppm); + } catch (ControlNotFoundException const&) { + DEBUG_TRACE (DEBUG::Console1, string_compose ("No Encoder found %1\n", n_controls)); + return false; + } } bool -Console1::setup_plugin_button(const PluginParameterMapping& ppm, int32_t n_controls, - const ParameterDescriptor& parameterDescriptor, - const std::shared_ptr& c) +Console1::set_plugin_receive_connection (Controller* controller, const std::shared_ptr& ac, const ParameterDescriptor& parameterDescriptor, const PluginParameterMapping& ppm) { - try { - ControllerButton* cb = get_button (ppm.controllerId); - std::function plugin_mapping = - [=] (bool b, PBD::Controllable::GroupControlDisposition d) -> void { - cb->set_led_state (c->get_value ()); - DEBUG_TRACE (DEBUG::Console1, - string_compose ("<-ControllerButton Plugin parameter %1: %2 \n", - n_controls, - c->get_value ())); - }; - cb->set_plugin_action ([=] (uint32_t val) { - double v = val / 127.f; - c->set_value (parameterDescriptor.from_interface (v, true), - PBD::Controllable::GroupControlDisposition::UseGroup); - DEBUG_TRACE ( - DEBUG::Console1, - string_compose ("->ControllerButton Plugin parameter %1: %2 - %3\n", n_controls, val, v)); - }); + DEBUG_TRACE (DEBUG::Console1, "Console1::set_plugin_receive_connection \n"); + + if (ppm.shift != shift_state) + return false; + + std::function plugin_mapping; + + switch (controller->get_type ()) { + case ControllerType::ENCODER: { + Encoder* e = dynamic_cast (controller); + if (e) { + DEBUG_TRACE (DEBUG::Console1, "Console1::set_plugin_receive_connection ENCODER\n"); + + plugin_mapping = + [=] (bool b, PBD::Controllable::GroupControlDisposition d) -> void { + double origin = ac->get_value (); + double v = parameterDescriptor.to_interface (origin, true); + e->set_value (v * 127); + DEBUG_TRACE ( + DEBUG::Console1, + string_compose ("to: <-Encoder Plugin parameter %1: origin %2 translated %3 - %4\n", ppm.paramIndex, origin, v, v * 127)); + }; + DEBUG_TRACE (DEBUG::Console1, string_compose ("ENCODER has plugin_action %1, has shitft_plugin_action %2\n", e->get_plugin_action () ? "Yes" : "No", e->get_plugin_shift_action () ? "Yes" : "No")); + } + }; + break; + case ControllerType::CONTROLLER_BUTTON: { + ControllerButton* button = dynamic_cast (controller); + if (button) { + DEBUG_TRACE (DEBUG::Console1, "Console1::set_plugin_receive_connection CONTROLLER_BUTTON \n"); + + plugin_mapping = [=] (bool b, PBD::Controllable::GroupControlDisposition d) -> void { + button->set_led_state (ac->get_value ()); + DEBUG_TRACE (DEBUG::Console1, + string_compose ("<-ControllerButton Plugin parameter %1: %2 \n", + ppm.paramIndex, + ac->get_value ())); + }; + } + }; + break; + default: + return false; + break; + } - c->Changed.connect ( - plugin_connections, MISSING_INVALIDATOR, std::bind (plugin_mapping, _1, _2), this); - c->Changed (true, PBD::Controllable::GroupControlDisposition::UseGroup); - return true; - } catch (ControlNotFoundException const&) { - DEBUG_TRACE (DEBUG::Console1, string_compose ("No ControllerButton found %1\n", n_controls)); - return false; - } + ac->Changed.connect ( + plugin_connections, MISSING_INVALIDATOR, std::bind (plugin_mapping, _1, _2), this); + ac->Changed (true, PBD::Controllable::GroupControlDisposition::UseGroup); + return true; } bool Console1::handle_plugin_parameter(const PluginParameterMapping& ppm, int32_t n_controls, const ParameterDescriptor& parameterDescriptor, - const std::shared_ptr& c) + const std::shared_ptr& ac) { bool swtch = false; - if (parameterDescriptor.integer_step && parameterDescriptor.upper == 1) { - swtch = true; - } else if (ppm.is_switch) { - swtch = true; - } - if (!swtch) { - return setup_plugin_encoder(ppm, n_controls, parameterDescriptor, c); - } else { - return setup_plugin_button(ppm, n_controls, parameterDescriptor, c); + DEBUG_TRACE (DEBUG::Console1, string_compose ("\nName: %1 \n", parameterDescriptor.label)); + DEBUG_TRACE (DEBUG::Console1, string_compose ("Normal: %1 \n", parameterDescriptor.normal)); + DEBUG_TRACE (DEBUG::Console1, string_compose ("Lower: %1 \n", parameterDescriptor.lower)); + DEBUG_TRACE (DEBUG::Console1, string_compose ("Upper: %1 \n", parameterDescriptor.upper)); + DEBUG_TRACE (DEBUG::Console1, string_compose ("Toggled: %1 \n", parameterDescriptor.toggled)); + DEBUG_TRACE (DEBUG::Console1, string_compose ("Logarithmic: %1 \n", parameterDescriptor.logarithmic)); + DEBUG_TRACE (DEBUG::Console1, string_compose ("Rangesteps: %1 \n", parameterDescriptor.rangesteps)); + DEBUG_TRACE (DEBUG::Console1, string_compose ("Unit: %1 \n", parameterDescriptor.unit)); + DEBUG_TRACE (DEBUG::Console1, string_compose ("Step: %1 \n", parameterDescriptor.step)); + DEBUG_TRACE (DEBUG::Console1, string_compose ("Smallstep: %1 \n", parameterDescriptor.smallstep)); + DEBUG_TRACE (DEBUG::Console1, string_compose ("Largestep: %1 \n", parameterDescriptor.largestep)); + DEBUG_TRACE (DEBUG::Console1, string_compose ("Int-step: %1 \n", parameterDescriptor.integer_step)); + DEBUG_TRACE (DEBUG::Console1, string_compose ("Sr_dependent: %1 \n", parameterDescriptor.sr_dependent)); + DEBUG_TRACE (DEBUG::Console1, string_compose ("Enumeration: %1 \n", parameterDescriptor.enumeration)); + DEBUG_TRACE (DEBUG::Console1, string_compose ("Inlinectrl: %1 \n", parameterDescriptor.inline_ctrl)); + + if (parameterDescriptor.toggled) + swtch = true; + else if (parameterDescriptor.integer_step && parameterDescriptor.upper == 1) + swtch = true; + else if (ppm.is_switch) + swtch = true; + + return setup_plugin_controller(ppm, n_controls, parameterDescriptor, ac); +} + +bool +Console1::remap_plugin_parameter (int plugin_index) +{ + DEBUG_TRACE (DEBUG::Console1, string_compose ("Console1::remap_plugin_parameter index = %1 \n", plugin_index)); + //plugin_connections.drop_connections (); + + int32_t n_controls = -1; + std::shared_ptr proc = find_plugin (plugin_index); + set p = proc->what_can_be_automated (); + + std::shared_ptr plugin_insert = std::dynamic_pointer_cast (proc); + if (!plugin_insert) + return false; + + std::shared_ptr plugin = plugin_insert->plugin (); + if (!plugin) + return false; + + setup_plugin_mute_button (plugin_insert); + + PluginMappingMap::iterator pmmit = plugin_mapping_map.find (plugin->unique_id ()); + if (pmmit == plugin_mapping_map.end ()) + return false; + PluginMapping pluginMapping = pmmit->second; + + for (set::iterator j = p.begin (); j != p.end (); ++j) { + ++n_controls; + std::string n = proc->describe_parameter (*j); + DEBUG_TRACE (DEBUG::Console1, string_compose ("Console1::remap_plugin_parameter: Plugin parameter %1: %2\n", n_controls, n)); + if (n == "hidden") { + continue; + } + ParameterDescriptor parameterDescriptor; + plugin->get_parameter_descriptor (n_controls, parameterDescriptor); + PluginParameterMapping ppm = pluginMapping.parameters[n_controls]; + Controller *controller = get_controller (ppm.controllerId); + std::shared_ptr ac = plugin_insert->automation_control (Evoral::Parameter (PluginAutomation, 0, n_controls)); + if (controller && ac) { + DEBUG_TRACE (DEBUG::Console1, string_compose ("CONTROLLER has plugin_action %1, has shitft_plugin_action %2\n", controller->get_plugin_action () ? "Yes" : "No", controller->get_plugin_shift_action () ? "Yes" : "No")); + set_plugin_receive_connection (controller, ac, parameterDescriptor, ppm); + } } + return true; } bool @@ -499,8 +576,8 @@ Console1::spill_plugins (const int32_t plugin_index) // Setup mute button setup_plugin_mute_button(plugin_insert); - PluginMappingMap::iterator pmmit = pluginMappingMap.find (plugin->unique_id ()); - mapping_found = (pmmit != pluginMappingMap.end ()); + PluginMappingMap::iterator pmmit = plugin_mapping_map.find (plugin->unique_id ()); + mapping_found = (pmmit != plugin_mapping_map.end ()); if (!mapping_found) { if (create_mapping_stubs) { @@ -527,13 +604,6 @@ Console1::spill_plugins (const int32_t plugin_index) plugin->get_parameter_descriptor (n_controls, parameterDescriptor); if (plugin->parameter_is_control (n_controls)) { DEBUG_TRACE (DEBUG::Console1, "parameter is control\n"); - DEBUG_TRACE (DEBUG::Console1, string_compose("normal: %1, lower %2, upper %3, toogled %4, log %5, num steps %6\n", - parameterDescriptor.normal, - parameterDescriptor.lower, - parameterDescriptor.upper, - parameterDescriptor.toggled, - parameterDescriptor.logarithmic, - parameterDescriptor.rangesteps ) ) } if (plugin->parameter_is_output (n_controls)) { DEBUG_TRACE (DEBUG::Console1, "parameter is output\n"); @@ -557,11 +627,12 @@ Glib::RefPtr Console1::getPluginControllerModel() { plugin_controller_model = Gtk::ListStore::create (plugin_controller_columns); Gtk::TreeModel::Row plugin_controller_combo_row; - for( const auto &controller : controllerNameIdMap ){ - plugin_controller_combo_row = *(plugin_controller_model->append ()); - plugin_controller_combo_row[plugin_controller_columns.controllerId] = controller.second; - plugin_controller_combo_row[plugin_controller_columns.controllerName] = X_(controller.first); - } + for( const auto &controller : controllerNameIdMap ) + { + plugin_controller_combo_row = *(plugin_controller_model->append ()); + plugin_controller_combo_row[plugin_controller_columns.controllerId] = controller.second; + plugin_controller_combo_row[plugin_controller_columns.controllerName] = X_ (controller.first); + } return plugin_controller_model; } diff --git a/libs/surfaces/console1/console1.cc b/libs/surfaces/console1/console1.cc index 974391a3be9..64c4730f2a5 100644 --- a/libs/surfaces/console1/console1.cc +++ b/libs/surfaces/console1/console1.cc @@ -1265,4 +1265,12 @@ const std::string Console1::findControllerNameById (const ControllerID id){ } return std::string(); } + +void +Console1::reset_midi_assign_mode () +{ + DEBUG_TRACE (DEBUG::Console1, "console1::reset_midi_assign_mode()\n"); + midi_assign_mode = false; +} + } // namespace Console1 \ No newline at end of file diff --git a/libs/surfaces/console1/console1.h b/libs/surfaces/console1/console1.h index 66884248b22..d2702da2815 100644 --- a/libs/surfaces/console1/console1.h +++ b/libs/surfaces/console1/console1.h @@ -132,6 +132,8 @@ class Console1 : public MIDISurface bool midi_assign_mode = false; + void reset_midi_assign_mode (); + bool in_use(){ return _in_use; } @@ -143,10 +145,11 @@ class Console1 : public MIDISurface PBD::Signal Periodic; /* Local Signals */ - PBD::Signal BankChange; - PBD::Signal ShiftChange; - PBD::Signal PluginStateChange; - PBD::Signal EQBandQBindingChange; + PBD::Signal PluginStubAdded; + PBD::Signal BankChange; + PBD::Signal ShiftChange; + PBD::Signal PluginStateChange; + PBD::Signal EQBandQBindingChange; sigc::signal2 SendControllerNumber; enum ControllerID { @@ -672,31 +675,31 @@ class Console1 : public MIDISurface void create_plugin_mapping_stubs (const std::shared_ptr proc, const std::shared_ptr plugin); bool spill_plugins (const int32_t plugin_index); - bool setup_plugin_mute_button (const std::shared_ptr &plugin_insert); - - bool setup_plugin_encoder (const PluginParameterMapping &ppm, int32_t n_controls, - const ARDOUR::ParameterDescriptor ¶meterDescriptor, - const std::shared_ptr &c); - - bool setup_plugin_button (const PluginParameterMapping &ppm, int32_t n_controls, - const ARDOUR::ParameterDescriptor ¶meterDescriptor, - const std::shared_ptr &c); + + bool setup_plugin_mute_button (const std::shared_ptr& plugin_insert); + + bool setup_plugin_controller (const PluginParameterMapping& ppm, int32_t n_controls, + const ARDOUR::ParameterDescriptor& parameterDescriptor, + const std::shared_ptr& ac); - bool handle_plugin_parameter (const PluginParameterMapping &ppm, int32_t n_controls, - const ARDOUR::ParameterDescriptor ¶meterDescriptor, - const std::shared_ptr &c); + bool handle_plugin_parameter (const PluginParameterMapping& ppm, int32_t n_controls, + const ARDOUR::ParameterDescriptor& parameterDescriptor, + const std::shared_ptr& c); - /* plugin operations */ - void remove_plugin_operations (); + bool set_plugin_receive_connection (Controller* controller, const std::shared_ptr& ac, const ARDOUR::ParameterDescriptor& parameterDescriptor, const PluginParameterMapping& ppm); + + bool remap_plugin_parameter (int plugin_index); + + /* plugin operations */ + void remove_plugin_operations (); std::shared_ptr find_plugin (const int32_t plugin_index); - bool select_plugin (const int32_t plugin_index); + bool select_plugin (const int32_t plugin_index); bool map_select_plugin (const int32_t plugin_index); - void eqBandQChangeMapping (bool mapValues); + void eqBandQChangeMapping (bool mapValues); - - public: +public: struct PluginMapping { std::string id; @@ -705,9 +708,8 @@ class Console1 : public MIDISurface ParameterMap parameters; }; using PluginMappingMap = std::map; - PluginMappingMap pluginMappingMap; + PluginMappingMap plugin_mapping_map; - PluginMappingMap getPluginMappingMap () { return pluginMappingMap; } Glib::RefPtr getPluginControllerModel(); void write_plugin_mapping (PluginMapping &mapping); };