summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/ardour/ardour/controllable_descriptor.h82
-rw-r--r--libs/ardour/ardour/session.h2
-rw-r--r--libs/ardour/ardour/types.h20
-rw-r--r--libs/ardour/controllable_descriptor.cc298
-rw-r--r--libs/ardour/session_state.cc187
-rw-r--r--libs/ardour/wscript1
-rw-r--r--libs/evoral/evoral/Parameter.hpp4
-rw-r--r--libs/evoral/src/ControlSet.cpp10
-rw-r--r--libs/surfaces/cc121/cc121.cc1
-rw-r--r--libs/surfaces/cc121/cc121.h1
-rw-r--r--libs/surfaces/faderport/faderport.cc1
-rw-r--r--libs/surfaces/faderport/faderport.h1
-rw-r--r--libs/surfaces/generic_midi/generic_midi_control_protocol.cc336
-rw-r--r--libs/surfaces/generic_midi/generic_midi_control_protocol.h3
-rw-r--r--libs/surfaces/generic_midi/midicontrollable.cc13
-rw-r--r--libs/surfaces/generic_midi/midicontrollable.h7
16 files changed, 342 insertions, 625 deletions
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 <vector>
-#include <string>
-#include <stdint.h>
-
-#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<uint32_t> _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<PBD::Controllable> controllable_by_id (const PBD::ID&);
boost::shared_ptr<AutomationControl> automation_control_by_id (const PBD::ID&);
- boost::shared_ptr<PBD::Controllable> controllable_by_descriptor (const ARDOUR::ControllableDescriptor&);
void add_controllable (boost::shared_ptr<PBD::Controllable>);
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 <io.h> // Microsoft's nearest equivalent to <unistd.h>
-#include <ardourext/misc.h>
-#else
-#include <regex.h>
-#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<string> path;
- split (front, path, '/');
-
- if (path.size() < 2) {
- return -1;
- }
-
- vector<string> 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<digits> or S<digits> 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<digits> or S<digits> 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/<band> */
-
- 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<AutomationControl> (controllable_by_id (id));
}
-boost::shared_ptr<Controllable>
-Session::controllable_by_descriptor (const ControllableDescriptor& desc)
-{
- boost::shared_ptr<Controllable> c;
- boost::shared_ptr<Stripable> s;
- boost::shared_ptr<Route> 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<Route> (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<Processor> p = r->nth_plugin (plugin);
-
- if (p) {
- c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
- 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 <midi++/types.h>
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 <midi++/types.h>
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 <sstream>
#include <algorithm>
+#ifdef COMPILER_MSVC
+#include <io.h> // Microsoft's nearest equivalent to <unistd.h>
+#include <ardourext/misc.h>
+#else
+#include <regex.h>
+#endif
+
#include <glibmm/fileutils.h>
#include <glibmm/miscutils.h>
+#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<Controllable>
-GenericMidiControlProtocol::lookup_controllable (const ControllableDescriptor& desc) const
+GenericMidiControlProtocol::lookup_controllable (const string & str) const
{
- return session->controllable_by_descriptor (desc);
+ boost::shared_ptr<Controllable> 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<string> path;
+ split (front, path, '/');
+
+ if (path.size() < 2) {
+ return c;
+ }
+
+ string back = str.substr (first_space);
+ vector<string> 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<Stripable> 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<Route> r = boost::dynamic_pointer_cast<Route> (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<Processor> proc = r->nth_plugin (plugin);
+
+ if (proc) {
+ boost::shared_ptr<PluginInsert> p = boost::dynamic_pointer_cast<PluginInsert> (proc);
+ if (p) {
+ uint32_t param;
+ bool ok;
+ param = p->plugin()->nth_parameter (parameter_index, ok);
+ if (ok) {
+ c = boost::dynamic_pointer_cast<Controllable> (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/<band> */
+ /* /route/eq/freq/<band> */
+ /* /route/eq/q/<band> */
+ /* /route/eq/shape/<band> */
+
+ 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<ARDOUR::Port>, s
void
GenericMidiControlProtocol::connected ()
{
- cerr << "Now connected\n";
}
boost::shared_ptr<Port>
@@ -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<PBD::Controllable> lookup_controllable (const ARDOUR::ControllableDescriptor&) const;
+ boost::shared_ptr<PBD::Controllable> 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<Controllable> c = _surface->lookup_controllable (*_descriptor);
+ boost::shared_ptr<Controllable> 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;