summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2016-04-15 17:57:40 +0200
committerRobin Gareus <robin@gareus.org>2016-04-15 17:57:40 +0200
commit424cacfbc83516d9e935bd93135e58b34dcfc002 (patch)
treec106cbc68fbb6e26b07e8c8e8608385b60f19cce
parent6f4ccfcd3b8ea971170b339fa93d501680cf44b3 (diff)
variable plugin port config.
* extend plugin API (query IO ports) * collect possible variable plugin configurations (AU, Lua) * prepare semi-automatic configuration (presets: mono, stereo, N)
-rw-r--r--libs/ardour/ardour/audio_unit.h3
-rw-r--r--libs/ardour/ardour/luaproc.h3
-rw-r--r--libs/ardour/ardour/lv2_plugin.h2
-rw-r--r--libs/ardour/ardour/plugin.h5
-rw-r--r--libs/ardour/ardour/plugin_insert.h6
-rw-r--r--libs/ardour/ardour/route.h1
-rw-r--r--libs/ardour/audio_unit.cc90
-rw-r--r--libs/ardour/luaproc.cc76
-rw-r--r--libs/ardour/lv2_plugin.cc2
-rw-r--r--libs/ardour/plugin.cc14
-rw-r--r--libs/ardour/plugin_insert.cc37
-rw-r--r--libs/ardour/route.cc39
12 files changed, 211 insertions, 67 deletions
diff --git a/libs/ardour/ardour/audio_unit.h b/libs/ardour/ardour/audio_unit.h
index b83798fd3e..63bd05b50d 100644
--- a/libs/ardour/ardour/audio_unit.h
+++ b/libs/ardour/ardour/audio_unit.h
@@ -74,6 +74,8 @@ class LIBARDOUR_API AUPlugin : public ARDOUR::Plugin
void set_parameter (uint32_t which, float val);
float get_parameter (uint32_t which) const;
+ PluginOutputConfiguration possible_output () const { return _output_configs; }
+
int get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const;
uint32_t nth_parameter (uint32_t which, bool& ok) const;
void activate ();
@@ -172,6 +174,7 @@ class LIBARDOUR_API AUPlugin : public ARDOUR::Plugin
AudioBufferList* buffers;
bool _has_midi_input;
bool _has_midi_output;
+ PluginOutputConfiguration _output_configs;
/* despite all the cool work that apple did on their AU preset
system, they left factory presets and user presets as two
diff --git a/libs/ardour/ardour/luaproc.h b/libs/ardour/ardour/luaproc.h
index 0f4f8d7d6d..a0f49d61bb 100644
--- a/libs/ardour/ardour/luaproc.h
+++ b/libs/ardour/ardour/luaproc.h
@@ -63,6 +63,8 @@ public:
std::string get_docs () const { return _docs; }
std::string get_parameter_docs (uint32_t) const;
+ PluginOutputConfiguration possible_output () const { return _output_configs; }
+
std::set<Evoral::Parameter> automatable() const;
void activate () { }
@@ -140,6 +142,7 @@ private:
ChanCount _configured_in;
ChanCount _configured_out;
+ PluginOutputConfiguration _output_configs;
bool _has_midi_input;
bool _has_midi_output;
diff --git a/libs/ardour/ardour/lv2_plugin.h b/libs/ardour/ardour/lv2_plugin.h
index f1907e80ae..34e68fdc7f 100644
--- a/libs/ardour/ardour/lv2_plugin.h
+++ b/libs/ardour/ardour/lv2_plugin.h
@@ -80,7 +80,7 @@ class LIBARDOUR_API LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee
int get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const;
uint32_t nth_parameter (uint32_t port, bool& ok) const;
- IOPortDescription describe_io_port (DataType dt, bool input, uint32_t id);
+ IOPortDescription describe_io_port (DataType dt, bool input, uint32_t id) const;
const void* extension_data (const char* uri) const;
diff --git a/libs/ardour/ardour/plugin.h b/libs/ardour/ardour/plugin.h
index ec749281af..d284c2620d 100644
--- a/libs/ardour/ardour/plugin.h
+++ b/libs/ardour/ardour/plugin.h
@@ -22,6 +22,7 @@
#include <boost/shared_ptr.hpp>
#include <string>
+#include <set>
#include "pbd/statefuldestructible.h"
#include "pbd/controllable.h"
@@ -54,6 +55,7 @@ class AutomationControl;
typedef boost::shared_ptr<Plugin> PluginPtr;
typedef boost::shared_ptr<PluginInfo> PluginInfoPtr;
typedef std::list<PluginInfoPtr> PluginInfoList;
+typedef std::set<uint32_t> PluginOutputConfiguration;
/** A plugin is an external module (usually 3rd party provided) loaded into Ardour
* for the purpose of digital signal processing.
@@ -124,7 +126,8 @@ class LIBARDOUR_API Plugin : public PBD::StatefulDestructible, public Latent
bool is_sidechain;
};
- virtual IOPortDescription describe_io_port (DataType dt, bool input, uint32_t id);
+ virtual IOPortDescription describe_io_port (DataType dt, bool input, uint32_t id) const;
+ virtual PluginOutputConfiguration possible_output () const;
virtual void set_automation_control (uint32_t /*port_index*/, boost::shared_ptr<ARDOUR::AutomationControl>) { }
diff --git a/libs/ardour/ardour/plugin_insert.h b/libs/ardour/ardour/plugin_insert.h
index aa1164187d..c8f0a84222 100644
--- a/libs/ardour/ardour/plugin_insert.h
+++ b/libs/ardour/ardour/plugin_insert.h
@@ -134,7 +134,8 @@ class LIBARDOUR_API PluginInsert : public Processor
}
}
- ChanCount required_buffers () const { return _required_buffers; }
+ const ChanCount& required_buffers () const { return _required_buffers; }
+ const ChanCount& preset_out () const { return _preset_out; }
// allow to override output_streams(), implies "Custom Mode"
@@ -144,6 +145,7 @@ class LIBARDOUR_API PluginInsert : public Processor
void set_outputs (const ChanCount&);
void set_strict_io (bool b);
void set_custom_cfg (bool b);
+ bool set_preset_out (const ChanCount&);
bool add_sidechain (uint32_t n_audio = 1);
bool del_sidechain ();
boost::shared_ptr<SideChain> sidechain () const { return _sidechain; }
@@ -306,6 +308,7 @@ class LIBARDOUR_API PluginInsert : public Processor
ChanCount _configured_internal; // with side-chain
ChanCount _configured_out;
ChanCount _custom_out;
+ ChanCount _preset_out;
ChanCount _cached_sidechain_pins;
ChanCount _required_buffers;
@@ -317,6 +320,7 @@ class LIBARDOUR_API PluginInsert : public Processor
bool _mapping_changed;
Match private_can_support_io_configuration (ChanCount const &, ChanCount &) const;
+ Match internal_can_support_io_configuration (ChanCount const &, ChanCount &) const;
Match automatic_can_support_io_configuration (ChanCount const &, ChanCount &) const;
/** details of the match currently being used */
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index 7e7d5d55d4..c8f6005872 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -313,6 +313,7 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
*/
bool customize_plugin_insert (boost::shared_ptr<Processor> proc, uint32_t count, ChanCount outs);
bool add_remove_sidechain (boost::shared_ptr<Processor> proc, bool);
+ bool plugin_preset_output (boost::shared_ptr<Processor> proc, ChanCount outs);
/* enable sidechain input for a given processor
*
diff --git a/libs/ardour/audio_unit.cc b/libs/ardour/audio_unit.cc
index 2ded196f52..2746f76330 100644
--- a/libs/ardour/audio_unit.cc
+++ b/libs/ardour/audio_unit.cc
@@ -1133,8 +1133,7 @@ AUPlugin::output_streams() const
bool
AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out, ChanCount* imprecise)
{
- // Note: We never attempt to multiply-instantiate plugins to meet io configurations.
-
+ _output_configs.clear ();
const int32_t audio_in = in.n_audio();
int32_t audio_out;
AUPluginInfoPtr pinfo = boost::dynamic_pointer_cast<AUPluginInfo>(get_info());
@@ -1151,7 +1150,10 @@ AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out, Cha
name(), io_configs.size(), in, out));
// preferred setting (provided by plugin_insert)
+ const int preferred_out = out.n_audio ();
audio_out = out.n_audio ();
+ bool found = false;
+ bool exact_match = false;
/* kAudioUnitProperty_SupportedNumChannels
* https://developer.apple.com/library/mac/documentation/MusicAudio/Conceptual/AudioUnitProgrammingGuide/TheAudioUnit/TheAudioUnit.html#//apple_ref/doc/uid/TP40003278-CH12-SW20
@@ -1184,35 +1186,43 @@ AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out, Cha
int32_t possible_in = i->first;
int32_t possible_out = i->second;
- if ((possible_in == audio_in) && (possible_out == audio_out)) {
+ if ((possible_in == audio_in) && (possible_out == preferred_out)) {
DEBUG_TRACE (DEBUG::AudioUnits, string_compose ("\tCHOSEN: %1 in %2 out to match in %3 out %4\n",
- possible_in, possible_out,
- in, out));
+ possible_in, possible_out,
+ in, out));
- out.set (DataType::MIDI, 0);
- out.set (DataType::AUDIO, audio_out);
-
- return true;
+ // exact match
+ _output_configs.insert (preferred_out);
+ exact_match = true;
+ found = true;
+ break;
}
}
/* now allow potentially "imprecise" matches */
- audio_out = -1;
- bool found = false;
-
+ int32_t audio_out = -1;
float penalty = 9999;
- const int preferred_out = out.n_audio ();
int used_possible_in = 0;
-#define FOUNDCFG(nch) { \
- float p = fabsf ((float)(nch) - preferred_out); \
- if ((nch) > preferred_out) { p *= 1.1; } \
- if (p < penalty) { \
- used_possible_in = possible_in; \
- audio_out = (nch); \
- penalty = p; \
- found = true; \
- } \
+#define FOUNDCFG(nch) { \
+ float p = fabsf ((float)(nch) - preferred_out); \
+ _output_configs.insert (nch); \
+ if ((nch) > preferred_out) { p *= 1.1; } \
+ if (p < penalty) { \
+ used_possible_in = possible_in; \
+ audio_out = (nch); \
+ penalty = p; \
+ found = true; \
+ } \
+}
+
+#define ANYTHINGGOES \
+ _output_configs.insert (0);
+
+#define UPTO(nch) { \
+ for (int n = 1; n < nch; ++n) { \
+ _output_configs.insert (n); \
+ } \
}
for (vector<pair<int,int> >::iterator i = io_configs.begin(); i != io_configs.end(); ++i) {
@@ -1233,12 +1243,15 @@ AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out, Cha
if (possible_out == -1) {
/* any configuration possible, provide stereo output */
FOUNDCFG (preferred_out);
+ ANYTHINGGOES;
} else if (possible_out == -2) {
/* invalid, should be (0, -1) */
FOUNDCFG (preferred_out);
+ ANYTHINGGOES;
} else if (possible_out < -2) {
/* variable number of outputs up to -N, */
FOUNDCFG (min (-possible_out, preferred_out));
+ UPTO (-possible_out);
} else {
/* exact number of outputs */
FOUNDCFG (possible_out);
@@ -1253,11 +1266,13 @@ AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out, Cha
} else if (possible_out == -2) {
/* any configuration possible, pick matching */
FOUNDCFG (preferred_out);
+ ANYTHINGGOES;
} else if (possible_out < -2) {
/* explicitly variable number of outputs, pick maximum */
FOUNDCFG (max (-possible_out, preferred_out));
/* and try min, too, in case the penalty is lower */
FOUNDCFG (min (-possible_out, preferred_out));
+ UPTO (-possible_out)
} else {
/* exact number of outputs */
FOUNDCFG (possible_out);
@@ -1268,13 +1283,16 @@ AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out, Cha
if (possible_out == -1) {
/* any configuration possible, pick matching */
FOUNDCFG (preferred_out);
+ ANYTHINGGOES;
} else if (possible_out == -2) {
/* invalid. interpret as (-1, -1) */
FOUNDCFG (preferred_out);
+ ANYTHINGGOES;
} else if (possible_out < -2) {
/* invalid, interpret as (<-2, <-2)
* variable number of outputs up to -N, */
FOUNDCFG (min (-possible_out, preferred_out));
+ UPTO (-possible_out)
} else {
/* exact number of outputs */
FOUNDCFG (possible_out);
@@ -1291,14 +1309,17 @@ AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out, Cha
if (audio_in > -possible_in && imprecise == NULL) {
/* request is too large */
} else if (possible_out == -1) {
- /* any output configuration possible, provide stereo out */
+ /* any output configuration possible */
FOUNDCFG (preferred_out);
+ ANYTHINGGOES;
} else if (possible_out == -2) {
/* invalid. interpret as (<-2, -1) */
FOUNDCFG (preferred_out);
+ ANYTHINGGOES;
} else if (possible_out < -2) {
/* variable number of outputs up to -N, */
FOUNDCFG (min (-possible_out, preferred_out));
+ UPTO (-possible_out)
} else {
/* exact number of outputs */
FOUNDCFG (possible_out);
@@ -1310,15 +1331,16 @@ AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out, Cha
if (possible_out == -1) {
/* any output configuration possible */
FOUNDCFG (preferred_out);
+ ANYTHINGGOES;
} else if (possible_out == -2) {
- /* plugins shouldn't really use (>0,-2) but might.
- * interpret as (>0,-1):
- */
+ /* plugins shouldn't really use (>0,-2), interpret as (>0,-1) */
FOUNDCFG (preferred_out);
+ ANYTHINGGOES;
} else if (possible_out < -2) {
/* > 0, < -2 is not specified
* interpret as up to -N */
FOUNDCFG (min (-possible_out, preferred_out));
+ UPTO (-possible_out)
} else {
/* exact number of outputs */
FOUNDCFG (possible_out);
@@ -1350,20 +1372,24 @@ AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out, Cha
}
}
- if (found) {
+ if (!found) {
+ DEBUG_TRACE (DEBUG::AudioUnits, string_compose ("\tFAIL: no io configs match %1\n", in));
+ return false;
+ }
+
+ if (exact_match) {
+ out.set (DataType::MIDI, 0); // currently always zero
+ out.set (DataType::AUDIO, preferred_out);
+ } else {
if (used_possible_in < -2 && audio_in == 0) {
// input-port count cannot be zero, use as many ports
// as outputs, but at most abs(possible_in)
audio_input_cnt = max (1, min (audio_out, -used_possible_in));
}
-
out.set (DataType::MIDI, 0); /// XXX
out.set (DataType::AUDIO, audio_out);
- DEBUG_TRACE (DEBUG::AudioUnits, string_compose ("\tCHOSEN: in %1 out %2\n", in, out));
- } else {
- DEBUG_TRACE (DEBUG::AudioUnits, string_compose ("\tFAIL: no io configs match %1\n", in));
- return false;
}
+ DEBUG_TRACE (DEBUG::AudioUnits, string_compose ("\tCHOSEN: in %1 out %2\n", in, out));
return true;
}
diff --git a/libs/ardour/luaproc.cc b/libs/ardour/luaproc.cc
index 31a5dd8785..baeb9409f4 100644
--- a/libs/ardour/luaproc.cc
+++ b/libs/ardour/luaproc.cc
@@ -311,6 +311,7 @@ bool
LuaProc::can_support_io_configuration (const ChanCount& in, ChanCount& out, ChanCount* imprecise)
{
// caller must hold process lock (no concurrent calls to interpreter
+ _output_configs.clear ();
if (in.n_midi() > 0 && !_has_midi_input && !imprecise) {
return false;
@@ -322,14 +323,9 @@ LuaProc::can_support_io_configuration (const ChanCount& in, ChanCount& out, Chan
return false;
}
- luabridge::LuaRef table = luabridge::getGlobal (L, "table"); //lua std lib
- luabridge::LuaRef tablesort = table["sort"];
- assert (tablesort.isFunction ());
-
luabridge::LuaRef *_iotable = NULL; // can't use reference :(
try {
luabridge::LuaRef iotable = ioconfig ();
- tablesort (iotable);
if (iotable.isTable ()) {
_iotable = new luabridge::LuaRef (iotable);
}
@@ -349,13 +345,14 @@ LuaProc::can_support_io_configuration (const ChanCount& in, ChanCount& out, Chan
return false;
}
+ bool found = false;
+ bool exact_match = false;
const int32_t audio_in = in.n_audio ();
- int32_t audio_out;
int32_t midi_out = 0; // TODO handle _has_midi_output
// preferred setting (provided by plugin_insert)
assert (out.n_audio () > 0);
- audio_out = out.n_audio ();
+ const int preferred_out = out.n_audio ();
for (luabridge::Iterator i (iotable); !i.isNil (); ++i) {
assert (i.value ().type () == LUA_TTABLE);
@@ -365,28 +362,36 @@ LuaProc::can_support_io_configuration (const ChanCount& in, ChanCount& out, Chan
int possible_out = io["audio_out"];
// exact match
- if ((possible_in == audio_in) && (possible_out == audio_out)) {
- out.set (DataType::MIDI, 0);
- out.set (DataType::AUDIO, audio_out);
- return true;
+ if ((possible_in == audio_in) && (possible_out == preferred_out)) {
+ _output_configs.insert (preferred_out);
+ exact_match = true;
+ found = true;
+ break;
}
}
/* now allow potentially "imprecise" matches */
- audio_out = -1;
- bool found = false;
-
+ int32_t audio_out = -1;
float penalty = 9999;
- const int preferred_out = out.n_audio ();
-#define FOUNDCFG(nch) { \
- float p = fabsf ((float)(nch) - preferred_out); \
- if ((nch) > preferred_out) { p *= 1.1; } \
- if (p < penalty) { \
- audio_out = (nch); \
- penalty = p; \
- found = true; \
- } \
+#define FOUNDCFG(nch) { \
+ float p = fabsf ((float)(nch) - preferred_out); \
+ _output_configs.insert (nch); \
+ if ((nch) > preferred_out) { p *= 1.1; } \
+ if (p < penalty) { \
+ audio_out = (nch); \
+ penalty = p; \
+ found = true; \
+ } \
+}
+
+#define ANYTHINGGOES \
+ _output_configs.insert (0);
+
+#define UPTO(nch) { \
+ for (int n = 1; n < nch; ++n) { \
+ _output_configs.insert (n); \
+ } \
}
for (luabridge::Iterator i (iotable); !i.isNil (); ++i) {
@@ -404,12 +409,15 @@ LuaProc::can_support_io_configuration (const ChanCount& in, ChanCount& out, Chan
if (possible_out == -1) {
/* any configuration possible, stereo output */
FOUNDCFG (preferred_out);
+ ANYTHINGGOES;
} else if (possible_out == -2) {
/* invalid, should be (0, -1) */
FOUNDCFG (preferred_out);
+ ANYTHINGGOES;
} else if (possible_out < -2) {
/* variable number of outputs up to -N, */
FOUNDCFG (min (-possible_out, preferred_out));
+ UPTO (-possible_out);
} else {
/* exact number of outputs */
FOUNDCFG (possible_out);
@@ -424,11 +432,13 @@ LuaProc::can_support_io_configuration (const ChanCount& in, ChanCount& out, Chan
} else if (possible_out == -2) {
/* any configuration possible, pick matching */
FOUNDCFG (preferred_out);
+ ANYTHINGGOES;
} else if (possible_out < -2) {
/* explicitly variable number of outputs, pick maximum */
FOUNDCFG (max (-possible_out, preferred_out));
/* and try min, too, in case the penalty is lower */
FOUNDCFG (min (-possible_out, preferred_out));
+ UPTO (-possible_out)
} else {
/* exact number of outputs */
FOUNDCFG (possible_out);
@@ -436,17 +446,19 @@ LuaProc::can_support_io_configuration (const ChanCount& in, ChanCount& out, Chan
}
if (possible_in == -2) {
-
if (possible_out == -1) {
/* any configuration possible, pick matching */
FOUNDCFG (preferred_out);
+ ANYTHINGGOES;
} else if (possible_out == -2) {
/* invalid. interpret as (-1, -1) */
FOUNDCFG (preferred_out);
+ ANYTHINGGOES;
} else if (possible_out < -2) {
/* invalid, interpret as (<-2, <-2)
* variable number of outputs up to -N, */
FOUNDCFG (min (-possible_out, preferred_out));
+ UPTO (-possible_out)
} else {
/* exact number of outputs */
FOUNDCFG (possible_out);
@@ -465,12 +477,15 @@ LuaProc::can_support_io_configuration (const ChanCount& in, ChanCount& out, Chan
} else if (possible_out == -1) {
/* any output configuration possible */
FOUNDCFG (preferred_out);
+ ANYTHINGGOES;
} else if (possible_out == -2) {
/* invalid. interpret as (<-2, -1) */
FOUNDCFG (preferred_out);
+ ANYTHINGGOES;
} else if (possible_out < -2) {
/* variable number of outputs up to -N, */
FOUNDCFG (min (-possible_out, preferred_out));
+ UPTO (-possible_out)
} else {
/* exact number of outputs */
FOUNDCFG (possible_out);
@@ -482,13 +497,16 @@ LuaProc::can_support_io_configuration (const ChanCount& in, ChanCount& out, Chan
if (possible_out == -1) {
/* any output configuration possible */
FOUNDCFG (preferred_out);
+ ANYTHINGGOES;
} else if (possible_out == -2) {
/* invalid. interpret as (>0, -1) */
FOUNDCFG (preferred_out);
+ ANYTHINGGOES;
} else if (possible_out < -2) {
/* > 0, < -2 is not specified
* interpret as up to -N */
FOUNDCFG (min (-possible_out, preferred_out));
+ UPTO (-possible_out)
} else {
/* exact number of outputs */
FOUNDCFG (possible_out);
@@ -523,13 +541,17 @@ LuaProc::can_support_io_configuration (const ChanCount& in, ChanCount& out, Chan
}
}
-
if (!found) {
return false;
}
- out.set (DataType::MIDI, midi_out); // currently always zero
- out.set (DataType::AUDIO, audio_out);
+ if (exact_match) {
+ out.set (DataType::MIDI, midi_out); // currently always zero
+ out.set (DataType::AUDIO, preferred_out);
+ } else {
+ out.set (DataType::MIDI, midi_out); // currently always zero
+ out.set (DataType::AUDIO, audio_out);
+ }
return true;
}
diff --git a/libs/ardour/lv2_plugin.cc b/libs/ardour/lv2_plugin.cc
index e13328b97b..43a4901ca7 100644
--- a/libs/ardour/lv2_plugin.cc
+++ b/libs/ardour/lv2_plugin.cc
@@ -1934,7 +1934,7 @@ LV2Plugin::get_parameter_descriptor(uint32_t which, ParameterDescriptor& desc) c
}
Plugin::IOPortDescription
-LV2Plugin::describe_io_port (ARDOUR::DataType dt, bool input, uint32_t id)
+LV2Plugin::describe_io_port (ARDOUR::DataType dt, bool input, uint32_t id) const
{
PortFlags match = 0;
switch (dt) {
diff --git a/libs/ardour/plugin.cc b/libs/ardour/plugin.cc
index 61141301cb..babc3e441f 100644
--- a/libs/ardour/plugin.cc
+++ b/libs/ardour/plugin.cc
@@ -258,7 +258,7 @@ Plugin::input_streams () const
}
Plugin::IOPortDescription
-Plugin::describe_io_port (ARDOUR::DataType dt, bool input, uint32_t id)
+Plugin::describe_io_port (ARDOUR::DataType dt, bool input, uint32_t id) const
{
std::stringstream ss;
switch (dt) {
@@ -278,12 +278,22 @@ Plugin::describe_io_port (ARDOUR::DataType dt, bool input, uint32_t id)
ss << _("Out") << " ";
}
- ss << id;
+ ss << (id + 1);
Plugin::IOPortDescription iod (ss.str());
return iod;
}
+PluginOutputConfiguration
+Plugin::possible_output () const
+{
+ PluginOutputConfiguration oc;
+ if (_info) {
+ oc.insert (_info->n_outputs.n_audio ());
+ }
+ return oc;
+}
+
const Plugin::PresetRecord *
Plugin::preset_by_label (const string& label)
{
diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc
index 2005d5b2e2..646bf5e63a 100644
--- a/libs/ardour/plugin_insert.cc
+++ b/libs/ardour/plugin_insert.cc
@@ -160,6 +160,17 @@ PluginInsert::set_custom_cfg (bool b)
}
bool
+PluginInsert::set_preset_out (const ChanCount& c)
+{
+ bool changed = _preset_out != c;
+ _preset_out = c;
+ if (changed && !_custom_cfg) {
+ PluginConfigChanged (); /* EMIT SIGNAL */
+ }
+ return changed;
+}
+
+bool
PluginInsert::add_sidechain (uint32_t n_audio)
{
// caller must hold process lock
@@ -1383,6 +1394,8 @@ PluginInsert::configure_io (ChanCount in, ChanCount out)
ChanCount dout (in); // hint
if (_custom_cfg) {
dout = _custom_out;
+ } else if (_preset_out.n_audio () > 0) {
+ dout.set (DataType::AUDIO, _preset_out.n_audio ());
} else if (dout.n_midi () > 0 && dout.n_audio () == 0) {
dout.set (DataType::AUDIO, 2);
}
@@ -1390,7 +1403,6 @@ PluginInsert::configure_io (ChanCount in, ChanCount out)
ChanCount useins;
bool const r = _plugins.front()->can_support_io_configuration (in, dout, &useins);
assert (r);
- assert (dout.n_audio() <= out.n_audio()); // sans midi bypass
if (useins.n_audio() == 0) {
useins = in;
}
@@ -1529,12 +1541,29 @@ PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
return private_can_support_io_configuration (in, out).method != Impossible;
}
+PluginInsert::Match
+PluginInsert::private_can_support_io_configuration (ChanCount const& in, ChanCount& out) const
+{
+ if (!_custom_cfg && _preset_out.n_audio () > 0) {
+ // preseed hint (for variable i/o)
+ out.set (DataType::AUDIO, _preset_out.n_audio ());
+ }
+
+ Match rv = internal_can_support_io_configuration (in, out);
+
+ if (!_custom_cfg && _preset_out.n_audio () > 0) {
+ DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("using output preset: %1 %2\n", name(), _preset_out));
+ out.set (DataType::AUDIO, _preset_out.n_audio ());
+ }
+ return rv;
+}
+
/** A private version of can_support_io_configuration which returns the method
* by which the configuration can be matched, rather than just whether or not
* it can be.
*/
PluginInsert::Match
-PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
+PluginInsert::internal_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
{
if (_plugins.empty()) {
return Match();
@@ -1848,6 +1877,7 @@ PluginInsert::state (bool full)
* in case the plugin goes missing) */
node.add_child_nocopy (* _configured_in.state (X_("ConfiguredInput")));
node.add_child_nocopy (* _configured_out.state (X_("ConfiguredOutput")));
+ node.add_child_nocopy (* _preset_out.state (X_("PresetOutput")));
/* save custom i/o config */
node.add_property("custom", _custom_cfg ? "yes" : "no");
@@ -2121,6 +2151,9 @@ PluginInsert::set_state(const XMLNode& node, int version)
if ((*i)->name() == X_("ConfiguredOutput")) {
_custom_out = ChanCount(**i);
}
+ if ((*i)->name() == X_("PresetOutput")) {
+ _preset_out = ChanCount(**i);
+ }
if (strncmp ((*i)->name ().c_str(), X_("InputMap-"), 9) == 0) {
long pc = atol (&((*i)->name().c_str()[9]));
if (pc >=0 && pc <= get_count()) {
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 51fc33a395..7ef2a62a24 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -2506,6 +2506,45 @@ Route::add_remove_sidechain (boost::shared_ptr<Processor> proc, bool add)
}
bool
+Route::plugin_preset_output (boost::shared_ptr<Processor> proc, ChanCount outs)
+{
+ boost::shared_ptr<PluginInsert> pi;
+ if ((pi = boost::dynamic_pointer_cast<PluginInsert>(proc)) == 0) {
+ return false;
+ }
+
+ {
+ Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
+ ProcessorList::iterator i = find (_processors.begin(), _processors.end(), proc);
+ if (i == _processors.end ()) {
+ return false;
+ }
+ }
+
+ {
+ Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
+ Glib::Threads::RWLock::WriterLock lm (_processor_lock);
+
+ const ChanCount& old (pi->preset_out ());
+ if (!pi->set_preset_out (outs)) {
+ return true; // no change, OK
+ }
+
+ list<pair<ChanCount, ChanCount> > c = try_configure_processors_unlocked (n_inputs (), 0);
+ if (c.empty()) {
+ /* not possible */
+ pi->set_preset_out (old);
+ return false;
+ }
+ configure_processors_unlocked (0);
+ }
+
+ processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
+ _session.set_dirty ();
+ return true;
+}
+
+bool
Route::reset_plugin_insert (boost::shared_ptr<Processor> proc)
{
ChanCount unused;