summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2016-04-02 03:19:02 +0200
committerRobin Gareus <robin@gareus.org>2016-04-02 03:19:02 +0200
commit2f62309d447d9f9426a7624b454aef06a58e6656 (patch)
treec57f7171aabca684a0b57db6896ab3125e99a38c
parent46ca35ce7ef4bd73af50466598bcc8431b01ef7a (diff)
keep port maps sane and properly detect changes
-rw-r--r--libs/ardour/ardour/plugin_insert.h1
-rw-r--r--libs/ardour/plugin_insert.cc87
2 files changed, 62 insertions, 26 deletions
diff --git a/libs/ardour/ardour/plugin_insert.h b/libs/ardour/ardour/plugin_insert.h
index 3933f352e5..2b1eddc905 100644
--- a/libs/ardour/ardour/plugin_insert.h
+++ b/libs/ardour/ardour/plugin_insert.h
@@ -92,6 +92,7 @@ class LIBARDOUR_API PluginInsert : public Processor
void set_input_map (uint32_t, ChanMapping);
void set_output_map (uint32_t, ChanMapping);
bool reset_map (bool emit = true);
+ bool sanitize_maps ();
// these are ports visible on the outside
ChanCount output_streams() const;
diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc
index 17625ff919..675c172fcf 100644
--- a/libs/ardour/plugin_insert.cc
+++ b/libs/ardour/plugin_insert.cc
@@ -879,6 +879,7 @@ PluginInsert::set_input_map (uint32_t num, ChanMapping m) {
if (num < _in_map.size()) {
bool changed = _in_map[num] != m;
_in_map[num] = m;
+ sanitize_maps ();
if (changed) {
PluginMapChanged (); /* EMIT SIGNAL */
}
@@ -890,6 +891,7 @@ PluginInsert::set_output_map (uint32_t num, ChanMapping m) {
if (num < _out_map.size()) {
bool changed = _out_map[num] != m;
_out_map[num] = m;
+ sanitize_maps ();
if (changed) {
PluginMapChanged (); /* EMIT SIGNAL */
}
@@ -944,6 +946,63 @@ PluginInsert::has_midi_bypass () const
}
bool
+PluginInsert::sanitize_maps ()
+{
+ bool changed = false;
+ /* strip dead wood */
+ PinMappings new_ins;
+ PinMappings new_outs;
+ for (uint32_t pc = 0; pc < get_count(); ++pc) {
+ ChanMapping new_in;
+ ChanMapping new_out;
+ for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
+ for (uint32_t i = 0; i < natural_input_streams().get (*t); ++i) {
+ bool valid;
+ uint32_t idx = _in_map[pc].get (*t, i, &valid);
+ if (valid && idx <= _configured_in.get (*t)) {
+ new_in.set (*t, i, idx);
+ }
+ }
+ for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
+ bool valid;
+ uint32_t idx = _out_map[pc].get (*t, o, &valid);
+ if (valid && idx <= _configured_out.get (*t)) {
+ new_out.set (*t, o, idx);
+ }
+ }
+ }
+ if (_in_map[pc] != new_in || _out_map[pc] != new_out) {
+ changed = true;
+ }
+ new_ins[pc] = new_in;
+ new_outs[pc] = new_out;
+ }
+ /* prevent dup output assignments */
+ for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
+ for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
+ bool mapped = false;
+ for (uint32_t pc = 0; pc < get_count(); ++pc) {
+ bool valid;
+ uint32_t idx = new_outs[pc].get_src (*t, o, &valid);
+ if (valid && mapped) {
+ new_outs[pc].unset (*t, idx);
+ } else if (valid) {
+ mapped = true;
+ }
+ }
+ }
+ }
+
+ if (_in_map != new_ins || _out_map != new_outs) {
+ changed = true;
+ }
+ _in_map = new_ins;
+ _out_map = new_outs;
+
+ return changed;
+}
+
+bool
PluginInsert::reset_map (bool emit)
{
uint32_t pc = 0;
@@ -1056,36 +1115,12 @@ PluginInsert::configure_io (ChanCount in, ChanCount out)
) {
/* If the configuraton has not changed, keep the mapping */
} else if (_match.custom_cfg && _configured) {
- /* strip dead wood */
- for (uint32_t pc = 0; pc < get_count(); ++pc) {
- ChanMapping new_in;
- ChanMapping new_out;
- for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
- for (uint32_t i = 0; i < natural_input_streams().get (*t); ++i) {
- bool valid;
- uint32_t idx = _in_map[pc].get (*t, i, &valid);
- if (valid && idx <= in.get (*t)) {
- new_in.set (*t, i, idx);
- }
- }
- for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
- bool valid;
- uint32_t idx = _out_map[pc].get (*t, o, &valid);
- if (valid && idx <= out.get (*t)) {
- new_out.set (*t, o, idx);
- }
- }
- }
- if (_in_map[pc] != new_in || _out_map[pc] != new_out) {
- mapping_changed = true;
- }
- _in_map[pc] = new_in;
- _out_map[pc] = new_out;
- }
+ mapping_changed = sanitize_maps ();
} else {
if (_maps_from_state) {
_maps_from_state = false;
mapping_changed = true;
+ sanitize_maps ();
} else {
/* generate a new mapping */
mapping_changed = reset_map (false);