1 /*
2  * Copyright (C) 2019-2020 Robin Gareus <robin@gareus.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 #ifndef _ardour_vst3_plugin_h_
20 #define _ardour_vst3_plugin_h_
21 
22 #include <map>
23 #include <set>
24 #include <vector>
25 
26 #include <boost/optional.hpp>
27 
28 #include "pbd/search_path.h"
29 #include "pbd/signals.h"
30 
31 #include "ardour/plugin.h"
32 #include "ardour/vst3_host.h"
33 
34 namespace ARDOUR
35 {
36 class VST3PluginModule;
37 class AutomationList;
38 }
39 
40 #if defined(__clang__)
41 # pragma clang diagnostic push
42 # pragma clang diagnostic ignored "-Wnon-virtual-dtor"
43 #elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
44 # pragma GCC diagnostic push
45 # pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
46 #endif
47 
48 namespace Steinberg {
49 /* VST3 hosted Plugin abstraction Implementation
50  *
51  * For convenience this is placed in the Steinberg namespace.
52  * Ardour::VST3Plugin has-a VST3PI (not is-a).
53  */
54 class LIBARDOUR_API VST3PI
55 	: public Vst::IComponentHandler
56 	, public Vst::IComponentHandler2
57 	, public Vst::IUnitHandler
58 	, public IPlugFrame
59 	, public Presonus::IContextInfoProvider3
60 {
61 public:
62 	VST3PI (boost::shared_ptr<ARDOUR::VST3PluginModule> m, std::string unique_id);
63 	virtual ~VST3PI ();
64 
65 	/* IComponentHandler */
66 	tresult PLUGIN_API beginEdit (Vst::ParamID id) SMTG_OVERRIDE;
67 	tresult PLUGIN_API performEdit (Vst::ParamID id, Vst::ParamValue value) SMTG_OVERRIDE;
68 	tresult PLUGIN_API endEdit (Vst::ParamID id) SMTG_OVERRIDE;
69 	tresult PLUGIN_API restartComponent (int32 flags) SMTG_OVERRIDE;
70 
71 	/* IComponentHandler2 */
72 	tresult PLUGIN_API setDirty (TBool state) SMTG_OVERRIDE;
73 	tresult PLUGIN_API requestOpenEditor (FIDString name) SMTG_OVERRIDE;
74 	tresult PLUGIN_API startGroupEdit () SMTG_OVERRIDE;
75 	tresult PLUGIN_API finishGroupEdit () SMTG_OVERRIDE;
76 
77 	/* IPlugFrame */
78 	tresult PLUGIN_API resizeView (IPlugView* view, ViewRect* newSize) SMTG_OVERRIDE;
79 
80 	/* IUnitHandler API */
81 	tresult PLUGIN_API notifyUnitSelection (Vst::UnitID) SMTG_OVERRIDE;
82 	tresult PLUGIN_API notifyProgramListChange (Vst::ProgramListID, int32) SMTG_OVERRIDE;
83 
84 	/* IContextInfoProvider3 API */
85 	tresult PLUGIN_API getContextInfoValue (int32&, FIDString) SMTG_OVERRIDE;
86 	tresult PLUGIN_API getContextInfoString (Vst::TChar*, int32, FIDString) SMTG_OVERRIDE;
87 	tresult PLUGIN_API getContextInfoValue (double&, FIDString) SMTG_OVERRIDE;
88 	tresult PLUGIN_API setContextInfoValue (FIDString, double) SMTG_OVERRIDE;
89 	tresult PLUGIN_API setContextInfoValue (FIDString, int32) SMTG_OVERRIDE;
90 	tresult PLUGIN_API setContextInfoString (FIDString, Vst::TChar*) SMTG_OVERRIDE;
91 	tresult PLUGIN_API beginEditContextInfoValue (FIDString) SMTG_OVERRIDE;
92 	tresult PLUGIN_API endEditContextInfoValue (FIDString) SMTG_OVERRIDE;
93 
94 	/* GUI */
95 	bool       has_editor () const;
96 	IPlugView* view ();
97 	void       close_view ();
98 	void       update_contoller_param ();
99 #if SMTG_OS_LINUX
100 	void set_runloop (Linux::IRunLoop*);
101 #endif
102 	PBD::Signal2<void, int, int> OnResizeView;
103 
104 	tresult PLUGIN_API queryInterface (const TUID _iid, void** obj) SMTG_OVERRIDE;
addRef()105 	uint32  PLUGIN_API addRef () SMTG_OVERRIDE { return 1; }
release()106 	uint32  PLUGIN_API release () SMTG_OVERRIDE { return 1; }
107 
fuid()108 	FUID const& fuid () const { return _fuid; }
109 
110 	/* Ardour Preset Helpers */
111 	Vst::IUnitInfo* unit_info ();
program_change_port()112 	Vst::ParameterInfo const& program_change_port () const { return _program_change_port; }
113 
set_n_factory_presets(size_t n)114 	void set_n_factory_presets (size_t n) { _n_factory_presets = n; }
n_factory_presets()115 	size_t n_factory_presets () const { return _n_factory_presets; }
116 
117 	/* API for Ardour -- Ports */
designated_bypass_port()118 	uint32_t designated_bypass_port ()         const { return _port_id_bypass; }
parameter_count()119 	uint32_t parameter_count ()                const { return _ctrl_params.size (); }
parameter_is_automatable(uint32_t p)120 	bool parameter_is_automatable (uint32_t p) const { return _ctrl_params[p].automatable; }
parameter_is_readonly(uint32_t p)121 	bool parameter_is_readonly (uint32_t p)    const { return _ctrl_params[p].read_only; }
parameter_label(uint32_t p)122 	std::string parameter_label (uint32_t p)   const { return _ctrl_params[p].label; }
123 
124 	float       default_value (uint32_t p) const;
125 	void        get_parameter_descriptor (uint32_t, ARDOUR::ParameterDescriptor&) const;
126 	std::string print_parameter (uint32_t p) const;
127 	std::string print_parameter (Vst::ParamID, Vst::ParamValue) const;
128 	bool        set_program (int p, int32 sample_off);
129 
130 	bool subscribe_to_automation_changes () const;
131 	void automation_state_changed (uint32_t, ARDOUR::AutoState, boost::weak_ptr<ARDOUR::AutomationList>);
132 
133 	ARDOUR::Plugin::IOPortDescription describe_io_port (ARDOUR::DataType dt, bool input, uint32_t id) const;
134 
135 	uint32_t n_audio_inputs () const;
136 	uint32_t n_audio_outputs () const;
137 
138 	/* MIDI/Event interface */
139 	void cycle_start ();
140 	void add_event (Evoral::Event<samplepos_t> const&, int32_t bus);
141 	void vst3_to_midi_buffers (ARDOUR::BufferSet&, ARDOUR::ChanMapping const&);
142 
143 	uint32_t n_midi_inputs () const;
144 	uint32_t n_midi_outputs () const;
145 
146 	/* API for Ardour -- Parameters */
147 	bool         try_set_parameter_by_id (Vst::ParamID id, float value);
148 	void         set_parameter (uint32_t p, float value, int32 sample_off);
149 	float        get_parameter (uint32_t p) const;
150 	std::string  format_parameter (uint32_t p) const;
151 	Vst::ParamID index_to_id (uint32_t) const;
152 
153 	enum ParameterChange { BeginGesture,
154 	                       EndGesture,
155 	                       ValueChange,
156 	                       InternalChange,
157 	                       PresetChange };
158 
159 	PBD::Signal3<void, ParameterChange, uint32_t, float> OnParameterChange;
160 
161 	/* API for Ardour -- Setup/Processing */
162 	uint32_t plugin_latency ();
163 	bool     set_block_size (int32_t);
164 	bool     activate ();
165 	bool     deactivate ();
166 
167 	/* State */
168 	bool save_state (RAMStream& stream);
169 	bool load_state (RAMStream& stream);
170 
context()171 	Vst::ProcessContext& context ()
172 	{
173 		return _context;
174 	}
175 
176 	void set_owner (ARDOUR::SessionObject* o);
177 
178 	void enable_io (std::vector<bool> const&, std::vector<bool> const&);
179 
180 	void process (float** ins, float** outs, uint32_t n_samples);
181 
182 	/* PSL Extension */
controller()183 	Vst::IEditController* controller () const
184 	{
185 		return _controller;
186 	}
187 	bool add_slave (Vst::IEditController*, bool);
188 	bool remove_slave (Vst::IEditController*);
189 
190 private:
191 	/* prevent copy construction */
192 	VST3PI (const VST3PI&);
193 
194 	void terminate ();
195 
196 	IPlugView* try_create_view () const;
197 
198 	bool connect_components ();
199 	bool disconnect_components ();
200 
201 	bool  update_processor ();
202 	int32 count_channels (Vst::MediaType, Vst::BusDirection, Vst::BusType);
203 
204 	bool evoral_to_vst3 (Vst::Event&, Evoral::Event<samplepos_t> const&, int32_t);
205 
206 	void update_shadow_data ();
207 	bool synchronize_states ();
208 
209 	void set_parameter_by_id (Vst::ParamID id, float value, int32 sample_off);
210 	void set_parameter_internal (Vst::ParamID id, float& value, int32 sample_off, bool normalized);
211 
212 	void set_event_bus_state (bool enabled);
213 
214 	bool midi_controller (int32_t, int16_t, Vst::CtrlNumber, Vst::ParamID& id);
215 	bool live_midi_cc (int32_t, int16_t, Vst::CtrlNumber);
216 
217 	bool setup_info_listener ();
218 	void stripable_property_changed (PBD::PropertyChange const&);
219 
220 	bool setup_psl_info_handler ();
221 	void psl_subscribe_to (boost::shared_ptr<ARDOUR::AutomationControl>, FIDString);
222 	void psl_stripable_property_changed (PBD::PropertyChange const&);
223 
224 	void foward_signal (Presonus::IContextInfoHandler2*, FIDString) const;
225 
226 	boost::shared_ptr<ARDOUR::VST3PluginModule> _module;
227 
228 	boost::shared_ptr<ConnectionProxy> _component_cproxy;
229 	boost::shared_ptr<ConnectionProxy> _controller_cproxy;
230 
231 	FUID                  _fuid;
232 	Vst::IComponent*      _component;
233 	Vst::IEditController* _controller;
234 	IPlugView*            _view;
235 
236 #if SMTG_OS_LINUX
237 	Linux::IRunLoop* _run_loop;
238 #endif
239 
240 	FUnknownPtr<Vst::IAudioProcessor> _processor;
241 	Vst::ProcessContext               _context;
242 
243 	/* Parameters */
244 	Vst3ParameterChanges _input_param_changes;
245 	Vst3ParameterChanges _output_param_changes;
246 
247 	Vst3EventList _input_events;
248 	Vst3EventList _output_events;
249 
250 	/* state */
251 	bool    _is_processing;
252 	int32_t _block_size;
253 
254 	/* ports */
255 	struct Param {
256 		uint32_t    id;
257 		std::string label;
258 		std::string unit;
259 		int32_t     steps; // 1: toggle
260 		double      normal;
261 		bool        is_enum;
262 		bool        read_only;
263 		bool        automatable;
264 	};
265 
266 	uint32_t                         _port_id_bypass;
267 	Vst::ParameterInfo               _program_change_port;
268 	std::vector<Param>               _ctrl_params;
269 	std::map<Vst::ParamID, uint32_t> _ctrl_id_index;
270 	std::map<uint32_t, Vst::ParamID> _ctrl_index_id;
271 	std::vector<float>               _shadow_data;
272 	mutable std::vector<bool>        _update_ctrl;
273 
274 	std::vector<ARDOUR::Plugin::IOPortDescription> _io_name[Vst::kNumMediaTypes][2];
275 
276 	std::vector<bool> _enabled_audio_in;
277 	std::vector<bool> _enabled_audio_out;
278 
279 	/* PSL extensions, control protocol */
280 	ARDOUR::SessionObject*      _owner;
281 	PBD::ScopedConnectionList   _strip_connections;
282 	PBD::ScopedConnectionList   _ac_connection_list;
283 	std::set<Evoral::Parameter> _ac_subscriptions;
284 	bool                        _add_to_selection;
285 
286 	boost::optional<uint32_t> _plugin_latency;
287 
288 	int _n_bus_in;
289 	int _n_bus_out;
290 
291 	std::vector<Vst::AudioBusBuffers> _busbuf_in;
292 	std::vector<Vst::AudioBusBuffers> _busbuf_out;
293 
294 	int _n_inputs;
295 	int _n_outputs;
296 	int _n_aux_inputs;
297 	int _n_aux_outputs;
298 	int _n_midi_inputs;
299 	int _n_midi_outputs;
300 	int _n_factory_presets;
301 };
302 
303 } // namespace Steinberg
304 
305 namespace ARDOUR {
306 
307 class LIBARDOUR_API VST3Plugin : public ARDOUR::Plugin
308 {
309 public:
310 	VST3Plugin (AudioEngine&, Session&, Steinberg::VST3PI*);
311 	VST3Plugin (const VST3Plugin&);
312 	~VST3Plugin ();
313 
unique_id()314 	std::string unique_id () const { return get_info ()->unique_id; }
name()315 	const char* name ()      const { return get_info ()->name.c_str (); }
label()316 	const char* label ()     const { return get_info ()->name.c_str (); }
maker()317 	const char* maker ()     const { return get_info ()->creator.c_str (); }
318 
319 	uint32_t parameter_count () const;
320 	float    default_value (uint32_t port);
321 	void     set_parameter (uint32_t port, float val, sampleoffset_t when);
322 	float    get_parameter (uint32_t port) const;
323 	int      get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const;
324 	uint32_t nth_parameter (uint32_t port, bool& ok) const;
325 	bool     print_parameter (uint32_t, std::string&) const;
326 
parameter_is_audio(uint32_t)327 	bool parameter_is_audio (uint32_t)   const { return false; }
parameter_is_control(uint32_t)328 	bool parameter_is_control (uint32_t) const { return true; }
329 
330 	bool parameter_is_input (uint32_t) const;
331 	bool parameter_is_output (uint32_t) const;
332 
333 	uint32_t designated_bypass_port ();
334 
335 	std::set<Evoral::Parameter> automatable () const;
336 	std::string                 describe_parameter (Evoral::Parameter);
337 	IOPortDescription           describe_io_port (DataType dt, bool input, uint32_t id) const;
338 	PluginOutputConfiguration   possible_output () const;
339 
340 	void set_automation_control (uint32_t, boost::shared_ptr<ARDOUR::AutomationControl>);
341 
state_node_name()342 	std::string state_node_name () const
343 	{
344 		return "vst3";
345 	}
346 
347 	void add_state (XMLNode*) const;
348 	int  set_state (const XMLNode&, int version);
349 
350 	bool        load_preset (PresetRecord);
351 	std::string do_save_preset (std::string);
352 	void        do_remove_preset (std::string);
353 
activate()354 	void activate ()
355 	{
356 		_plug->activate ();
357 	}
358 
deactivate()359 	void deactivate ()
360 	{
361 		_plug->deactivate ();
362 	}
363 
364 	int set_block_size (pframes_t);
365 
366 	void set_owner (ARDOUR::SessionObject* o);
367 
368 	void add_slave (boost::shared_ptr<Plugin>, bool);
369 	void remove_slave (boost::shared_ptr<Plugin>);
370 
371 	int connect_and_run (BufferSet&  bufs,
372 	                     samplepos_t start, samplepos_t end, double speed,
373 	                     ChanMapping const& in, ChanMapping const& out,
374 	                     pframes_t nframes, samplecnt_t offset);
375 
376 	bool                  has_editor () const;
377 	Steinberg::IPlugView* view ();
378 	void                  close_view ();
379 	void                  update_contoller_param ();
380 #if SMTG_OS_LINUX
381 	void set_runloop (Steinberg::Linux::IRunLoop*);
382 #endif
383 
384 	PBD::Signal2<void, int, int> OnResizeView;
385 
386 private:
387 	samplecnt_t plugin_latency () const;
388 	void        init ();
389 	void        find_presets ();
390 	void        forward_resize_view (int w, int h);
391 	void        parameter_change_handler (Steinberg::VST3PI::ParameterChange, uint32_t, float);
392 
393 	PBD::Searchpath preset_search_path () const;
394 
395 	Steinberg::VST3PI* _plug;
396 
397 	PBD::ScopedConnectionList _connections;
398 
399 	std::map<std::string, std::string> _preset_uri_map;
400 
401 	std::vector<bool> _connected_inputs;
402 	std::vector<bool> _connected_outputs;
403 };
404 
405 /* ****************************************************************************/
406 
407 class LIBARDOUR_API VST3PluginInfo : public PluginInfo
408 {
409 public:
410 	VST3PluginInfo ();
~VST3PluginInfo()411 	~VST3PluginInfo () {}
412 
413 	PluginPtr                         load (Session& session);
414 	std::vector<Plugin::PresetRecord> get_presets (bool user_only) const;
415 	bool                              is_instrument () const;
416 
417 	boost::shared_ptr<VST3PluginModule> m;
418 };
419 
420 } // namespace ARDOUR
421 #endif
422