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