mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-06 14:54:56 +01:00
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.
This commit is contained in:
parent
637e70749c
commit
8a18929d57
16 changed files with 342 additions and 625 deletions
|
|
@ -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__ */
|
|
||||||
|
|
@ -116,7 +116,6 @@ class BufferSet;
|
||||||
class Bundle;
|
class Bundle;
|
||||||
class Butler;
|
class Butler;
|
||||||
class Click;
|
class Click;
|
||||||
class ControllableDescriptor;
|
|
||||||
class CoreSelection;
|
class CoreSelection;
|
||||||
class ExportHandler;
|
class ExportHandler;
|
||||||
class ExportStatus;
|
class ExportStatus;
|
||||||
|
|
@ -1082,7 +1081,6 @@ public:
|
||||||
|
|
||||||
boost::shared_ptr<PBD::Controllable> controllable_by_id (const PBD::ID&);
|
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<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 add_controllable (boost::shared_ptr<PBD::Controllable>);
|
||||||
void remove_controllable (PBD::Controllable*);
|
void remove_controllable (PBD::Controllable*);
|
||||||
|
|
|
||||||
|
|
@ -158,26 +158,6 @@ namespace ARDOUR {
|
||||||
SendLevelAutomation,
|
SendLevelAutomation,
|
||||||
SendEnableAutomation,
|
SendEnableAutomation,
|
||||||
SendAzimuthAutomation,
|
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 {
|
enum AutoState {
|
||||||
|
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -85,7 +85,6 @@
|
||||||
#include "ardour/automation_control.h"
|
#include "ardour/automation_control.h"
|
||||||
#include "ardour/boost_debug.h"
|
#include "ardour/boost_debug.h"
|
||||||
#include "ardour/butler.h"
|
#include "ardour/butler.h"
|
||||||
#include "ardour/controllable_descriptor.h"
|
|
||||||
#include "ardour/control_protocol_manager.h"
|
#include "ardour/control_protocol_manager.h"
|
||||||
#include "ardour/directory_names.h"
|
#include "ardour/directory_names.h"
|
||||||
#include "ardour/disk_reader.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));
|
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
|
void
|
||||||
Session::add_instant_xml (XMLNode& node, bool write_to_config)
|
Session::add_instant_xml (XMLNode& node, bool write_to_config)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,6 @@ libardour_sources = [
|
||||||
'chan_count.cc',
|
'chan_count.cc',
|
||||||
'chan_mapping.cc',
|
'chan_mapping.cc',
|
||||||
'config_text.cc',
|
'config_text.cc',
|
||||||
'controllable_descriptor.cc',
|
|
||||||
'control_group.cc',
|
'control_group.cc',
|
||||||
'control_protocol_manager.cc',
|
'control_protocol_manager.cc',
|
||||||
'cycle_timer.cc',
|
'cycle_timer.cc',
|
||||||
|
|
|
||||||
|
|
@ -88,5 +88,9 @@ private:
|
||||||
|
|
||||||
} // namespace Evoral
|
} // namespace Evoral
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
std::ostream& operator<< (std::ostream &str, Evoral::Parameter const &);
|
||||||
|
}
|
||||||
|
|
||||||
#endif // EVORAL_PARAMETER_HPP
|
#endif // EVORAL_PARAMETER_HPP
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,8 @@ ControlSet::control (const Parameter& parameter, bool create_if_missing)
|
||||||
{
|
{
|
||||||
Controls::iterator i = _controls.find(parameter);
|
Controls::iterator i = _controls.find(parameter);
|
||||||
|
|
||||||
|
cerr << "Look for " << parameter << endl;
|
||||||
|
|
||||||
if (i != _controls.end()) {
|
if (i != _controls.end()) {
|
||||||
return i->second;
|
return i->second;
|
||||||
|
|
||||||
|
|
@ -103,3 +105,11 @@ ControlSet::clear_controls ()
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Evoral
|
} // 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();
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,6 @@
|
||||||
#include "ardour/audioengine.h"
|
#include "ardour/audioengine.h"
|
||||||
#include "ardour/amp.h"
|
#include "ardour/amp.h"
|
||||||
#include "ardour/bundle.h"
|
#include "ardour/bundle.h"
|
||||||
#include "ardour/controllable_descriptor.h"
|
|
||||||
#include "ardour/debug.h"
|
#include "ardour/debug.h"
|
||||||
#include "ardour/filesystem_paths.h"
|
#include "ardour/filesystem_paths.h"
|
||||||
#include "ardour/midi_port.h"
|
#include "ardour/midi_port.h"
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,6 @@
|
||||||
|
|
||||||
namespace PBD {
|
namespace PBD {
|
||||||
class Controllable;
|
class Controllable;
|
||||||
class ControllableDescriptor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <midi++/types.h>
|
#include <midi++/types.h>
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,6 @@
|
||||||
#include "ardour/audioengine.h"
|
#include "ardour/audioengine.h"
|
||||||
#include "ardour/amp.h"
|
#include "ardour/amp.h"
|
||||||
#include "ardour/bundle.h"
|
#include "ardour/bundle.h"
|
||||||
#include "ardour/controllable_descriptor.h"
|
|
||||||
#include "ardour/debug.h"
|
#include "ardour/debug.h"
|
||||||
#include "ardour/filesystem_paths.h"
|
#include "ardour/filesystem_paths.h"
|
||||||
#include "ardour/midi_port.h"
|
#include "ardour/midi_port.h"
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@
|
||||||
|
|
||||||
namespace PBD {
|
namespace PBD {
|
||||||
class Controllable;
|
class Controllable;
|
||||||
class ControllableDescriptor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <midi++/types.h>
|
#include <midi++/types.h>
|
||||||
|
|
|
||||||
|
|
@ -22,25 +22,35 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <algorithm>
|
#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/fileutils.h>
|
||||||
#include <glibmm/miscutils.h>
|
#include <glibmm/miscutils.h>
|
||||||
|
|
||||||
|
#include "pbd/compose.h"
|
||||||
|
#include "pbd/convert.h"
|
||||||
#include "pbd/error.h"
|
#include "pbd/error.h"
|
||||||
#include "pbd/failed_constructor.h"
|
#include "pbd/failed_constructor.h"
|
||||||
#include "pbd/file_utils.h"
|
#include "pbd/file_utils.h"
|
||||||
|
#include "pbd/i18n.h"
|
||||||
|
#include "pbd/strsplit.h"
|
||||||
#include "pbd/types_convert.h"
|
#include "pbd/types_convert.h"
|
||||||
#include "pbd/xml++.h"
|
#include "pbd/xml++.h"
|
||||||
#include "pbd/compose.h"
|
|
||||||
|
|
||||||
#include "midi++/port.h"
|
#include "midi++/port.h"
|
||||||
|
|
||||||
#include "ardour/async_midi_port.h"
|
#include "ardour/async_midi_port.h"
|
||||||
#include "ardour/audioengine.h"
|
#include "ardour/audioengine.h"
|
||||||
#include "ardour/audioengine.h"
|
#include "ardour/auditioner.h"
|
||||||
#include "ardour/controllable_descriptor.h"
|
|
||||||
#include "ardour/filesystem_paths.h"
|
#include "ardour/filesystem_paths.h"
|
||||||
#include "ardour/session.h"
|
#include "ardour/session.h"
|
||||||
#include "ardour/midi_ui.h"
|
#include "ardour/midi_ui.h"
|
||||||
|
#include "ardour/plugin_insert.h"
|
||||||
#include "ardour/rc_configuration.h"
|
#include "ardour/rc_configuration.h"
|
||||||
#include "ardour/midiport_manager.h"
|
#include "ardour/midiport_manager.h"
|
||||||
#include "ardour/debug.h"
|
#include "ardour/debug.h"
|
||||||
|
|
@ -919,11 +929,6 @@ GenericMidiControlProtocol::reset_controllables ()
|
||||||
++next;
|
++next;
|
||||||
|
|
||||||
if (!existingBinding->learned()) {
|
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
|
/* its entirely possible that the session doesn't have
|
||||||
* the specified controllable (e.g. it has too few
|
* the specified controllable (e.g. it has too few
|
||||||
|
|
@ -940,9 +945,318 @@ GenericMidiControlProtocol::reset_controllables ()
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<Controllable>
|
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*
|
MIDIFunction*
|
||||||
|
|
@ -1226,7 +1540,6 @@ GenericMidiControlProtocol::connection_handler (boost::weak_ptr<ARDOUR::Port>, s
|
||||||
void
|
void
|
||||||
GenericMidiControlProtocol::connected ()
|
GenericMidiControlProtocol::connected ()
|
||||||
{
|
{
|
||||||
cerr << "Now connected\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<Port>
|
boost::shared_ptr<Port>
|
||||||
|
|
@ -1249,4 +1562,3 @@ GenericMidiControlProtocol::maybe_start_touch (Controllable* controllable)
|
||||||
actl->start_touch (session->audible_sample ());
|
actl->start_touch (session->audible_sample ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@ namespace PBD {
|
||||||
|
|
||||||
namespace ARDOUR {
|
namespace ARDOUR {
|
||||||
class AsyncMIDIPort;
|
class AsyncMIDIPort;
|
||||||
class ControllableDescriptor;
|
|
||||||
class MidiPort;
|
class MidiPort;
|
||||||
class Session;
|
class Session;
|
||||||
}
|
}
|
||||||
|
|
@ -67,7 +66,7 @@ class GenericMidiControlProtocol : public ARDOUR::ControlProtocol {
|
||||||
int set_feedback (bool yn);
|
int set_feedback (bool yn);
|
||||||
bool get_feedback () const;
|
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*);
|
void maybe_start_touch (PBD::Controllable*);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@
|
||||||
|
|
||||||
#include "ardour/async_midi_port.h"
|
#include "ardour/async_midi_port.h"
|
||||||
#include "ardour/automation_control.h"
|
#include "ardour/automation_control.h"
|
||||||
#include "ardour/controllable_descriptor.h"
|
|
||||||
#include "ardour/midi_ui.h"
|
#include "ardour/midi_ui.h"
|
||||||
#include "ardour/debug.h"
|
#include "ardour/debug.h"
|
||||||
|
|
||||||
|
|
@ -49,7 +48,6 @@ using namespace ARDOUR;
|
||||||
MIDIControllable::MIDIControllable (GenericMidiControlProtocol* s, MIDI::Parser& p, bool m)
|
MIDIControllable::MIDIControllable (GenericMidiControlProtocol* s, MIDI::Parser& p, bool m)
|
||||||
: _surface (s)
|
: _surface (s)
|
||||||
, controllable (0)
|
, controllable (0)
|
||||||
, _descriptor (0)
|
|
||||||
, _parser (p)
|
, _parser (p)
|
||||||
, _momentary (m)
|
, _momentary (m)
|
||||||
{
|
{
|
||||||
|
|
@ -68,7 +66,6 @@ MIDIControllable::MIDIControllable (GenericMidiControlProtocol* s, MIDI::Parser&
|
||||||
|
|
||||||
MIDIControllable::MIDIControllable (GenericMidiControlProtocol* s, MIDI::Parser& p, Controllable& c, bool m)
|
MIDIControllable::MIDIControllable (GenericMidiControlProtocol* s, MIDI::Parser& p, Controllable& c, bool m)
|
||||||
: _surface (s)
|
: _surface (s)
|
||||||
, _descriptor (0)
|
|
||||||
, _parser (p)
|
, _parser (p)
|
||||||
, _momentary (m)
|
, _momentary (m)
|
||||||
{
|
{
|
||||||
|
|
@ -90,17 +87,13 @@ MIDIControllable::MIDIControllable (GenericMidiControlProtocol* s, MIDI::Parser&
|
||||||
MIDIControllable::~MIDIControllable ()
|
MIDIControllable::~MIDIControllable ()
|
||||||
{
|
{
|
||||||
drop_external_control ();
|
drop_external_control ();
|
||||||
delete _descriptor;
|
|
||||||
_descriptor = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
MIDIControllable::init (const std::string& s)
|
MIDIControllable::init (const std::string& s)
|
||||||
{
|
{
|
||||||
_current_uri = s;
|
_current_uri = s;
|
||||||
delete _descriptor;
|
return 0;
|
||||||
_descriptor = new ControllableDescriptor;
|
|
||||||
return _descriptor->set (s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -250,11 +243,11 @@ MIDIControllable::midi_sense_note_off (Parser &p, EventTwoBytes *tb)
|
||||||
int
|
int
|
||||||
MIDIControllable::lookup_controllable()
|
MIDIControllable::lookup_controllable()
|
||||||
{
|
{
|
||||||
if (!_descriptor) {
|
if (_current_uri.empty()) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<Controllable> c = _surface->lookup_controllable (*_descriptor);
|
boost::shared_ptr<Controllable> c = _surface->lookup_controllable (_current_uri);
|
||||||
|
|
||||||
if (!c) {
|
if (!c) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
||||||
|
|
@ -30,10 +30,6 @@
|
||||||
|
|
||||||
#include "ardour/types.h"
|
#include "ardour/types.h"
|
||||||
|
|
||||||
namespace ARDOUR {
|
|
||||||
class ControllableDescriptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace MIDI {
|
namespace MIDI {
|
||||||
class Channel;
|
class Channel;
|
||||||
class Parser;
|
class Parser;
|
||||||
|
|
@ -96,8 +92,6 @@ class MIDIControllable : public PBD::Stateful
|
||||||
void set_controllable (PBD::Controllable*);
|
void set_controllable (PBD::Controllable*);
|
||||||
const std::string& current_uri() const { return _current_uri; }
|
const std::string& current_uri() const { return _current_uri; }
|
||||||
|
|
||||||
ARDOUR::ControllableDescriptor& descriptor() const { return *_descriptor; }
|
|
||||||
|
|
||||||
std::string control_description() const { return _control_description; }
|
std::string control_description() const { return _control_description; }
|
||||||
|
|
||||||
XMLNode& get_state (void);
|
XMLNode& get_state (void);
|
||||||
|
|
@ -121,7 +115,6 @@ class MIDIControllable : public PBD::Stateful
|
||||||
|
|
||||||
GenericMidiControlProtocol* _surface;
|
GenericMidiControlProtocol* _surface;
|
||||||
PBD::Controllable* controllable;
|
PBD::Controllable* controllable;
|
||||||
ARDOUR::ControllableDescriptor* _descriptor;
|
|
||||||
std::string _current_uri;
|
std::string _current_uri;
|
||||||
MIDI::Parser& _parser;
|
MIDI::Parser& _parser;
|
||||||
bool setting;
|
bool setting;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue