update processor in-place mode when pin-mapping changes
[ardour.git] / libs / ardour / plugin_insert.cc
index dd99e981ef097268e9034e3a1a75103f17439548..cdf1e600a8451bfbf6f6e93e4b0a19b2347a29f1 100644 (file)
@@ -294,12 +294,22 @@ PluginInsert::internal_input_streams() const
 ChanCount
 PluginInsert::natural_output_streams() const
 {
+#ifdef MIXBUS
+       if (is_channelstrip ()) {
+               return _configured_out;
+       }
+#endif
        return _plugins[0]->get_info()->n_outputs;
 }
 
 ChanCount
 PluginInsert::natural_input_streams() const
 {
+#ifdef MIXBUS
+       if (is_channelstrip ()) {
+               return _configured_in;
+       }
+#endif
        return _plugins[0]->get_info()->n_inputs;
 }
 
@@ -458,8 +468,13 @@ PluginInsert::flush ()
 void
 PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t offset, bool with_auto, framepos_t now)
 {
+       // TODO: atomically copy maps & _no_inplace
        PinMappings in_map (_in_map);
        PinMappings out_map (_out_map);
+       if (_mapping_changed) {
+               _no_inplace = check_inplace ();
+               _mapping_changed = false;
+       }
 
 #if 1
        // TODO optimize special case.
@@ -938,6 +953,7 @@ PluginInsert::set_input_map (uint32_t num, ChanMapping m) {
                sanitize_maps ();
                if (changed) {
                        PluginMapChanged (); /* EMIT SIGNAL */
+                       _mapping_changed = true;
                }
        }
 }
@@ -950,6 +966,7 @@ PluginInsert::set_output_map (uint32_t num, ChanMapping m) {
                sanitize_maps ();
                if (changed) {
                        PluginMapChanged (); /* EMIT SIGNAL */
+                       _mapping_changed = true;
                }
        }
 }
@@ -1019,6 +1036,24 @@ PluginInsert::is_channelstrip () const {
 }
 #endif
 
+bool
+PluginInsert::check_inplace ()
+{
+       // auto-detect if inplace processing is possible
+       bool inplace_ok = true;
+       for (uint32_t pc = 0; pc < get_count() && inplace_ok ; ++pc) {
+               if (!_in_map[pc].is_monotonic ()) {
+                       inplace_ok = false;
+               }
+               if (!_out_map[pc].is_monotonic ()) {
+                       inplace_ok = false;
+               }
+       }
+       bool no_inplace = !inplace_ok || _plugins.front()->inplace_broken ();
+       DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1 %2\n", name(), no_inplace ? "No Inplace Processing" : "In-Place"));
+       return no_inplace;
+}
+
 bool
 PluginInsert::sanitize_maps ()
 {
@@ -1127,6 +1162,7 @@ PluginInsert::reset_map (bool emit)
        }
        if (emit) {
                PluginMapChanged (); /* EMIT SIGNAL */
+               _mapping_changed = true;
        }
        return true;
 }
@@ -1229,6 +1265,9 @@ PluginInsert::configure_io (ChanCount in, ChanCount out)
        } else if (_match.custom_cfg && _configured) {
                mapping_changed = sanitize_maps ();
        } else {
+#ifdef MIXBUS
+               if (is_channelstrip ()) { _maps_from_state = false; }
+#endif
                if (_maps_from_state) {
                        _maps_from_state = false;
                        mapping_changed = true;
@@ -1263,17 +1302,9 @@ PluginInsert::configure_io (ChanCount in, ChanCount out)
 #endif
        }
 
-       // auto-detect if inplace processing is possible
-       bool inplace_ok = true;
-       for (uint32_t pc = 0; pc < get_count() && inplace_ok ; ++pc) {
-               if (!_in_map[pc].is_monotonic ()) {
-                       inplace_ok = false;
-               }
-               if (!_out_map[pc].is_monotonic ()) {
-                       inplace_ok = false;
-               }
-       }
-       _no_inplace = !inplace_ok || _plugins.front()->inplace_broken ();
+       _no_inplace = check_inplace ();
+       _mapping_changed = false;
+       DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1 %2\n", name(), _no_inplace ? "No Inplace Processing" : "In-Place"));
 
        if (old_in != in || old_out != out || old_internal != _configured_internal
                        || (old_match.method != _match.method && (old_match.method == Split || _match.method == Split))
@@ -1325,6 +1356,13 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanC
                return Match();
        }
 
+#ifdef MIXBUS
+       if (is_channelstrip ()) {
+               out = inx;
+               return Match (ExactMatch, 1);
+       }
+#endif
+
        /* if a user specified a custom cfg, so be it. */
        if (_custom_cfg) {
                out = _custom_out;
@@ -1380,12 +1418,6 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanC
                return m;
        }
 
-#ifdef MIXBUS
-       if (is_channelstrip ()) {
-               return Match (Replicate, 1, _strict_io);
-       }
-#endif
-
        ChanCount ns_inputs  = inputs - sidechain_input_pins ();
 
        DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("resolving 'Impossible' match for %1\n", name()));
@@ -1514,11 +1546,6 @@ PluginInsert::automatic_can_support_io_configuration (ChanCount const & inx, Cha
 
        uint32_t f             = 0;
        bool     can_replicate = true;
-#ifdef MIXBUS
-       if (is_channelstrip ()) {
-               can_replicate = false;
-       }
-#endif
        for (DataType::iterator t = DataType::begin(); t != DataType::end() && can_replicate; ++t) {
 
                // ignore side-chains