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