change API for GainControl, VCA and VCAManager
[ardour.git] / libs / ardour / plugin_insert.cc
index 79c4c5de6140e318a9bd062c8e65525d066a255f..451f801f1d77e1d879e86336d42c8e18eb400966 100644 (file)
@@ -375,6 +375,35 @@ PluginInsert::needs_midi_input() const
        return pip->n_inputs.n_midi() != 0 && pip->n_outputs.n_audio() != 0;
 }
 
+bool
+PluginInsert::has_output_presets (ChanCount in, ChanCount out)
+{
+       if (!_configured && _plugins[0]->get_info ()->reconfigurable_io ()) {
+               // collect possible configurations, prefer given in/out
+               _plugins[0]->can_support_io_configuration (in, out);
+       }
+
+       PluginOutputConfiguration ppc (_plugins[0]->possible_output ());
+
+       if (ppc.size () == 0) {
+               return false;
+       }
+       if (!strict_io () && ppc.size () == 1) {
+               return false;
+       }
+
+       if (strict_io () && ppc.size () == 1) {
+               // "stereo" is currently preferred default for instruments
+               if (ppc.find (2) != ppc.end ()) {
+                       return false;
+               }
+       }
+       if (!needs_midi_input ()) {
+                       return false;
+       }
+       return true;
+}
+
 void
 PluginInsert::create_automatable_parameters ()
 {
@@ -631,10 +660,10 @@ PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t of
                //std::cerr << "               streams " << internal_input_streams().n_audio() << std::endl;
                //std::cerr << "filling buffer with " << collect_signal_nframes << " frames at " << _signal_analysis_collected_nframes << std::endl;
 
-               _signal_analysis_inputs.set_count(internal_input_streams());
+               _signal_analysis_inputs.set_count(input_streams());
 
-               for (uint32_t i = 0; i < internal_input_streams().n_audio(); ++i) {
-                       _signal_analysis_inputs.get_audio(i).read_from(
+               for (uint32_t i = 0; i < input_streams().n_audio(); ++i) {
+                       _signal_analysis_inputs.get_audio(i).read_from (
                                bufs.get_audio(i),
                                collect_signal_nframes,
                                _signal_analysis_collected_nframes); // offset is for target buffer
@@ -766,9 +795,9 @@ PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t of
                //std::cerr << "       output, bufs " << bufs.count().n_audio() << " count,  " << bufs.available().n_audio() << " available" << std::endl;
                //std::cerr << "               streams " << internal_output_streams().n_audio() << std::endl;
 
-               _signal_analysis_outputs.set_count(internal_output_streams());
+               _signal_analysis_outputs.set_count(output_streams());
 
-               for (uint32_t i = 0; i < internal_output_streams().n_audio(); ++i) {
+               for (uint32_t i = 0; i < output_streams().n_audio(); ++i) {
                        _signal_analysis_outputs.get_audio(i).read_from(
                                bufs.get_audio(i),
                                collect_signal_nframes,
@@ -1163,6 +1192,20 @@ PluginInsert::set_thru_map (ChanMapping m) {
        }
 }
 
+bool
+PluginInsert::pre_seed (const ChanCount& in, const ChanCount& out,
+               const ChanMapping& im, const ChanMapping& om, const ChanMapping& tm)
+{
+       if (_configured) { return false; }
+       _configured_in = in;
+       _configured_out = out;
+       _in_map[0] = im;
+       _out_map[0] = om;
+       _thru_map = tm;
+       _maps_from_state = in.n_total () > 0 && out.n_total () > 0;
+       return true;
+}
+
 ChanMapping
 PluginInsert::input_map () const
 {
@@ -1287,6 +1330,30 @@ PluginInsert::check_inplace ()
                        inplace_ok = false;
                }
        }
+
+       if (inplace_ok) {
+               /* check if every output is fed by the corresponding input
+                *
+                * this prevents  in-port 1 -> sink-pin 2  ||  source-pin 1 -> out port 1, source-pin 2 -> out port 2
+                * (with in-place,  source-pin 1 -> out port 1 overwrites in-port 1)
+                *
+                * but allows     in-port 1 -> sink-pin 2  ||  source-pin 2 -> out port 1
+                */
+               ChanMapping in_map (input_map ());
+               const ChanMapping::Mappings out_m (output_map ().mappings ());
+               for (ChanMapping::Mappings::const_iterator t = out_m.begin (); t != out_m.end () && inplace_ok; ++t) {
+                       for (ChanMapping::TypeMapping::const_iterator c = (*t).second.begin (); c != (*t).second.end () ; ++c) {
+                               /* src-pin: c->first, out-port: c->second */
+                               bool valid;
+                               uint32_t in_port = in_map.get (t->first, c->first, &valid);
+                               if (valid && in_port != c->second) {
+                                       inplace_ok = false;
+                                       break;
+                               }
+                       }
+               }
+       }
+
        DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: %2\n", name(), inplace_ok ? "In-Place" : "No Inplace Processing"));
        return !inplace_ok; // no-inplace
 }
@@ -1697,10 +1764,10 @@ PluginInsert::configure_io (ChanCount in, ChanCount out)
        // buffers and the analyser makes sure it gets enough data for the
        // analysis window
        session().ensure_buffer_set (_signal_analysis_inputs, in);
-       //_signal_analysis_inputs.set_count (in);
+       _signal_analysis_inputs.set_count (in);
 
        session().ensure_buffer_set (_signal_analysis_outputs, out);
-       //_signal_analysis_outputs.set_count (out);
+       _signal_analysis_outputs.set_count (out);
 
        // std::cerr << "set counts to i" << in.n_audio() << "/o" << out.n_audio() << std::endl;
 
@@ -1834,6 +1901,8 @@ PluginInsert::internal_can_support_io_configuration (ChanCount const & inx, Chan
                        // houston, we have a problem.
                        return Match (Impossible, 0);
                }
+               // midi bypass
+               if (inx.n_midi () > 0 && out.n_midi () == 0) { out.set (DataType::MIDI, 1); }
                return Match (Delegate, 1, _strict_io);
        }
 
@@ -1902,6 +1971,8 @@ PluginInsert::automatic_can_support_io_configuration (ChanCount const & inx, Cha
                if (!r) {
                        return Match (Impossible, 0);
                }
+               // midi bypass
+               if (in.n_midi () > 0 && out.n_midi () == 0) { out.set (DataType::MIDI, 1); }
                return Match (Delegate, 1);
        }
 
@@ -2698,8 +2769,8 @@ PluginInsert::collect_signal_for_analysis (framecnt_t nframes)
 {
        // called from outside the audio thread, so this should be safe
        // only do audio as analysis is (currently) only for audio plugins
-       _signal_analysis_inputs.ensure_buffers(  DataType::AUDIO, internal_input_streams().n_audio(),  nframes);
-       _signal_analysis_outputs.ensure_buffers( DataType::AUDIO, internal_output_streams().n_audio(), nframes);
+       _signal_analysis_inputs.ensure_buffers (DataType::AUDIO, input_streams().n_audio(),  nframes);
+       _signal_analysis_outputs.ensure_buffers (DataType::AUDIO, output_streams().n_audio(), nframes);
 
        _signal_analysis_collected_nframes   = 0;
        _signal_analysis_collect_nframes_max = nframes;