1 /*
2  * Copyright (C) 2000-2017 Paul Davis <paul@linuxaudiosystems.com>
3  * Copyright (C) 2007-2014 David Robillard <d@drobilla.net>
4  * Copyright (C) 2008-2009 Sampo Savolainen <v2@iki.fi>
5  * Copyright (C) 2009-2012 Carl Hetherington <carl@carlh.net>
6  * Copyright (C) 2013-2019 Robin Gareus <robin@gareus.org>
7  * Copyright (C) 2018 Johannes Mueller <github@johannes-mueller.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23 
24 #ifndef __ardour_plugin_insert_h__
25 #define __ardour_plugin_insert_h__
26 
27 #include <vector>
28 #include <string>
29 
30 #include <boost/weak_ptr.hpp>
31 
32 #include "pbd/stack_allocator.h"
33 #include "pbd/timing.h"
34 #include "pbd/g_atomic_compat.h"
35 
36 #include "ardour/ardour.h"
37 #include "ardour/libardour_visibility.h"
38 #include "ardour/chan_mapping.h"
39 #include "ardour/fixed_delay.h"
40 #include "ardour/io.h"
41 #include "ardour/types.h"
42 #include "ardour/parameter_descriptor.h"
43 #include "ardour/plugin.h"
44 #include "ardour/processor.h"
45 #include "ardour/readonly_control.h"
46 #include "ardour/sidechain.h"
47 #include "ardour/automation_control.h"
48 
49 class XMLNode;
50 
51 namespace ARDOUR {
52 
53 class Session;
54 class Route;
55 class Plugin;
56 
57 /** Plugin inserts: send data through a plugin
58  */
59 class LIBARDOUR_API PluginInsert : public Processor
60 {
61 public:
62 	PluginInsert (Session&, boost::shared_ptr<Plugin> = boost::shared_ptr<Plugin>());
63 	~PluginInsert ();
64 
65 	void drop_references ();
66 
67 	static const std::string port_automation_node_name;
68 
69 	int set_state(const XMLNode&, int version);
70 	void update_id (PBD::ID);
71 	void set_owner (SessionObject*);
72 	void set_state_dir (const std::string& d = "");
73 
74 	void run (BufferSet& in, samplepos_t start_sample, samplepos_t end_sample, double speed, pframes_t nframes, bool);
75 	void silence (samplecnt_t nframes, samplepos_t start_sample);
76 
77 	void activate ();
78 	void deactivate ();
79 	void flush ();
80 
81 	void enable (bool yn);
82 	bool enabled () const;
83 	bool bypassable () const;
84 
85 	bool reset_parameters_to_default ();
86 	bool can_reset_all_parameters ();
87 
88 	bool write_immediate_event (Evoral::EventType event_type, size_t size, const uint8_t* buf);
89 
90 	void automation_run (samplepos_t, pframes_t, bool only_active = false);
91 	bool find_next_event (double, double, Evoral::ControlEvent&, bool only_active = true) const;
92 
93 	int set_block_size (pframes_t nframes);
94 
input_map(uint32_t num)95 	ChanMapping input_map (uint32_t num) const {
96 		if (num < _in_map.size()) {
97 			return _in_map.find (num)->second;
98 		} else {
99 			return ChanMapping ();
100 		}
101 	}
102 
output_map(uint32_t num)103 	ChanMapping output_map (uint32_t num) const {
104 		if (num < _out_map.size()) {
105 			return _out_map.find (num)->second;
106 		} else {
107 			return ChanMapping ();
108 		}
109 	}
110 
thru_map()111 	ChanMapping thru_map () const {
112 		return _thru_map;
113 	}
114 
115 	bool pre_seed (const ChanCount&, const ChanCount&, const ChanMapping&, const ChanMapping&, const ChanMapping&);
116 
117 	ChanMapping input_map () const; ///< combined (all instances) input map
118 	ChanMapping no_sc_input_map () const; ///< combined (all instances) input map w/o sidechain sinks
119 	ChanMapping output_map () const; ///< combined (all instances) output map
120 	bool has_midi_bypass () const;
121 	bool has_midi_thru () const;
inplace()122 	bool inplace () const { return ! _no_inplace; }
123 
124 	bool is_channelstrip () const;
125 
126 	void set_input_map (uint32_t, ChanMapping);
127 	void set_output_map (uint32_t, ChanMapping);
128 	void set_thru_map (ChanMapping);
129 	bool reset_map (bool emit = true);
configured()130 	bool configured () const { return _configured; }
131 
132 	// these are ports visible on the outside
133 	ChanCount output_streams() const;
134 	ChanCount input_streams() const;
135 	ChanCount internal_streams() const; // with side-chain
136 
137 	// actual ports of all plugins.
138 	// n * natural_i/o or result of reconfigurable i/o
139 	ChanCount internal_output_streams() const;
140 	ChanCount internal_input_streams() const;
141 
142 	// a single plugin's internal i/o
143 	ChanCount natural_output_streams() const;
144 	ChanCount natural_input_streams() const;
145 
146 	/** plugin ports marked as sidechain */
147 	ChanCount sidechain_input_pins() const;
148 
149 	/** Plugin-Insert IO sidechain ports */
sidechain_input_ports()150 	ChanCount sidechain_input_ports() const {
151 		if (_sidechain) {
152 			return _sidechain->input ()->n_ports ();
153 		} else {
154 			return ChanCount ();
155 		}
156 	}
157 
required_buffers()158 	const ChanCount& required_buffers () const { return _required_buffers; }
preset_out()159 	const ChanCount& preset_out () const { return _preset_out; }
160 
161 	// allow to override output_streams(), implies "Custom Mode"
162 
163 	// only the owning route may call these (with process lock held)
164 	// route is not a friend class, it owns us
165 	bool set_count      (uint32_t num);
166 	void set_sinks      (const ChanCount&); // reconfigurable I/O ONLY
167 	void set_outputs    (const ChanCount&);
168 	void set_strict_io  (bool b);
169 	void set_custom_cfg (bool b);
170 	bool set_preset_out (const ChanCount&);
171 	bool add_sidechain  (uint32_t n_audio = 1, uint32_t n_midi = 0);
172 	bool del_sidechain ();
173 	void update_sidechain_name ();
sidechain()174 	boost::shared_ptr<SideChain> sidechain () const { return _sidechain; }
175 	// end C++ class slavery!
176 
get_count()177 	uint32_t get_count  () const { return _plugins.size(); }
strict_io()178 	bool     strict_io  () const { return _strict_io; }
custom_cfg()179 	bool     custom_cfg () const { return _custom_cfg; }
180 
181 	bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
182 	bool configure_io (ChanCount in, ChanCount out);
183 
184 	bool has_no_inputs() const;
185 	bool has_no_audio_inputs() const;
186 
187 	bool is_instrument () const;
188 
189 	bool has_output_presets (
190 			ChanCount in = ChanCount (DataType::MIDI, 1),
191 			ChanCount out = ChanCount (DataType::AUDIO, 2)
192 			);
193 
194 	void realtime_handle_transport_stopped ();
195 	void realtime_locate (bool);
196 	void monitoring_changed ();
197 
198 	bool load_preset (Plugin::PresetRecord);
199 
200 	bool provides_stats () const;
201 	bool get_stats (PBD::microseconds_t& min, PBD::microseconds_t& max, double& avg, double& dev) const;
202 	void clear_stats ();
203 
204 	/** A control that manipulates a plugin parameter (control port). */
205 	struct PluginControl : public AutomationControl
206 	{
207 		PluginControl (PluginInsert*                     p,
208 		               const Evoral::Parameter&          param,
209 		               const ParameterDescriptor&        desc,
210 		               boost::shared_ptr<AutomationList> list=boost::shared_ptr<AutomationList>());
211 
212 		double get_value (void) const;
213 		void catch_up_with_external_value (double val);
214 		XMLNode& get_state();
215 		std::string get_user_string() const;
216 
217 	private:
218 		PluginInsert* _plugin;
219 		void actually_set_value (double val, PBD::Controllable::GroupControlDisposition group_override);
220 	};
221 
222 	/** A control that manipulates a plugin property (message). */
223 	struct PluginPropertyControl : public AutomationControl
224 	{
225 		PluginPropertyControl (PluginInsert*                     p,
226 		                       const Evoral::Parameter&          param,
227 		                       const ParameterDescriptor&        desc,
228 		                       boost::shared_ptr<AutomationList> list=boost::shared_ptr<AutomationList>());
229 
230 		double get_value (void) const;
231 		XMLNode& get_state();
232 	protected:
233 		void actually_set_value (double value, PBD::Controllable::GroupControlDisposition);
234 
235 	private:
236 		PluginInsert* _plugin;
237 		Variant       _value;
238 	};
239 
240 	boost::shared_ptr<Plugin> plugin(uint32_t num=0) const {
241 		if (num < _plugins.size()) {
242 			return _plugins[num];
243 		} else {
244 			return _plugins[0]; // we always have one
245 		}
246 	}
247 
248 	samplecnt_t plugin_latency () const;
249 
has_sidechain()250 	bool has_sidechain () const {
251 		return _sidechain ? true : false;
252 	}
253 
sidechain_input()254 	boost::shared_ptr<IO> sidechain_input () const {
255 		if (_sidechain) {
256 			return _sidechain->input ();
257 		}
258 		return boost::shared_ptr<IO> ();
259 	}
260 
261 	PluginType type () const;
262 
263 	boost::shared_ptr<ReadOnlyControl> control_output (uint32_t) const;
264 
265 	std::string describe_parameter (Evoral::Parameter param);
266 
267 	samplecnt_t signal_latency () const;
268 
269 	boost::shared_ptr<Plugin> get_impulse_analysis_plugin();
270 
271 	void collect_signal_for_analysis (samplecnt_t nframes);
272 
strict_io_configured()273 	bool strict_io_configured () const {
274 		return _match.strict_io;
275 	}
276 
splitting()277 	bool splitting () const {
278 		return _match.method == Split;
279 	}
280 
configured_io(ChanCount & in,ChanCount & out)281 	void configured_io (ChanCount &in, ChanCount &out) const {
282 		in = _configured_in;
283 		out = _configured_out;
284 	}
285 
286 	PBD::Signal2<void,BufferSet*, BufferSet*> AnalysisDataGathered;
287 	PBD::Signal0<void> PluginIoReConfigure;
288 	PBD::Signal0<void> PluginMapChanged;
289 	PBD::Signal0<void> PluginConfigChanged;
290 
291 	/** Enumeration of the ways in which we can match our insert's
292 	 *  IO to that of the plugin(s).
293 	 */
294 	enum MatchingMethod {
295 		Impossible,  ///< we can't
296 		Delegate,    ///< we are delegating to the plugin, and it can handle it
297 		NoInputs,    ///< plugin has no inputs, so anything goes
298 		ExactMatch,  ///< our insert's inputs are the same as the plugin's
299 		Replicate,   ///< we have multiple instances of the plugin
300 		Split,       ///< we copy one of our insert's inputs to multiple plugin inputs
301 		Hide,        ///< we `hide' some of the plugin's inputs by feeding them silence
302 	};
303 
304 	/** Description of how we can match our plugin's IO to our own insert IO */
305 	struct Match {
MatchMatch306 		Match () : method (Impossible), plugins (0), strict_io (false), custom_cfg (false) {}
307 		Match (MatchingMethod m, int32_t p,
308 				bool strict = false, bool custom = false, ChanCount h = ChanCount ())
methodMatch309 			: method (m), plugins (p), hide (h), strict_io (strict), custom_cfg (custom) {}
310 
311 		MatchingMethod method; ///< method to employ
312 		int32_t plugins;       ///< number of copies of the plugin that we need
313 		ChanCount hide;        ///< number of channels to hide
314 		bool strict_io;        ///< force in == out
315 		bool custom_cfg;       ///< custom config (if not strict)
316 	};
317 
318 protected:
319 	XMLNode& state ();
320 
321 private:
322 	/* disallow copy construction */
323 	PluginInsert (const PluginInsert&);
324 
325 	void parameter_changed_externally (uint32_t, float);
326 
327 	void set_parameter (Evoral::Parameter param, float val, sampleoffset_t);
328 
329 	float default_parameter_value (const Evoral::Parameter& param);
330 
331 	typedef std::vector<boost::shared_ptr<Plugin> > Plugins;
332 	Plugins _plugins;
333 
334 	boost::shared_ptr<SideChain> _sidechain;
335 	uint32_t _sc_playback_latency;
336 	uint32_t _sc_capture_latency;
337 	uint32_t _plugin_signal_latency;
338 
339 	boost::weak_ptr<Plugin> _impulseAnalysisPlugin;
340 
341 	samplecnt_t _signal_analysis_collect_nsamples;
342 	samplecnt_t _signal_analysis_collect_nsamples_max;
343 
344 	BufferSet _signal_analysis_inputs;
345 	BufferSet _signal_analysis_outputs;
346 
347 	FixedDelay _delaybuffers;
348 
349 	ChanCount _configured_in;
350 	ChanCount _configured_internal; // with side-chain
351 	ChanCount _configured_out;
352 	ChanCount _custom_out;
353 	ChanCount _custom_sinks;
354 	ChanCount _preset_out;
355 	ChanCount _cached_sidechain_pins;
356 	ChanCount _required_buffers;
357 
358 	bool _configured;
359 	bool _no_inplace;
360 	bool _strict_io;
361 	bool _custom_cfg;
362 	bool _maps_from_state;
363 	bool _mapping_changed;
364 
365 	Match private_can_support_io_configuration (ChanCount const &, ChanCount &) const;
366 	Match internal_can_support_io_configuration (ChanCount const &, ChanCount &) const;
367 	Match automatic_can_support_io_configuration (ChanCount const &, ChanCount &) const;
368 
369 	/** details of the match currently being used */
370 	Match _match;
371 
372 	/* ordered map [plugin instance ID] => ARDOUR::ChanMapping
373 	 * TODO: consider replacing with boost::flat_map<> or std::vector<>.
374 	 */
375 #if defined(_MSC_VER) /* && (_MSC_VER < 1900)
376 	                   * Regarding the note (below) it was initially
377 	                   * thought that this got fixed in VS2015 - but
378 	                   * in fact it's still faulty (JE - Feb 2021) */
379 	/* Use the older (heap based) mapping for early versions of MSVC.
380 	 * In fact it might be safer to use this for all MSVC builds - as
381 	 * our StackAllocator class depends on 'boost::aligned_storage'
382 	 * which is known to be troublesome with Visual C++ :-
383 	 * https://www.boost.org/doc/libs/1_65_0/libs/type_traits/doc/html/boost_typetraits/reference/aligned_storage.html
384 	 */
385 	class PinMappings : public std::map <uint32_t, ARDOUR::ChanMapping>
386 #else
387 	class PinMappings : public std::map <uint32_t, ARDOUR::ChanMapping, std::less<uint32_t>, PBD::StackAllocator<std::pair<const uint32_t, ARDOUR::ChanMapping>, 4> >
388 #endif
389 	{
390 		public:
391 			/* this emulates C++11's  std::map::at()
392 			 * return mapping for given plugin instance */
p(const uint32_t i)393 			inline ARDOUR::ChanMapping const& p (const uint32_t i) const {
394 #ifndef NDEBUG
395 				const_iterator x = find (i);
396 				assert (x != end ());
397 				return x->second;
398 #else
399 				return find(i)->second;
400 #endif
401 			}
402 	};
403 
404 	PinMappings _in_map;
405 	PinMappings _out_map;
406 	ChanMapping _thru_map; // out-idx <=  in-idx
407 
408 	void automate_and_run (BufferSet& bufs, samplepos_t start, samplepos_t end, double speed, pframes_t nframes);
409 	void connect_and_run (BufferSet& bufs, samplepos_t start, samplecnt_t end, double speed, pframes_t nframes, samplecnt_t offset, bool with_auto);
410 	void bypass (BufferSet& bufs, pframes_t nframes);
411 	void inplace_silence_unconnected (BufferSet&, const PinMappings&, samplecnt_t nframes, samplecnt_t offset) const;
412 
413 	void create_automatable_parameters ();
414 	void control_list_automation_state_changed (Evoral::Parameter, AutoState);
415 	void set_parameter_state_2X (const XMLNode& node, int version);
416 	void set_control_ids (const XMLNode&, int version);
417 	void update_control_values (const XMLNode&, int version);
418 
419 	void enable_changed ();
420 	void bypassable_changed ();
421 
422 	bool sanitize_maps ();
423 	bool check_inplace ();
424 	void mapping_changed ();
425 
426 	boost::shared_ptr<Plugin> plugin_factory (boost::shared_ptr<Plugin>);
427 	void add_plugin (boost::shared_ptr<Plugin>);
428 	void plugin_removed (boost::weak_ptr<Plugin>);
429 
430 	void add_sidechain_from_xml (const XMLNode& node, int version);
431 
432 	void start_touch (uint32_t param_id);
433 	void end_touch (uint32_t param_id);
434 
435 	void latency_changed ();
436 	bool _latency_changed;
437 	uint32_t _bypass_port;
438 	bool     _inverted_bypass_enable;
439 
440 	typedef std::map<uint32_t, boost::shared_ptr<ReadOnlyControl> >CtrlOutMap;
441 	CtrlOutMap _control_outputs;
442 
443 	void preset_load_set_value (uint32_t, float);
444 
445 	PBD::TimingStats  _timing_stats;
446 	GATOMIC_QUAL gint _stat_reset;
447 	GATOMIC_QUAL gint _flush;
448 };
449 
450 } // namespace ARDOUR
451 
452 std::ostream& operator<<(std::ostream& o, const ARDOUR::PluginInsert::Match& m);
453 
454 #endif /* __ardour_plugin_insert_h__ */
455