From 8a18929d57ef82b1233278668a9efe78fe1c17f0 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Thu, 21 Jun 2018 13:05:37 -0400 Subject: remove Session::controllable_by_descriptor() and move code into GenericMIDI code (the only user). This also removes enums introduced to describe well-known parameters for Mixbus. Lookup now involves string parsing every time, but this is not likely to be a notable cost. --- libs/ardour/ardour/controllable_descriptor.h | 82 ----- libs/ardour/ardour/session.h | 2 - libs/ardour/ardour/types.h | 20 -- libs/ardour/controllable_descriptor.cc | 298 ------------------ libs/ardour/session_state.cc | 187 ------------ libs/ardour/wscript | 1 - libs/evoral/evoral/Parameter.hpp | 4 + libs/evoral/src/ControlSet.cpp | 10 + libs/surfaces/cc121/cc121.cc | 1 - libs/surfaces/cc121/cc121.h | 1 - libs/surfaces/faderport/faderport.cc | 1 - libs/surfaces/faderport/faderport.h | 1 - .../generic_midi/generic_midi_control_protocol.cc | 336 ++++++++++++++++++++- .../generic_midi/generic_midi_control_protocol.h | 3 +- libs/surfaces/generic_midi/midicontrollable.cc | 13 +- libs/surfaces/generic_midi/midicontrollable.h | 7 - 16 files changed, 342 insertions(+), 625 deletions(-) delete mode 100644 libs/ardour/ardour/controllable_descriptor.h delete mode 100644 libs/ardour/controllable_descriptor.cc diff --git a/libs/ardour/ardour/controllable_descriptor.h b/libs/ardour/ardour/controllable_descriptor.h deleted file mode 100644 index af762473a9..0000000000 --- a/libs/ardour/ardour/controllable_descriptor.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - Copyright (C) 2009 Paul Davis - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef __libardour_controllable_descriptor_h__ -#define __libardour_controllable_descriptor_h__ - -#include -#include -#include - -#include "ardour/libardour_visibility.h" -#include "ardour/types.h" - -namespace ARDOUR { - -class LIBARDOUR_API ControllableDescriptor { -public: - enum TopLevelType { - PresentationOrderRoute, - PresentationOrderTrack, - PresentationOrderBus, - PresentationOrderVCA, - NamedRoute, - SelectionCount, - }; - - ControllableDescriptor () - : _top_level_type (PresentationOrderRoute) - , _subtype (GainAutomation) - , _banked (false) - , _bank_offset (0) - {} - - int set (const std::string&); - - /* it is only valid to call top_level_name() if top_level_type() returns - NamedRoute - */ - - TopLevelType top_level_type() const { return _top_level_type; } - const std::string& top_level_name() const { return _top_level_name; } - - AutomationType subtype() const { return _subtype; } - - uint32_t presentation_order() const; - uint32_t selection_id() const; - uint32_t target (uint32_t n) const; - bool banked() const { return _banked; } - - void set_bank_offset (uint32_t o) { _bank_offset = o; } - -private: - TopLevelType _top_level_type; - AutomationType _subtype; - std::string _top_level_name; - union { - uint32_t _presentation_order; - uint32_t _selection_id; - }; - std::vector _target; - uint32_t _banked; - uint32_t _bank_offset; -}; - -} - -#endif /* __libardour_controllable_descriptor_h__ */ diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 4cf725ae2f..835e6668bc 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -116,7 +116,6 @@ class BufferSet; class Bundle; class Butler; class Click; -class ControllableDescriptor; class CoreSelection; class ExportHandler; class ExportStatus; @@ -1082,7 +1081,6 @@ public: boost::shared_ptr controllable_by_id (const PBD::ID&); boost::shared_ptr automation_control_by_id (const PBD::ID&); - boost::shared_ptr controllable_by_descriptor (const ARDOUR::ControllableDescriptor&); void add_controllable (boost::shared_ptr); void remove_controllable (PBD::Controllable*); diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h index ed6ba96617..a3af7e2c3d 100644 --- a/libs/ardour/ardour/types.h +++ b/libs/ardour/ardour/types.h @@ -158,26 +158,6 @@ namespace ARDOUR { SendLevelAutomation, SendEnableAutomation, SendAzimuthAutomation, - - /* these describe "well known" controls of a Stripable that are - covered by the types above. They should be used only as part - of ControllableDescriptor - */ - - EQEnableAutomation, - EQGainAutomation, - EQFreqAutomation, - EQQAutomation, - EQShapeAutomation, - FilterFreqAutomation, - FilterSlopeAutomation, - FilterEnableAutomation, - CompressorEnableAutomation, - CompressorThresholdAutomation, - CompressorSpeedAutomation, - CompressorModeAutomation, - CompressorMakeupAutomation, - /* Redux not included because it is read-only */ }; enum AutoState { diff --git a/libs/ardour/controllable_descriptor.cc b/libs/ardour/controllable_descriptor.cc deleted file mode 100644 index b55b0b3c4c..0000000000 --- a/libs/ardour/controllable_descriptor.cc +++ /dev/null @@ -1,298 +0,0 @@ -/* - Copyright (C) 2009 Paul Davis - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifdef COMPILER_MSVC -#include // Microsoft's nearest equivalent to -#include -#else -#include -#endif - -#include "pbd/strsplit.h" -#include "pbd/convert.h" - -#include "ardour/controllable_descriptor.h" - -using namespace std; -using namespace PBD; -using namespace ARDOUR; - -int -ControllableDescriptor::set (const std::string& str) -{ - string::size_type first_space = str.find_first_of (" "); - - if (first_space == string::npos) { - return -1; - } - - string front = str.substr (0, first_space); - string back = str.substr (first_space); - - vector path; - split (front, path, '/'); - - if (path.size() < 2) { - return -1; - } - - vector rest; - split (back, rest, ' '); - - if (rest.size() < 1) { - return -1; - } - - bool stripable = false; - regex_t compiled_pattern; - const char * const pattern = "^[BS]?[0-9]+"; - - if (path[0] == "route" || path[0] == "rid") { - - /* this is not going to fail */ - regcomp (&compiled_pattern, pattern, REG_EXTENDED|REG_NOSUB); - bool matched = (regexec (&compiled_pattern, rest[0].c_str(), 0, 0, 0) == 0); - regfree (&compiled_pattern); - - if (matched) { - _top_level_type = PresentationOrderRoute; - stripable = true; - } else { - _top_level_type = NamedRoute; - _top_level_name = rest[0]; - } - - } else if (path[0] == "vca") { - _top_level_type = PresentationOrderVCA; - stripable = true; - } else if (path[0] == "bus") { - /* digits, or B or S will be used as for route; - anything else will be treated as a track name. - */ - - /* this is not going to fail */ - - regcomp (&compiled_pattern, pattern, REG_EXTENDED|REG_NOSUB); - bool matched = (regexec (&compiled_pattern, rest[0].c_str(), 0, 0, 0) == 0); - regfree (&compiled_pattern); - - if (matched) { - _top_level_type = PresentationOrderBus; - stripable = true; - } else { - _top_level_type = NamedRoute; - _top_level_name = rest[0]; - } - - } else if (path[0] == "track") { - - /* digits, or B or S will be used as for route; - anything else will be treated as a track name. - */ - - /* this is not going to fail */ - regcomp (&compiled_pattern, pattern, REG_EXTENDED|REG_NOSUB); - bool matched = (regexec (&compiled_pattern, rest[0].c_str(), 0, 0, 0) == 0); - regfree (&compiled_pattern); - - if (matched) { - _top_level_type = PresentationOrderTrack; - stripable = true; - } else { - _top_level_type = NamedRoute; - _top_level_name = rest[0]; - } - } - - if (stripable) { - if (rest[0][0] == 'B') { - _banked = true; - _presentation_order = atoi (rest[0].substr (1)); - } else if (rest[0][0] == 'S') { - _top_level_type = SelectionCount; - _banked = true; - _selection_id = atoi (rest[0].substr (1)); - } else if (isdigit (rest[0][0])) { - _banked = false; - _presentation_order = atoi (rest[0]); - } else { - return -1; - } - - _presentation_order -= 1; /* order is zero-based, but maps use 1-based */ - } - - if (path[1] == "gain") { - _subtype = GainAutomation; - - } else if (path[1] == "trim") { - _subtype = TrimAutomation; - - } else if (path[1] == "solo") { - _subtype = SoloAutomation; - - } else if (path[1] == "mute") { - _subtype = MuteAutomation; - - } else if (path[1] == "recenable") { - _subtype = RecEnableAutomation; - - } else if (path[1] == "panwidth") { - _subtype = PanWidthAutomation; - - } else if (path[1] == "pandirection" || path[1] == "balance") { - _subtype = PanAzimuthAutomation; - - } else if (path[1] == "plugin") { - if (path.size() == 3 && rest.size() == 3) { - if (path[2] == "parameter") { - _subtype = PluginAutomation; - _target.push_back (atoi (rest[1])); - _target.push_back (atoi (rest[2])); - } else { - return -1; - } - } else { - return -1; - } - } else if (path[1] == "send") { - - if (path.size() == 3 && rest.size() == 2) { - if (path[2] == "gain") { - _subtype = SendLevelAutomation; - _target.push_back (atoi (rest[1])); - - } else if (path[2] == "direction") { - _subtype = SendAzimuthAutomation; - _target.push_back (atoi (rest[1])); - } else if (path[2] == "enable") { - _subtype = SendEnableAutomation; - _target.push_back (atoi (rest[1])); - } else { - return -1; - - } - } else { - return -1; - } - } else if (path[1] == "eq") { - - /* /route/eq/gain/ */ - - if (path.size() != 3) { - return -1; - } - - _target.push_back (atoi (path[3])); /* band number */ - - if (path[2] == "enable") { - _subtype = EQEnableAutomation; - } else if (path[2] == "gain") { - _subtype = EQGainAutomation; - } else if (path[2] == "freq") { - _subtype = EQFreqAutomation; - } else if (path[2] == "q") { - _subtype = EQQAutomation; - } else if (path[2] == "shape") { - _subtype = EQShapeAutomation; - } else { - return -1; - } - - /* get desired band number */ - _target.push_back (atoi (rest[1])); - - } else if (path[1] == "filter") { - - /* /route/filter/hi/freq */ - - if (path.size() != 4) { - return -1; - } - - if (path[2] == "hi") { - _target.push_back (1); /* high pass filter */ - } else { - _target.push_back (0); /* low pass filter */ - } - - if (path[3] == "enable") { - _subtype = FilterFreqAutomation; - } else if (path[3] == "freq") { - _subtype = FilterFreqAutomation; - } else if (path[3] == "slope") { - _subtype = FilterSlopeAutomation; - } else { - return -1; - } - - _target.push_back (atoi (rest[1])); - - } else if (path[1] == "compressor") { - - if (path.size() != 3) { - return -1; - } - - if (path[2] == "enable") { - _subtype = CompressorEnableAutomation; - } else if (path[2] == "threshold") { - _subtype = CompressorThresholdAutomation; - } else if (path[2] == "mode") { - _subtype = CompressorModeAutomation; - } else if (path[2] == "speed") { - _subtype = CompressorSpeedAutomation; - } else if (path[2] == "makeup") { - _subtype = CompressorMakeupAutomation; - } else { - return -1; - } - } - - return 0; -} - -uint32_t -ControllableDescriptor::presentation_order () const -{ - if (banked()) { - return _presentation_order + _bank_offset; - } - - return _presentation_order; -} - -uint32_t -ControllableDescriptor::selection_id () const -{ - if (banked()) { - return _selection_id + _bank_offset; - } - - return _selection_id; -} - -uint32_t -ControllableDescriptor::target (uint32_t n) const -{ - if (n < _target.size()) { - return _target[n]; - } - - return 0; -} diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 346a359229..c278454843 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -85,7 +85,6 @@ #include "ardour/automation_control.h" #include "ardour/boost_debug.h" #include "ardour/butler.h" -#include "ardour/controllable_descriptor.h" #include "ardour/control_protocol_manager.h" #include "ardour/directory_names.h" #include "ardour/disk_reader.h" @@ -3731,192 +3730,6 @@ Session::automation_control_by_id (const PBD::ID& id) return boost::dynamic_pointer_cast (controllable_by_id (id)); } -boost::shared_ptr -Session::controllable_by_descriptor (const ControllableDescriptor& desc) -{ - boost::shared_ptr c; - boost::shared_ptr s; - boost::shared_ptr r; - - switch (desc.top_level_type()) { - case ControllableDescriptor::NamedRoute: - { - std::string str = desc.top_level_name(); - - if (str == "Master" || str == "master") { - s = _master_out; - } else if (str == "control" || str == "listen" || str == "monitor" || str == "Monitor") { - s = _monitor_out; - } else if (str == "auditioner") { - s = auditioner; - } else { - s = route_by_name (desc.top_level_name()); - } - - break; - } - - case ControllableDescriptor::PresentationOrderRoute: - s = get_remote_nth_stripable (desc.presentation_order(), PresentationInfo::Route); - break; - - case ControllableDescriptor::PresentationOrderTrack: - s = get_remote_nth_stripable (desc.presentation_order(), PresentationInfo::Track); - break; - - case ControllableDescriptor::PresentationOrderBus: - s = get_remote_nth_stripable (desc.presentation_order(), PresentationInfo::Bus); - break; - - case ControllableDescriptor::PresentationOrderVCA: - s = get_remote_nth_stripable (desc.presentation_order(), PresentationInfo::VCA); - break; - - case ControllableDescriptor::SelectionCount: - s = route_by_selected_count (desc.selection_id()); - break; - } - - if (!s) { - return c; - } - - r = boost::dynamic_pointer_cast (s); - - switch (desc.subtype()) { - case GainAutomation: - c = s->gain_control (); - break; - - case TrimAutomation: - c = s->trim_control (); - break; - - case SoloAutomation: - c = s->solo_control(); - break; - - case MuteAutomation: - c = s->mute_control(); - break; - - case RecEnableAutomation: - c = s->rec_enable_control (); - break; - - case PanAzimuthAutomation: - c = s->pan_azimuth_control(); - break; - - case PanWidthAutomation: - c = s->pan_width_control(); - break; - - case PanElevationAutomation: - c = s->pan_elevation_control(); - break; - - case EQEnableAutomation: - c = s->eq_enable_controllable(); - break; - - case EQGainAutomation: - c = s->eq_gain_controllable(desc.target (0)); - break; - - case EQFreqAutomation: - c = s->eq_freq_controllable(desc.target(0)); - break; - - case EQQAutomation: - c = s->eq_q_controllable(desc.target(0)); - break; - - case EQShapeAutomation: - c = s->eq_shape_controllable(desc.target(0)); - break; - - case FilterFreqAutomation: - c = s->filter_freq_controllable(desc.target(0)); - break; - - case FilterSlopeAutomation: - c = s->filter_slope_controllable(desc.target(0)); - break; - - case FilterEnableAutomation: - c = s->filter_enable_controllable(desc.target(0)); - break; - - case CompressorEnableAutomation: - c = s->comp_enable_controllable(); - break; - - case CompressorThresholdAutomation: - c = s->comp_threshold_controllable(); - break; - - case CompressorSpeedAutomation: - c = s->comp_speed_controllable(); - break; - - case CompressorModeAutomation: - c = s->comp_mode_controllable(); - break; - - case CompressorMakeupAutomation: - c = s->comp_makeup_controllable(); - break; - - case PluginAutomation: - { - uint32_t plugin = desc.target (0); - uint32_t parameter_index = desc.target (1); - - /* revert to zero based counting */ - - if (plugin > 0) { - --plugin; - } - - if (parameter_index > 0) { - --parameter_index; - } - - if (!r) { - return c; - } - - boost::shared_ptr p = r->nth_plugin (plugin); - - if (p) { - c = boost::dynamic_pointer_cast( - p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index))); - } - break; - } - - case SendLevelAutomation: { - uint32_t send = desc.target (0); - if (send > 0) { - --send; - } - if (!r) { - return c; - } - c = r->send_level_controllable (send); - break; - } - - - default: - /* relax and return a null pointer */ - break; - } - - return c; -} - void Session::add_instant_xml (XMLNode& node, bool write_to_config) { diff --git a/libs/ardour/wscript b/libs/ardour/wscript index 5a5c99f22c..ec36068720 100644 --- a/libs/ardour/wscript +++ b/libs/ardour/wscript @@ -56,7 +56,6 @@ libardour_sources = [ 'chan_count.cc', 'chan_mapping.cc', 'config_text.cc', - 'controllable_descriptor.cc', 'control_group.cc', 'control_protocol_manager.cc', 'cycle_timer.cc', diff --git a/libs/evoral/evoral/Parameter.hpp b/libs/evoral/evoral/Parameter.hpp index 2614a03d86..10e95e096e 100644 --- a/libs/evoral/evoral/Parameter.hpp +++ b/libs/evoral/evoral/Parameter.hpp @@ -88,5 +88,9 @@ private: } // namespace Evoral +namespace std { +std::ostream& operator<< (std::ostream &str, Evoral::Parameter const &); +} + #endif // EVORAL_PARAMETER_HPP diff --git a/libs/evoral/src/ControlSet.cpp b/libs/evoral/src/ControlSet.cpp index cc8d7c60a7..f5a16057aa 100644 --- a/libs/evoral/src/ControlSet.cpp +++ b/libs/evoral/src/ControlSet.cpp @@ -74,6 +74,8 @@ ControlSet::control (const Parameter& parameter, bool create_if_missing) { Controls::iterator i = _controls.find(parameter); + cerr << "Look for " << parameter << endl; + if (i != _controls.end()) { return i->second; @@ -103,3 +105,11 @@ ControlSet::clear_controls () } } // namespace Evoral + +/* No good place for this so just put it here */ + +std::ostream& +std::operator<< (std::ostream & str, Evoral::Parameter const & p) +{ + return str << p.type() << '-' << p.id() << '-' << (int) p.channel(); +} diff --git a/libs/surfaces/cc121/cc121.cc b/libs/surfaces/cc121/cc121.cc index ac4acf3439..7c4f757eaf 100644 --- a/libs/surfaces/cc121/cc121.cc +++ b/libs/surfaces/cc121/cc121.cc @@ -44,7 +44,6 @@ #include "ardour/audioengine.h" #include "ardour/amp.h" #include "ardour/bundle.h" -#include "ardour/controllable_descriptor.h" #include "ardour/debug.h" #include "ardour/filesystem_paths.h" #include "ardour/midi_port.h" diff --git a/libs/surfaces/cc121/cc121.h b/libs/surfaces/cc121/cc121.h index bef1000ee6..ee9a3a5ccd 100644 --- a/libs/surfaces/cc121/cc121.h +++ b/libs/surfaces/cc121/cc121.h @@ -37,7 +37,6 @@ namespace PBD { class Controllable; - class ControllableDescriptor; } #include diff --git a/libs/surfaces/faderport/faderport.cc b/libs/surfaces/faderport/faderport.cc index ec4ceebb93..b8fc542f01 100644 --- a/libs/surfaces/faderport/faderport.cc +++ b/libs/surfaces/faderport/faderport.cc @@ -39,7 +39,6 @@ #include "ardour/audioengine.h" #include "ardour/amp.h" #include "ardour/bundle.h" -#include "ardour/controllable_descriptor.h" #include "ardour/debug.h" #include "ardour/filesystem_paths.h" #include "ardour/midi_port.h" diff --git a/libs/surfaces/faderport/faderport.h b/libs/surfaces/faderport/faderport.h index b174996e67..12854e3f2e 100644 --- a/libs/surfaces/faderport/faderport.h +++ b/libs/surfaces/faderport/faderport.h @@ -34,7 +34,6 @@ namespace PBD { class Controllable; - class ControllableDescriptor; } #include diff --git a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc index 1e1bda82e2..560bd43e57 100644 --- a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc +++ b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc @@ -22,25 +22,35 @@ #include #include +#ifdef COMPILER_MSVC +#include // Microsoft's nearest equivalent to +#include +#else +#include +#endif + #include #include +#include "pbd/compose.h" +#include "pbd/convert.h" #include "pbd/error.h" #include "pbd/failed_constructor.h" #include "pbd/file_utils.h" +#include "pbd/i18n.h" +#include "pbd/strsplit.h" #include "pbd/types_convert.h" #include "pbd/xml++.h" -#include "pbd/compose.h" #include "midi++/port.h" #include "ardour/async_midi_port.h" #include "ardour/audioengine.h" -#include "ardour/audioengine.h" -#include "ardour/controllable_descriptor.h" +#include "ardour/auditioner.h" #include "ardour/filesystem_paths.h" #include "ardour/session.h" #include "ardour/midi_ui.h" +#include "ardour/plugin_insert.h" #include "ardour/rc_configuration.h" #include "ardour/midiport_manager.h" #include "ardour/debug.h" @@ -919,11 +929,6 @@ GenericMidiControlProtocol::reset_controllables () ++next; if (!existingBinding->learned()) { - ControllableDescriptor& desc (existingBinding->descriptor()); - - if (desc.banked()) { - desc.set_bank_offset (_current_bank * _bank_size); - } /* its entirely possible that the session doesn't have * the specified controllable (e.g. it has too few @@ -940,9 +945,318 @@ GenericMidiControlProtocol::reset_controllables () } boost::shared_ptr -GenericMidiControlProtocol::lookup_controllable (const ControllableDescriptor& desc) const +GenericMidiControlProtocol::lookup_controllable (const string & str) const { - return session->controllable_by_descriptor (desc); + boost::shared_ptr c; + + DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("lookup controllable from \"%1\"\n", str)); + + if (!session) { + DEBUG_TRACE (DEBUG::GenericMidi, "no session\n"); + return c; + } + + /* step 1: split string apart */ + + string::size_type first_space = str.find_first_of (" "); + + if (first_space == string::npos) { + return c; + } + + string front = str.substr (0, first_space); + vector path; + split (front, path, '/'); + + if (path.size() < 2) { + return c; + } + + string back = str.substr (first_space); + vector rest; + split (back, rest, ' '); + + if (rest.empty()) { + return c; + } + + DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("parsed into path of %1, rest of %1\n", path.size(), rest.size())); + + /* Step 2: analyse parts of the string to figure out what type of + * Stripable we're looking for + */ + + enum Type { + Selection, + PresentationOrder, + Named, + }; + Type type = Named; + int id = 1; + string name; + + static regex_t compiled_pattern; + static bool compiled = false; + + if (!compiled) { + const char * const pattern = "^[BS]?[0-9]+"; + /* this pattern compilation is not going to fail */ + regcomp (&compiled_pattern, pattern, REG_EXTENDED|REG_NOSUB); + /* leak compiled pattern */ + compiled = true; + } + + /* Step 3: identify what "rest" looks like - name, or simple nueric, or + * banked/selection specifier + */ + + bool matched = (regexec (&compiled_pattern, rest[0].c_str(), 0, 0, 0) == 0); + + if (matched) { + bool banked = false; + + if (rest[0][0] == 'B') { + banked = true; + /* already matched digits, so we know atoi() will succeed */ + id = atoi (rest[0].substr (1)); + type = PresentationOrder; + } else if (rest[0][0] == 'S') { + /* already matched digits, so we know atoi() will succeed */ + id = atoi (rest[0].substr (1)); + type = Selection; + } else if (isdigit (rest[0][0])) { + /* already matched digits, so we know atoi() will succeed */ + id = atoi (rest[0]); + type = PresentationOrder; + } else { + return c; + } + + id -= 1; /* order is zero-based, but maps use 1-based */ + + if (banked) { + id += _current_bank * _bank_size; + } + + } else { + + type = Named; + name = rest[0]; + } + + /* step 4: find the reference Stripable */ + + boost::shared_ptr s; + + if (path[0] == X_("route") || path[0] == X_("rid")) { + + std::string name; + + switch (type) { + case PresentationOrder: + s = session->get_remote_nth_stripable (id, PresentationInfo::Route); + break; + case Named: + /* name */ + name = rest[0]; + + if (name == "Master" || name == X_("master")) { + s = session->master_out(); + } else if (name == X_("control") || name == X_("listen") || name == X_("monitor") || name == "Monitor") { + s = session->monitor_out(); + } else if (name == X_("auditioner")) { + s = session->the_auditioner(); + } else { + s = session->route_by_name (name); + } + break; + + case Selection: + s = session->route_by_selected_count (id); + break; + } + + } else if (path[0] == X_("vca")) { + + s = session->get_remote_nth_stripable (id, PresentationInfo::VCA); + + } else if (path[0] == X_("bus")) { + + switch (type) { + case Named: + s = session->route_by_name (name); + break; + default: + s = session->get_remote_nth_stripable (id, PresentationInfo::Bus); + } + + } else if (path[0] == X_("track")) { + + switch (type) { + case Named: + s = session->route_by_name (name); + break; + default: + s = session->get_remote_nth_stripable (id, PresentationInfo::Track); + } + } + + if (!s) { + DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("no stripable found for \"%1\"\n", str)); + return c; + } + + DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("found stripable %1\n", s->name())); + + /* step 5: find the referenced controllable for that stripable. + * + * Some controls exist only for Route, so we need that too + */ + + boost::shared_ptr r = boost::dynamic_pointer_cast (s); + + if (path[1] == X_("gain")) { + c = s->gain_control(); + } else if (path[1] == X_("trim")) { + c = s->trim_control (); + } else if (path[1] == X_("solo")) { + c = s->solo_control(); + } else if (path[1] == X_("mute")) { + c = s->mute_control(); + } else if (path[1] == X_("recenable")) { + c = s->rec_enable_control (); + } else if (path[1] == X_("panwidth")) { + c = s->pan_width_control (); + } else if (path[1] == X_("pandirection") || path[1] == X_("balance")) { + c = s->pan_azimuth_control (); + } else if (path[1] == X_("plugin")) { + + /* /route/plugin/parameter */ + + if (path.size() == 3 && rest.size() == 3) { + if (path[2] == X_("parameter")) { + + int plugin = atoi (rest[1]); + int parameter_index = atoi (rest[2]); + + /* revert to zero based counting */ + if (plugin > 0) { + --plugin; + } + if (parameter_index > 0) { + --parameter_index; + } + + if (r) { + boost::shared_ptr proc = r->nth_plugin (plugin); + + if (proc) { + boost::shared_ptr p = boost::dynamic_pointer_cast (proc); + if (p) { + uint32_t param; + bool ok; + param = p->plugin()->nth_parameter (parameter_index, ok); + if (ok) { + c = boost::dynamic_pointer_cast (proc->control (Evoral::Parameter (PluginAutomation, 0, param))); + } + } + } + } + } + } + + } else if (path[1] == X_("send")) { + + if (path.size() == 3 && rest.size() == 2) { + if (path[2] == X_("gain")) { + uint32_t send = atoi (rest[1]); + if (send > 0) { + --send; + } + c = s->send_level_controllable (send); + } else if (path[2] == X_("direction")) { + /* XXX not implemented yet */ + + } else if (path[2] == X_("enable")) { + /* XXX not implemented yet */ + } + } + + } else if (path[1] == X_("eq")) { + + /* /route/eq/enable */ + /* /route/eq/gain/ */ + /* /route/eq/freq/ */ + /* /route/eq/q/ */ + /* /route/eq/shape/ */ + + if (path.size() == 3) { + + if (path[2] == X_("enable")) { + c = s->eq_enable_controllable (); + } + + } else if (path.size() == 4) { + + int band = atoi (path[3]); /* band number */ + + if (path[2] == X_("gain")) { + c = s->eq_gain_controllable (band); + } else if (path[2] == X_("freq")) { + c = s->eq_freq_controllable (band); + } else if (path[2] == X_("q")) { + c = s->eq_q_controllable (band); + } else if (path[2] == X_("shape")) { + c = s->eq_shape_controllable (band); + } + } + } else if (path[1] == X_("filter")) { + + /* /route/filter/hi/freq */ + + if (path.size() == 4) { + + int filter; + + if (path[2] == X_("hi")) { + filter = 1; /* high pass filter */ + } else { + filter = 0; /* low pass filter */ + } + + if (path[3] == X_("enable")) { + c = s->filter_enable_controllable (filter); + } else if (path[3] == X_("freq")) { + c = s->filter_freq_controllable (filter); + } else if (path[3] == X_("slope")) { + c = s->filter_slope_controllable (filter); + } + + } else if (path[1] == X_("compressor")) { + + if (path.size() == 3) { + if (path[2] == X_("enable")) { + c = s->comp_enable_controllable (); + } else if (path[2] == X_("threshold")) { + c = s->comp_threshold_controllable (); + } else if (path[2] == X_("mode")) { + c = s->comp_mode_controllable (); + } else if (path[2] == X_("speed")) { + c = s->comp_speed_controllable (); + } else if (path[2] == X_("makeup")) { + c = s->comp_makeup_controllable (); + } + } + } + } + + if (c) { + DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("found controllable \"%1\"\n", c->name())); + } else { + DEBUG_TRACE (DEBUG::GenericMidi, "no controllable found\n"); + } + + return c; } MIDIFunction* @@ -1226,7 +1540,6 @@ GenericMidiControlProtocol::connection_handler (boost::weak_ptr, s void GenericMidiControlProtocol::connected () { - cerr << "Now connected\n"; } boost::shared_ptr @@ -1249,4 +1562,3 @@ GenericMidiControlProtocol::maybe_start_touch (Controllable* controllable) actl->start_touch (session->audible_sample ()); } } - diff --git a/libs/surfaces/generic_midi/generic_midi_control_protocol.h b/libs/surfaces/generic_midi/generic_midi_control_protocol.h index 6585c7ea24..da4bb619a3 100644 --- a/libs/surfaces/generic_midi/generic_midi_control_protocol.h +++ b/libs/surfaces/generic_midi/generic_midi_control_protocol.h @@ -34,7 +34,6 @@ namespace PBD { namespace ARDOUR { class AsyncMIDIPort; - class ControllableDescriptor; class MidiPort; class Session; } @@ -67,7 +66,7 @@ class GenericMidiControlProtocol : public ARDOUR::ControlProtocol { int set_feedback (bool yn); bool get_feedback () const; - boost::shared_ptr lookup_controllable (const ARDOUR::ControllableDescriptor&) const; + boost::shared_ptr lookup_controllable (std::string const &) const; void maybe_start_touch (PBD::Controllable*); diff --git a/libs/surfaces/generic_midi/midicontrollable.cc b/libs/surfaces/generic_midi/midicontrollable.cc index fe592965ee..13b47a4d7c 100644 --- a/libs/surfaces/generic_midi/midicontrollable.cc +++ b/libs/surfaces/generic_midi/midicontrollable.cc @@ -34,7 +34,6 @@ #include "ardour/async_midi_port.h" #include "ardour/automation_control.h" -#include "ardour/controllable_descriptor.h" #include "ardour/midi_ui.h" #include "ardour/debug.h" @@ -49,7 +48,6 @@ using namespace ARDOUR; MIDIControllable::MIDIControllable (GenericMidiControlProtocol* s, MIDI::Parser& p, bool m) : _surface (s) , controllable (0) - , _descriptor (0) , _parser (p) , _momentary (m) { @@ -68,7 +66,6 @@ MIDIControllable::MIDIControllable (GenericMidiControlProtocol* s, MIDI::Parser& MIDIControllable::MIDIControllable (GenericMidiControlProtocol* s, MIDI::Parser& p, Controllable& c, bool m) : _surface (s) - , _descriptor (0) , _parser (p) , _momentary (m) { @@ -90,17 +87,13 @@ MIDIControllable::MIDIControllable (GenericMidiControlProtocol* s, MIDI::Parser& MIDIControllable::~MIDIControllable () { drop_external_control (); - delete _descriptor; - _descriptor = 0; } int MIDIControllable::init (const std::string& s) { _current_uri = s; - delete _descriptor; - _descriptor = new ControllableDescriptor; - return _descriptor->set (s); + return 0; } void @@ -250,11 +243,11 @@ MIDIControllable::midi_sense_note_off (Parser &p, EventTwoBytes *tb) int MIDIControllable::lookup_controllable() { - if (!_descriptor) { + if (_current_uri.empty()) { return -1; } - boost::shared_ptr c = _surface->lookup_controllable (*_descriptor); + boost::shared_ptr c = _surface->lookup_controllable (_current_uri); if (!c) { return -1; diff --git a/libs/surfaces/generic_midi/midicontrollable.h b/libs/surfaces/generic_midi/midicontrollable.h index b6486dc873..b8c69e036e 100644 --- a/libs/surfaces/generic_midi/midicontrollable.h +++ b/libs/surfaces/generic_midi/midicontrollable.h @@ -30,10 +30,6 @@ #include "ardour/types.h" -namespace ARDOUR { - class ControllableDescriptor; -} - namespace MIDI { class Channel; class Parser; @@ -96,8 +92,6 @@ class MIDIControllable : public PBD::Stateful void set_controllable (PBD::Controllable*); const std::string& current_uri() const { return _current_uri; } - ARDOUR::ControllableDescriptor& descriptor() const { return *_descriptor; } - std::string control_description() const { return _control_description; } XMLNode& get_state (void); @@ -121,7 +115,6 @@ class MIDIControllable : public PBD::Stateful GenericMidiControlProtocol* _surface; PBD::Controllable* controllable; - ARDOUR::ControllableDescriptor* _descriptor; std::string _current_uri; MIDI::Parser& _parser; bool setting; -- cgit v1.2.3