Ardour  9.0-pre0-1792-g9dafed2d76
vst3_host.h
Go to the documentation of this file.
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_host_h_
20 #define _ardour_vst3_host_h_
21 
22 #include <atomic>
23 #include <cstdint>
24 #include <map>
25 #include <memory>
26 #include <string>
27 #include <vector>
28 
29 #include <glib.h>
30 
32 #include "vst3/vst3.h"
33 
34 #define QUERY_INTERFACE_IMPL(Interface) \
35 tresult PLUGIN_API queryInterface (const TUID _iid, void** obj) SMTG_OVERRIDE \
36 { \
37  QUERY_INTERFACE (_iid, obj, FUnknown::iid, Interface) \
38  QUERY_INTERFACE (_iid, obj, Interface::iid, Interface) \
39  *obj = nullptr; \
40  return kNoInterface; \
41 }
42 
43 #if defined(__clang__)
44 # pragma clang diagnostic push
45 # pragma clang diagnostic ignored "-Wnon-virtual-dtor"
46 # pragma clang diagnostic ignored "-Wdelete-non-virtual-dtor"
47 # pragma clang diagnostic ignored "-Wdelete-non-abstract-non-virtual-dtor"
48 #elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
49 # pragma GCC diagnostic push
50 # pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
51 # pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
52 #endif
53 
54 namespace ARDOUR {
55  class Session;
56 }
57 
58 namespace Steinberg {
59 
60 LIBARDOUR_API extern std::string tchar_to_utf8 (Vst::TChar const* s);
61 LIBARDOUR_API extern bool utf8_to_tchar (Vst::TChar* rv, const char* s, size_t l = 0);
62 LIBARDOUR_API extern bool utf8_to_tchar (Vst::TChar* rv, std::string const& s, size_t l = 0);
63 
64 namespace Vst {
65  /* see public.sdk/source/vst/vstpresetfile.cpp */
66  typedef char ChunkID[4]; // using ChunkID = char[4];
67  static const int32 kClassIDSize = 32; // ASCII-encoded FUID
68  static const int32 kHeaderSize = sizeof (ChunkID) + sizeof (int32) + kClassIDSize + sizeof (TSize);
69  static const int32 kListOffsetPos = kHeaderSize - sizeof (TSize);
70 } // namespace Vst
71 
73 {
74 public:
75  enum Type {
79  kBinary
80  };
81 
82  HostAttribute (int64 value)
83  : _size (0)
84  , _type (kInteger)
85  {
86  v.intValue = value;
87  }
88 
89  HostAttribute (double value)
90  : _size (0)
91  , _type (kFloat)
92  {
93  v.floatValue = value;
94  }
95 
96  HostAttribute (const Vst::TChar* value, uint32 size)
97  : _size (size)
98  , _type (kString)
99  {
100  v.stringValue = new Vst::TChar[_size + 1];
101  memcpy (v.stringValue, value, _size * sizeof (Vst::TChar));
102  v.stringValue[size] = 0;
103  }
104 
105  HostAttribute (const void* value, uint32 size)
106  : _size (size)
107  , _type (kBinary)
108  {
109  v.binaryValue = new char[_size];
110  memcpy (v.binaryValue, value, _size);
111  }
112 
114  {
115  if (_size) {
116  delete[] v.binaryValue;
117  }
118  }
119 
120  Type getType () const { return _type; }
121  int64 intValue () const { return v.intValue; }
122  double floatValue () const { return v.floatValue; }
123 
124  const Vst::TChar* stringValue (uint32& stringSize)
125  {
126  stringSize = _size;
127  return v.stringValue;
128  }
129 
130  const void* binaryValue (uint32& binarySize)
131  {
132  binarySize = _size;
133  return v.binaryValue;
134  }
135 
136 protected:
137  union v {
138  int64 intValue;
139  double floatValue;
140  Vst::TChar* stringValue;
141  char* binaryValue;
142  } v;
143 
144  uint32 _size;
146 
147 private:
148  /* prevent copy construction */
149  HostAttribute (HostAttribute const& other);
150 };
151 
152 class LIBARDOUR_API RefObject : public FUnknown
153 {
154 public:
156  virtual ~RefObject () {}
157  uint32 PLUGIN_API addRef () SMTG_OVERRIDE;
158  uint32 PLUGIN_API release () SMTG_OVERRIDE;
159 
160 private:
161  std::atomic<int> _cnt; // atomic
162 };
163 
164 class LIBARDOUR_API HostAttributeList : public Vst::IAttributeList, public RefObject
165 {
166 public:
168  virtual ~HostAttributeList ();
169 
170  QUERY_INTERFACE_IMPL (Vst::IAttributeList);
171 
172  uint32 PLUGIN_API addRef () SMTG_OVERRIDE
173  {
174  return RefObject::addRef ();
175  }
176 
177  uint32 PLUGIN_API release () SMTG_OVERRIDE
178  {
179  return RefObject::release ();
180  }
181 
182  tresult PLUGIN_API setInt (AttrID aid, int64 value) SMTG_OVERRIDE;
183  tresult PLUGIN_API getInt (AttrID aid, int64& value) SMTG_OVERRIDE;
184  tresult PLUGIN_API setFloat (AttrID aid, double value) SMTG_OVERRIDE;
185  tresult PLUGIN_API getFloat (AttrID aid, double& value) SMTG_OVERRIDE;
186  tresult PLUGIN_API setString (AttrID aid, const Vst::TChar* string) SMTG_OVERRIDE;
187  tresult PLUGIN_API getString (AttrID aid, Vst::TChar* string, uint32 size) SMTG_OVERRIDE;
188  tresult PLUGIN_API setBinary (AttrID aid, const void* data, uint32 size) SMTG_OVERRIDE;
189  tresult PLUGIN_API getBinary (AttrID aid, const void*& data, uint32& size) SMTG_OVERRIDE;
190 
191 protected:
192  void removeAttrID (AttrID aid);
193 
194  std::map<std::string, HostAttribute*> list;
195 };
196 
197 class LIBARDOUR_API HostMessage : public Vst::IMessage, public RefObject
198 {
199 public:
201  virtual ~HostMessage ();
202 
203  QUERY_INTERFACE_IMPL (Vst::IMessage);
204 
205  uint32 PLUGIN_API addRef () SMTG_OVERRIDE
206  {
207  return RefObject::addRef ();
208  }
209 
210  uint32 PLUGIN_API release () SMTG_OVERRIDE
211  {
212  return RefObject::release ();
213  }
214 
215  const char* PLUGIN_API getMessageID () SMTG_OVERRIDE;
216  void PLUGIN_API setMessageID (const char* messageID) SMTG_OVERRIDE;
217  Vst::IAttributeList* PLUGIN_API getAttributes () SMTG_OVERRIDE;
218 
219 protected:
220  char* _messageId;
221  std::shared_ptr<HostAttributeList> _attribute_list;
222 };
223 
224 class LIBARDOUR_API ConnectionProxy : public Vst::IConnectionPoint, public RefObject
225 {
226 public:
227  ConnectionProxy (IConnectionPoint* src);
228  ~ConnectionProxy () SMTG_OVERRIDE;
229 
230  QUERY_INTERFACE_IMPL (Vst::IConnectionPoint);
231 
232  uint32 PLUGIN_API addRef () SMTG_OVERRIDE
233  {
234  return RefObject::addRef ();
235  }
236 
237  uint32 PLUGIN_API release () SMTG_OVERRIDE
238  {
239  return RefObject::release ();
240  }
241 
242  /* IConnectionPoint API */
243  tresult PLUGIN_API connect (Vst::IConnectionPoint*) SMTG_OVERRIDE;
244  tresult PLUGIN_API disconnect (Vst::IConnectionPoint*) SMTG_OVERRIDE;
245  tresult PLUGIN_API notify (Vst::IMessage*) SMTG_OVERRIDE;
246 
247  bool disconnect ();
248 
249 protected:
250  IConnectionPoint* _src;
251  IConnectionPoint* _dst;
252 };
253 
254 class LIBARDOUR_API PlugInterfaceSupport : public Vst::IPlugInterfaceSupport
255 {
256 public:
258  QUERY_INTERFACE_IMPL (Vst::IPlugInterfaceSupport);
259 
260  uint32 PLUGIN_API addRef () SMTG_OVERRIDE
261  {
262  return 1;
263  }
264 
265  uint32 PLUGIN_API release () SMTG_OVERRIDE
266  {
267  return 1;
268  }
269 
270  tresult PLUGIN_API isPlugInterfaceSupported (const TUID) SMTG_OVERRIDE;
271 
272  void addPlugInterfaceSupported (const TUID);
273 
274 private:
275  std::vector<FUID> _interfaces;
276 };
277 
278 class LIBARDOUR_API HostApplication : public Vst::IHostApplication , public Presonus::IContextInfoProvider
279 {
280 public:
281  static Vst::IHostApplication* getHostContext ()
282  {
283  static HostApplication* app = new HostApplication;
284  return app;
285  }
286 
288  return static_cast<HostApplication*> (getHostContext ());
289  }
290 
291  virtual ~HostApplication () {}
292  tresult PLUGIN_API queryInterface (const TUID _iid, void** obj) SMTG_OVERRIDE;
293 
294  uint32 PLUGIN_API addRef () SMTG_OVERRIDE
295  {
296  return 1;
297  }
298 
299  uint32 PLUGIN_API release () SMTG_OVERRIDE
300  {
301  return 1;
302  }
303 
304  tresult PLUGIN_API getName (Vst::String128 name) SMTG_OVERRIDE;
305  tresult PLUGIN_API createInstance (TUID cid, TUID _iid, void** obj) SMTG_OVERRIDE;
306 
308 
309  /* IContextInfoProvider API */
310  tresult PLUGIN_API getContextInfoValue (int32&, FIDString) SMTG_OVERRIDE;
311  tresult PLUGIN_API getContextInfoString (Vst::TChar*, int32, FIDString) SMTG_OVERRIDE;
312 
313 protected:
314  std::unique_ptr<PlugInterfaceSupport> _plug_interface_support;
315 private:
318 };
319 
320 class LIBARDOUR_LOCAL Vst3ParamValueQueue : public Vst::IParamValueQueue
321 {
322 public:
323  QUERY_INTERFACE_IMPL (Vst::IParamValueQueue);
324 
325  uint32 PLUGIN_API addRef () SMTG_OVERRIDE
326  {
327  return 1;
328  }
329 
330  uint32 PLUGIN_API release () SMTG_OVERRIDE
331  {
332  return 1;
333  }
334 
335  static const int maxNumPoints = 64;
336 
337  Vst3ParamValueQueue ()
338  {
339  _values.reserve (maxNumPoints);
340  _id = Vst::kNoParamId;
341  }
342 
343  Vst::ParamID PLUGIN_API getParameterId () SMTG_OVERRIDE
344  {
345  return _id;
346  }
347 
348  void setParameterId (Vst::ParamID id)
349  {
350  _values.clear ();
351  _id = id;
352  }
353 
354  int32 PLUGIN_API getPointCount () SMTG_OVERRIDE
355  {
356  return _values.size ();
357  }
358 
359  tresult PLUGIN_API getPoint (int32 index, int32&, Vst::ParamValue&) SMTG_OVERRIDE;
360  tresult PLUGIN_API addPoint (int32, Vst::ParamValue, int32&) SMTG_OVERRIDE;
361 
362 protected:
363  struct Value {
364  Value (Vst::ParamValue v, int32 offset)
365  : value (v)
366  , sampleOffset (offset)
367  {}
368 
369  Vst::ParamValue value;
370  int32 sampleOffset;
371  };
372 
373  std::vector<Value> _values;
374  Vst::ParamID _id;
375 };
376 
377 class LIBARDOUR_LOCAL Vst3ParameterChanges : public Vst::IParameterChanges
378 {
379 public:
380  QUERY_INTERFACE_IMPL (Vst::IParameterChanges);
381 
382  uint32 PLUGIN_API addRef () SMTG_OVERRIDE
383  {
384  return 1;
385  }
386 
387  uint32 PLUGIN_API release () SMTG_OVERRIDE
388  {
389  return 1;
390  }
391 
392  Vst3ParameterChanges ()
393  {
394  clear ();
395  }
396 
397  void set_n_params (int n)
398  {
399  _queue.resize (n);
400  }
401 
402  void clear ()
403  {
404  _used_queue_count = 0;
405  }
406 
407  int32 PLUGIN_API getParameterCount () SMTG_OVERRIDE
408  {
409  return _used_queue_count;
410  }
411 
412  Vst::IParamValueQueue* PLUGIN_API getParameterData (int32 index) SMTG_OVERRIDE;
413  Vst::IParamValueQueue* PLUGIN_API addParameterData (Vst::ParamID const& id, int32& index) SMTG_OVERRIDE;
414 
415 protected:
416  std::vector<Vst3ParamValueQueue> _queue;
417  int _used_queue_count;
418 };
419 
420 class LIBARDOUR_LOCAL Vst3EventList : public Vst::IEventList
421 {
422 public:
423  Vst3EventList ()
424  {
425  _events.reserve (128);
426  }
427 
428  QUERY_INTERFACE_IMPL (Vst::IEventList)
429 
430  uint32 PLUGIN_API addRef () SMTG_OVERRIDE
431  {
432  return 1;
433  }
434 
435  uint32 PLUGIN_API release () SMTG_OVERRIDE
436  {
437  return 1;
438  }
439 
440  int32 PLUGIN_API PLUGIN_API getEventCount () SMTG_OVERRIDE
441  {
442  return _events.size ();
443  }
444 
445  tresult PLUGIN_API getEvent (int32 index, Vst::Event& e) SMTG_OVERRIDE
446  {
447  if (index >= 0 && index < (int32)_events.size ()) {
448  e = _events[index];
449  return kResultTrue;
450  } else {
451  return kResultFalse;
452  }
453  }
454 
455  tresult PLUGIN_API addEvent (Vst::Event& e) SMTG_OVERRIDE
456  {
457  _events.push_back (e);
458  return kResultTrue;
459  }
460 
461  void clear ()
462  {
463  _events.clear ();
464  }
465 
466 protected:
467  std::vector<Vst::Event> _events;
468 };
469 
470 class LIBARDOUR_LOCAL RAMStream : public IBStream, public ISizeableStream, public Vst::IStreamAttributes
471 {
472 public:
473  RAMStream ();
474  RAMStream (uint8_t* data, size_t size);
475  RAMStream (std::string const& fn);
476 
477  virtual ~RAMStream ();
478 
479  tresult PLUGIN_API queryInterface (const TUID _iid, void** obj) SMTG_OVERRIDE;
480 
481  uint32 PLUGIN_API addRef () SMTG_OVERRIDE
482  {
483  return 1;
484  }
485 
486  uint32 PLUGIN_API release () SMTG_OVERRIDE
487  {
488  return 1;
489  }
490 
491  /* IBStream API */
492  tresult PLUGIN_API read (void* buffer, int32 numBytes, int32* numBytesRead) SMTG_OVERRIDE;
493  tresult PLUGIN_API write (void* buffer, int32 numBytes, int32* numBytesWritten) SMTG_OVERRIDE;
494  tresult PLUGIN_API seek (int64 pos, int32 mode, int64* result) SMTG_OVERRIDE;
495  tresult PLUGIN_API tell (int64* pos) SMTG_OVERRIDE;
496 
497  /* ISizeableStream API */
498  tresult PLUGIN_API getStreamSize (int64&) SMTG_OVERRIDE;
499  tresult PLUGIN_API setStreamSize (int64) SMTG_OVERRIDE;
500 
501  /* IStreamAttributes API */
502  tresult PLUGIN_API getFileName (Vst::String128 name) SMTG_OVERRIDE;
503  Vst::IAttributeList* PLUGIN_API getAttributes () SMTG_OVERRIDE;
504 
505  /* convenience API for state I/O */
506  void rewind ()
507  {
508  _pos = 0;
509  }
510 
511  bool readonly () const
512  {
513  return _readonly;
514  }
515 
516  bool write_int32 (int32 i);
517  bool write_int64 (int64 i);
518  bool write_ChunkID (const Vst::ChunkID& id);
519  bool write_TUID (const TUID& tuid);
520 
521  bool read_int32 (int32& i);
522  bool read_int64 (int64& i);
523  bool read_ChunkID (Vst::ChunkID& id);
524  bool read_TUID (TUID& tuid);
525 
526  /* direct access */
527  uint8_t const* data () const
528  {
529  return _data;
530  }
531 
532  int64 size () const
533  {
534  return _size;
535  }
536 
537 #ifndef NDEBUG
538  void hexdump (int64 max_len = 64) const;
539 #endif
540 
541 private:
542  bool reallocate_buffer (int64 size, bool exact);
543 
544  template <typename T>
545  bool read_pod (T& t)
546  {
547  int32 n_read = 0;
548  read ((void*)&t, sizeof (T), &n_read);
549  return n_read == sizeof (T);
550  }
551 
552  template <typename T>
553  bool write_pod (const T& t)
554  {
555  int32 written = 0;
556  write (const_cast<void*> ((const void*)&t), sizeof (T), &written);
557  return written == sizeof (T);
558  }
559 
560  uint8_t* _data;
561  int64 _size;
562  int64 _alloc;
563  int64 _pos;
564  bool _readonly;
565 
566  HostAttributeList attribute_list;
567 };
568 
569 class LIBARDOUR_LOCAL ROMStream : public IBStream
570 {
571 public:
572  ROMStream (IBStream& src, TSize offset, TSize size);
573  virtual ~ROMStream ();
574 
575  tresult PLUGIN_API queryInterface (const TUID _iid, void** obj) SMTG_OVERRIDE;
576 
577  uint32 PLUGIN_API addRef () SMTG_OVERRIDE
578  {
579  return 1;
580  }
581 
582  uint32 PLUGIN_API release () SMTG_OVERRIDE
583  {
584  return 1;
585  }
586 
587  /* IBStream API */
588  tresult PLUGIN_API read (void* buffer, int32 numBytes, int32* numBytesRead) SMTG_OVERRIDE;
589  tresult PLUGIN_API write (void* buffer, int32 numBytes, int32* numBytesWritten) SMTG_OVERRIDE;
590  tresult PLUGIN_API seek (int64 pos, int32 mode, int64* result) SMTG_OVERRIDE;
591  tresult PLUGIN_API tell (int64* pos) SMTG_OVERRIDE;
592 
593  void rewind ()
594  {
595  _pos = 0;
596  }
597 
598 protected:
599  IBStream& _stream;
600  int64 _offset;
601  int64 _size;
602  int64 _pos;
603 };
604 
605 #if defined(__clang__)
606 #pragma clang diagnostic pop
607 #elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
608 #pragma GCC diagnostic pop
609 #endif
610 
611 } // namespace Steinberg
612 #endif
IConnectionPoint * _src
Definition: vst3_host.h:250
~ConnectionProxy() SMTG_OVERRIDE
tresult PLUGIN_API notify(Vst::IMessage *) SMTG_OVERRIDE
IConnectionPoint * _dst
Definition: vst3_host.h:251
tresult PLUGIN_API disconnect(Vst::IConnectionPoint *) SMTG_OVERRIDE
uint32 PLUGIN_API release() SMTG_OVERRIDE
Definition: vst3_host.h:237
tresult PLUGIN_API connect(Vst::IConnectionPoint *) SMTG_OVERRIDE
ConnectionProxy(IConnectionPoint *src)
static HostApplication * theHostContext()
Definition: vst3_host.h:287
tresult PLUGIN_API queryInterface(const TUID _iid, void **obj) SMTG_OVERRIDE
tresult PLUGIN_API getContextInfoValue(int32 &, FIDString) SMTG_OVERRIDE
std::unique_ptr< PlugInterfaceSupport > _plug_interface_support
Definition: vst3_host.h:314
void set_session(ARDOUR::Session *)
uint32 PLUGIN_API addRef() SMTG_OVERRIDE
Definition: vst3_host.h:294
tresult PLUGIN_API createInstance(TUID cid, TUID _iid, void **obj) SMTG_OVERRIDE
static Vst::IHostApplication * getHostContext()
Definition: vst3_host.h:281
tresult PLUGIN_API getContextInfoString(Vst::TChar *, int32, FIDString) SMTG_OVERRIDE
tresult PLUGIN_API getName(Vst::String128 name) SMTG_OVERRIDE
uint32 PLUGIN_API release() SMTG_OVERRIDE
Definition: vst3_host.h:299
ARDOUR::Session * _session
Definition: vst3_host.h:317
tresult PLUGIN_API setBinary(AttrID aid, const void *data, uint32 size) SMTG_OVERRIDE
tresult PLUGIN_API getBinary(AttrID aid, const void *&data, uint32 &size) SMTG_OVERRIDE
std::map< std::string, HostAttribute * > list
Definition: vst3_host.h:194
uint32 PLUGIN_API release() SMTG_OVERRIDE
Definition: vst3_host.h:177
tresult PLUGIN_API setString(AttrID aid, const Vst::TChar *string) SMTG_OVERRIDE
tresult PLUGIN_API setInt(AttrID aid, int64 value) SMTG_OVERRIDE
uint32 PLUGIN_API addRef() SMTG_OVERRIDE
Definition: vst3_host.h:172
void removeAttrID(AttrID aid)
tresult PLUGIN_API getFloat(AttrID aid, double &value) SMTG_OVERRIDE
tresult PLUGIN_API setFloat(AttrID aid, double value) SMTG_OVERRIDE
tresult PLUGIN_API getInt(AttrID aid, int64 &value) SMTG_OVERRIDE
tresult PLUGIN_API getString(AttrID aid, Vst::TChar *string, uint32 size) SMTG_OVERRIDE
double floatValue() const
Definition: vst3_host.h:122
HostAttribute(const void *value, uint32 size)
Definition: vst3_host.h:105
Type getType() const
Definition: vst3_host.h:120
HostAttribute(int64 value)
Definition: vst3_host.h:82
int64 intValue() const
Definition: vst3_host.h:121
const Vst::TChar * stringValue(uint32 &stringSize)
Definition: vst3_host.h:124
const void * binaryValue(uint32 &binarySize)
Definition: vst3_host.h:130
HostAttribute(HostAttribute const &other)
HostAttribute(const Vst::TChar *value, uint32 size)
Definition: vst3_host.h:96
HostAttribute(double value)
Definition: vst3_host.h:89
uint32 PLUGIN_API release() SMTG_OVERRIDE
Definition: vst3_host.h:210
const char *PLUGIN_API getMessageID() SMTG_OVERRIDE
uint32 PLUGIN_API addRef() SMTG_OVERRIDE
Definition: vst3_host.h:205
uint32 PLUGIN_API addRef() SMTG_OVERRIDE
Definition: vst3_host.h:260
uint32 PLUGIN_API release() SMTG_OVERRIDE
Definition: vst3_host.h:265
void addPlugInterfaceSupported(const TUID)
std::vector< FUID > _interfaces
Definition: vst3_host.h:275
tresult PLUGIN_API isPlugInterfaceSupported(const TUID) SMTG_OVERRIDE
uint32 PLUGIN_API release() SMTG_OVERRIDE
virtual ~RefObject()
Definition: vst3_host.h:156
uint32 PLUGIN_API addRef() SMTG_OVERRIDE
GtkImageIconNameData name
Definition: gtkimage.h:6
#define LIBARDOUR_LOCAL
#define LIBARDOUR_API
union Value Value
static const int32 kClassIDSize
Definition: vst3_host.h:67
char ChunkID[4]
Definition: vst3_host.h:66
static const int32 kListOffsetPos
Definition: vst3_host.h:69
static const int32 kHeaderSize
Definition: vst3_host.h:68
std::string tchar_to_utf8(Vst::TChar const *s)
bool utf8_to_tchar(Vst::TChar *rv, const char *s, size_t l=0)
Definition: lobject.h:100
#define QUERY_INTERFACE_IMPL(Interface)
Definition: vst3_host.h:34