ASPiK SDK
vst3plugin.h
1 // --- header
2 #ifndef __VST3Plugin__
3 #define __VST3Plugin__
4 
5 // --- VST3
6 #include "public.sdk/source/vst/vstsinglecomponenteffect.h"
7 #include "pluginterfaces/vst/ivstparameterchanges.h"
8 
9 // --- MIDI EVENTS
10 #include "pluginterfaces/vst/ivstevents.h"
11 
12 // --- WString Support
13 #include "pluginterfaces/base/ustring.h"
14 
15 // --- our plugin core object
16 #include "plugincore.h"
17 #include "plugingui.h"
18 
19 // --- windows.h bug
20 #define ENABLE_WINDOWS_H 1
21 
22 #if MAC
23 #include <CoreFoundation/CoreFoundation.h>
24 #else
25 #ifdef ENABLE_WINDOWS_H
26  #include <windows.h>
27 #endif
28 extern void* hInstance; // VSTGUI hInstance
29 #endif
30 
31 #include <vector>
32 
33 namespace Steinberg {
34 namespace Vst {
35 namespace ASPiK {
36 /*
37  The Processor object here ALSO contains the Edit Controller component since these
38  are combined as SingleComponentEffect; see documentation
39 */
40 class VSTParamUpdateQueue;
41 class GUIPluginConnector;
43 class VSTMIDIEventQueue;
44 
45 // --- sets up proxy MIDI CC parameters for one MIDI channel (these are shared across ALL MIDI channels)
46 // IF you want to have separate CC's decoded on separated channels, you need to duplicate this 15 (more) times
47 // see: https://forums.steinberg.net/t/vst3-and-midi-cc-pitfall/201879
48 //
49 // --- this sets up proxy parameters for the 128 MIDI CC [0, 127] + aftertouch [128] + pitchbend [129]
50 // thus the range of 130 IDs, from 1000 to 1129
51 const ParamID baseCCParamID = 1000; // *** VST3 MIDI CC Proxy Variables STATRT Channel 0, shared with all other channels
52 const ParamID baseCCParamIDEnd = 1129; // *** VST3 MIDI CC Proxy Variables END Channel 0, shared with all other channels
53 
54 // --- MIDI helpers; replace with your own if needed
55 const unsigned char CONTROL_CHANGE = 0xB0;
56 const unsigned char CHANNEL_PRESSURE = 0xD0;
57 const unsigned char PITCH_BEND = 0xE0;
58 
70 class VST3Plugin : public SingleComponentEffect, public IMidiMapping
71 {
72 public:
73  // --- constructor
74  VST3Plugin();
75 
76  // --- destructor
77  ~VST3Plugin();
78 
79  /*** IAudioProcessor Interface ***/
81  tresult PLUGIN_API initialize(FUnknown* context) override;
82 
84  tresult PLUGIN_API setBusArrangements(SpeakerArrangement* inputs, int32 numIns, SpeakerArrangement* outputs, int32 numOuts) override;
85 
87  tresult PLUGIN_API canProcessSampleSize(int32 symbolicSampleSize) override;
88 
90  tresult PLUGIN_API setupProcessing(ProcessSetup& newSetup) override;
91 
93  tresult PLUGIN_API setActive(TBool state) override;
94 
96  // These get/set the plugin variables
97  tresult PLUGIN_API setState(IBStream* fileStream) override;
98  tresult PLUGIN_API getState(IBStream* fileStream) override;
99 
101  // Update the GUI control variables
102  bool doControlUpdate(ProcessData& data);
103 
105  tresult PLUGIN_API process(ProcessData& data) override;
106 
108  virtual tresult PLUGIN_API getMidiControllerAssignment(int32 busIndex, int16 channel, CtrlNumber midiControllerNumber, ParamID& id/*out*/) override;
109 
110  // --- issue a MIDI CC message from a proxy parameter value
111  // see: https://forums.steinberg.net/t/vst3-and-midi-cc-pitfall/201879
112  bool issueMIDICCProxyMessage(ParamID proxyParamID, ParamValue proxyParamValue);
113 
114  // --- helper function for the proxy method
115  inline void unipolarDoubleToMIDI14_bit(double unipolarValue, uint32_t& midiDataLSB, uint32_t& midiDataMSB)
116  {
117  // --- convert to 16-bit unsigned short
118  unsigned short shValue = (unsigned short)(unipolarValue * (double)(0x4000));
119  unsigned short shd1 = shValue & 0x007F;
120 
121  // --- shift back by 1
122  unsigned short shd2 = shValue << 1;
123 
124  // --- split into MSB, LSB
125  shd2 = shd2 & 0x7F00;
126 
127  // --- shift MSB back to fill LSB position
128  shd2 = shd2 >> 8;
129 
130  // --- copy into unsigned ints, fill lower portions
131  midiDataLSB = shd1;
132  midiDataMSB = shd2;
133  }
134 
136  IPlugView* PLUGIN_API createView(const char* _name) override;
137 
139  tresult PLUGIN_API terminate() override;
140 
142  virtual tresult receiveText(const char8* text) override;
143 
145  tresult PLUGIN_API setParamNormalizedFromFile(ParamID tag, ParamValue value);
146 
148  tresult PLUGIN_API setComponentState(IBStream* fileStream) override;
149 
151  void updateMeters(ProcessData& data, bool forceOff = false);
152 
154  static FUnknown* createInstance(void* context) {return (IAudioProcessor*)new VST3Plugin(); }
155 
156  tresult PLUGIN_API setParamNormalized(ParamID tag, ParamValue value) override;
157 
159  virtual tresult PLUGIN_API getProgramName(ProgramListID listId, int32 programIndex, String128 name /*out*/) override;
160 
162  virtual void PLUGIN_API update(FUnknown* changedUnknown, int32 message) override ;
163 
164  // --- latency support
165  uint32 m_uLatencyInSamples = 0;
166 
168  virtual uint32 PLUGIN_API getLatencySamples() override {
169  return m_uLatencyInSamples; }
170 
172  virtual uint32 PLUGIN_API getTailSamples() override ;
173 
175  void updateHostInfo(ProcessData& data, HostInfo* hostInfo);
176 
177  static FUID* getFUID();
178  static const char* getPluginName();
179  static const char* getVendorName();
180  static const char* getVendorURL();
181  static const char* getVendorEmail();
182  static CString getPluginType();
183 
184  // --- define the IMidiMapping interface
185  OBJ_METHODS(VST3Plugin, SingleComponentEffect)
186  DEFINE_INTERFACES
187  DEF_INTERFACE(IMidiMapping)
188  DEF_INTERFACE(IUnitInfo)
189  END_DEFINE_INTERFACES(SingleComponentEffect)
190  REFCOUNT_METHODS(SingleComponentEffect)
191 
192 
193 private:
194  // --- our plugin core and interfaces
195  PluginCore* pluginCore = nullptr;
196  GUIPluginConnector* guiPluginConnector = nullptr;
197  PluginHostConnector* pluginHostConnector = nullptr;
198  VSTMIDIEventQueue* midiEventQueue = nullptr;
199  bool plugInSideBypass = false;
200  bool hasSidechain = false;
201 
202 protected:
203  // --- sample accurate parameter automation
205  unsigned int sampleAccuracy = 1;
206  bool enableSAAVST3 = false;
207 
208  // --- IUnitInfo and factory Preset support
209  typedef std::vector<IPtr<ProgramList> > ProgramListVector;
210  typedef std::map<ProgramListID, ProgramListVector::size_type> ProgramIndexMap;
211  typedef std::vector<IPtr<Unit> > UnitVector;
212  UnitVector units;
213  ProgramListVector programLists;
214  ProgramIndexMap programIndexMap;
215  UnitID selectedUnit;
216 
217 
218 #if defined _WINDOWS || defined _WINDLL
219 #ifdef ENABLE_WINDOWS_H
220  // --- getMyDLLDirectory()
221  // returns the directory where the .component resides
222  char* getMyDLLDirectory(UString cPluginName)
223  {
224  HMODULE hmodule = GetModuleHandle(cPluginName);
225 
226  TCHAR dir[MAX_PATH];
227  memset(&dir[0], 0, MAX_PATH*sizeof(TCHAR));
228  dir[MAX_PATH-1] = '\0';
229 
230  if(hmodule)
231  GetModuleFileName(hmodule, &dir[0], MAX_PATH);
232  else
233  return nullptr;
234 
235  // convert to UString
236  UString DLLPath(&dir[0], MAX_PATH);
237 
238  char* pFullPath = new char[MAX_PATH];
239  char* pDLLRoot = new char[MAX_PATH];
240 
241  DLLPath.toAscii(pFullPath, MAX_PATH);
242 
243  size_t nLenDir = strlen(pFullPath);
244  size_t nLenDLL = wcslen(cPluginName) + 1; // +1 is for trailing backslash
245  memcpy(pDLLRoot, pFullPath, nLenDir-nLenDLL);
246  pDLLRoot[nLenDir-nLenDLL] = '\0';
247 
248  delete [] pFullPath;
249 
250  // caller must delete this after use
251  return pDLLRoot;
252  }
253 #endif
254 #endif
255 #if MAC
256  // --- getMyComponentDirectory()
257  // returns the directory where the .component resides
258  char* getMyComponentDirectory(CFStringRef bundleID)
259  {
260  if (bundleID != nullptr)
261  {
262  CFBundleRef helixBundle = CFBundleGetBundleWithIdentifier( bundleID );
263  if(helixBundle != nullptr)
264  {
265  CFURLRef bundleURL = CFBundleCopyBundleURL ( helixBundle );
266  if(bundleURL != nullptr)
267  {
268  CFURLRef componentFolderPathURL = CFURLCreateCopyDeletingLastPathComponent(nullptr, bundleURL);
269 
270  CFStringRef myComponentPath = CFURLCopyFileSystemPath(componentFolderPathURL, kCFURLPOSIXPathStyle);
271  CFRelease(componentFolderPathURL);
272 
273  if(myComponentPath != nullptr)
274  {
275  int nSize = CFStringGetLength(myComponentPath);
276  char* path = new char[nSize+1];
277  memset(path, 0, (nSize+1)*sizeof(char));
278 
279  bool success = CFStringGetCString(myComponentPath, path, nSize+1, kCFStringEncodingASCII);
280  CFRelease(myComponentPath);
281 
282  if(success) return path;
283  else return nullptr;
284  }
285  CFRelease(bundleURL);
286  }
287  }
288  CFRelease(bundleID);
289  }
290  return nullptr;
291  }
292 #endif
293 
294 };
295 
310 {
311 protected:
312  unsigned int bufferSize = 0;
313  ParamValue initialValue = 0.0;
314  ParamValue previousValue = 0.0;
315  ParamValue maxValue = 0.0;
316  ParamValue minValue = 0.0;
317 
318  // --- Store slope and b so that it needs to be calculated only once.
319  ParamValue slope;
320  ParamValue yIntercept;
321 
322  // --- Controls granularity
323  unsigned int* sampleAccuracy = nullptr;
324  int queueIndex = 0;
325  int queueSize = 0;
326  IParamValueQueue* parameterQueue = nullptr;
327  int x1, x2 = 0;
328  double y1, y2 = 0;
329  bool dirtyBit = false;
330  int sampleOffset = 0;
331 
332 public:
333  VSTParamUpdateQueue(void);
334  virtual ~VSTParamUpdateQueue(void){}
335  void initialize(ParamValue _initialValue, ParamValue _minValue, ParamValue _maxValue, unsigned int* _sampleAccuracy);
336  void setParamValueQueue(IParamValueQueue* _paramValueQueue, unsigned int _bufferSize);
337  void setSlope();
338  ParamValue interpolate(int x1, int x2, ParamValue y1, ParamValue y2, int x);
339  int needsUpdate(int x, ParamValue &value);
340 
341  // --- IParameterUpdateQueue
342  unsigned int getParameterIndex();
343  bool getValueAtOffset(long int _sampleOffset, double _previousValue, double& _nextValue);
344  bool getNextValue(double& _nextValue);
345 };
346 
347 
348 
368 {
369 public:
370  PluginHostConnector(VST3Plugin* _editController) {editController = _editController;}
371  virtual ~PluginHostConnector(){}
372 
378  virtual void sendHostMessage(const HostMessageInfo& hostMessageInfo)
379  {
380  switch(hostMessageInfo.hostMessage)
381  {
382  case sendGUIUpdate:
383  {
384  GUIUpdateData guiUpdateData = hostMessageInfo.guiUpdateData;
385 
386  for(unsigned int i = 0; i < guiUpdateData.guiParameters.size(); i++)
387  {
388  GUIParameter guiParam = guiUpdateData.guiParameters[i];
389  if(editController)
390  {
391  ParamValue normalizedValue = editController->plainParamToNormalized(guiParam.controlID, guiParam.actualValue);
392  editController->setParamNormalized(guiParam.controlID, normalizedValue);
393  }
394  }
395 
396  // --- clean up
397  for (unsigned int i = 0; i < guiUpdateData.guiParameters.size(); i++)
398  guiUpdateData.guiParameters.pop_back();
399 
400  break;
401  }
402  default:
403  break;
404  }
405  }
406 
407 protected:
409 };
410 
411 // --- GUI -> Plugin interface
427 {
428 public:
430  CustomViewController(ICustomView* _customViewIF) { customViewIF = _customViewIF; }
431  virtual ~CustomViewController() {}
432 
434  virtual void updateView()
435  {
436  if (customViewIF)
437  customViewIF->updateView();
438  }
439 
441  virtual void pushDataValue(double data)
442  {
443  if (customViewIF)
444  customViewIF->pushDataValue(data);
445  }
446 
448  virtual void sendMessage(void* data)
449  {
450  if (customViewIF)
451  customViewIF->sendMessage(data);
452  }
453 
455  void setCustomViewPtr(ICustomView* _customViewIF) { customViewIF = _customViewIF; }
456 
458  const ICustomView* getCustomViewPtr() { return customViewIF; }
459 
461  void clearCustomViewPtr() { customViewIF = nullptr; }
462 
463 
464 private:
465  ICustomView* customViewIF = nullptr;
466 };
467 
489 {
490 public:
492  GUIPluginConnector(PluginCore* _pluginCore, VST3Plugin* _editController)
493  {
494  pluginCore = _pluginCore;
495  editController = _editController;
496  }
497 
500  {
501  for (customViewControllerMap::const_iterator it = customSubControllerMap.begin(), end = customSubControllerMap.end(); it != end; ++it)
502  {
503  delete it->second;
504  }
505  for (customViewControllerMap::const_iterator it = customViewMap.begin(), end = customViewMap.end(); it != end; ++it)
506  {
507  delete it->second;
508  }
509  }
510 
512  virtual void parameterChanged(int32_t controlID, double actualValue, double normalizedValue)
513  {
514  if(pluginCore)
515  pluginCore->guiParameterChanged(controlID, actualValue);
516 
517  if(!editController) return;
518 
519  // --- set parameter on object
520  editController->setParamNormalized(controlID, normalizedValue);
521 
522  // --- perform the operation
523  editController->performEdit(controlID, normalizedValue);
524  }
525 
527  virtual double getNormalizedPluginParameter(int32_t controlID)
528  {
529  if(!editController) return 0.0;
530 
531  Parameter* param = editController->getParameterObject(controlID);
532  if(!param) return 0.0;
533 
534  return param->getNormalized();
535  }
536 
538  virtual double getActualPluginParameter(int32_t controlID)
539  {
540  if (!editController) return 0.0;
541 
542  Parameter* param = editController->getParameterObject(controlID);
543  if (!param) return 0.0;
544 
545  // --- get normalized and convert
546  double normalizedValue = param->getNormalized();
547  return param->toPlain(normalizedValue);
548  }
549 
550 
552  virtual bool registerSubcontroller(std::string subcontrollerName, ICustomView* customViewConnector)
553  {
554  // --- do we have this in our map already?
555  CustomViewController* pCVC = nullptr;
556 
557  customViewControllerMap::const_iterator it = customSubControllerMap.find(subcontrollerName);
558  if (it != customSubControllerMap.end())
559  {
560  pCVC = it->second;
561  pCVC->setCustomViewPtr(customViewConnector);
562  }
563  else
564  {
565  pCVC = new CustomViewController(customViewConnector);
566  customSubControllerMap.insert(std::make_pair(subcontrollerName, pCVC));
567  }
568 
569  MessageInfo info(PLUGINGUI_REGISTER_SUBCONTROLLER);
570  info.inMessageString = subcontrollerName;
571  info.inMessageData = pCVC;
572 
573  if (pluginCore && pluginCore->processMessage(info))
574  return true;
575 
576  return false;
577  }
578 
580  virtual bool deRregisterSubcontroller(ICustomView* customViewConnector)
581  {
582  CustomViewController* pCVC = getCustomSubController(customViewConnector);
583  if (pCVC)
584  {
585  pCVC->clearCustomViewPtr();
586 
587  MessageInfo info(PLUGINGUI_DE_REGISTER_SUBCONTROLLER);
588  info.inMessageString = "";
589  info.inMessageData = pCVC;
590 
591  if (pluginCore && pluginCore->processMessage(info))
592  return true;
593  }
594 
595  return false;
596  }
597 
599  virtual bool registerCustomView(std::string customViewName, ICustomView* customViewConnector)
600  {
601  // --- do we have this in our map already?
602  CustomViewController* pCVC = nullptr;
603 
604  customViewControllerMap::const_iterator it = customViewMap.find(customViewName);
605  if (it != customViewMap.end())
606  {
607  pCVC = it->second;
608  pCVC->setCustomViewPtr(customViewConnector);
609  }
610  else
611  {
612  pCVC = new CustomViewController(customViewConnector);
613  customViewMap.insert(std::make_pair(customViewName, pCVC));
614  }
615 
616  MessageInfo info(PLUGINGUI_REGISTER_CUSTOMVIEW);
617  info.inMessageString = customViewName;
618  info.inMessageData = pCVC;
619 
620  if(pluginCore && pluginCore->processMessage(info))
621  return true;
622 
623  return false;
624  }
625 
627  virtual bool deRegisterCustomView(ICustomView* customViewConnector)
628  {
629  CustomViewController* pCVC = getCustomViewController(customViewConnector);
630  if (pCVC)
631  {
632  // --- clear it
633  pCVC->clearCustomViewPtr();
634 
635  MessageInfo info(PLUGINGUI_DE_REGISTER_CUSTOMVIEW);
636  info.inMessageString = "";
637  info.inMessageData = pCVC;
638 
639  if (pluginCore && pluginCore->processMessage(info))
640  return true;
641  }
642 
643  return false;
644  }
645 
647  virtual bool guiDidOpen()
648  {
649  if(!pluginCore) return false;
650  MessageInfo info(PLUGINGUI_DIDOPEN);
651  return pluginCore->processMessage(info);
652  }
653 
655  virtual bool guiWillClose()
656  {
657  if(!pluginCore) return false;
658 
659  for (customViewControllerMap::const_iterator it = customViewMap.begin(), end = customViewMap.end(); it != end; ++it)
660  {
661  it->second->clearCustomViewPtr();
662  }
663  for (customViewControllerMap::const_iterator it = customSubControllerMap.begin(), end = customSubControllerMap.end(); it != end; ++it)
664  {
665  it->second->clearCustomViewPtr();
666  }
667 
668  MessageInfo info(PLUGINGUI_WILLCLOSE);
669  return pluginCore->processMessage(info);
670  }
671 
673  virtual bool guiTimerPing()
674  {
675  if(!pluginCore) return false;
676  MessageInfo info(PLUGINGUI_TIMERPING);
677  return pluginCore->processMessage(info);
678  }
679 
681  virtual bool checkNonBoundValueChange(int tag, float normalizedValue)
682  {
683  if(!pluginCore) return false;
684 
685  // --- do any additional stuff here
686  // --- dispatch non-bound value changes directly to receiver
687 
688  return false;
689  }
690 
691 protected:
692  PluginCore* pluginCore = nullptr;
694 
695  // --- this is for supporting the persistent interface pointer for the core object
696  // and is required by ASPiK Specifications
697  typedef std::map<std::string, CustomViewController*> customViewControllerMap;
698  customViewControllerMap customViewMap;
699 
702  {
703  for (customViewControllerMap::const_iterator it = customViewMap.begin(), end = customViewMap.end(); it != end; ++it)
704  {
705  if (it->second->getCustomViewPtr() == customViewConnector)
706  return it->second;
707  }
708 
709  return nullptr;
710  }
711 
713 
716  {
717  for (customViewControllerMap::const_iterator it = customSubControllerMap.begin(), end = customSubControllerMap.end(); it != end; ++it)
718  {
719  if (it->second->getCustomViewPtr() == customViewConnector)
720  return it->second;
721  }
722 
723  return nullptr;
724  }
725 
726 };
727 
744 {
745 public:
746  VSTMIDIEventQueue(PluginCore* _pluginCore)
747  {
748  pluginCore = _pluginCore;
749  };
750 
751  virtual ~VSTMIDIEventQueue(){ clearMIDIProxyEvents(); }
752 
753 public:
754  // --- VST3 only for CC mess
755  void clearMIDIProxyEvents()
756  {
757  proxyMIDIEvents.clear();
758  }
759 
760  void addMIDIProxyEvent(midiEvent& event)
761  {
762  proxyMIDIEvents.push_back(event);
763  }
764 
766  void setEventList(IEventList* _inputEvents)
767  {
768  inputEvents = _inputEvents;
769  currentEventIndex = 0;
770  }
771 
773  virtual unsigned int getEventCount()
774  {
775  if (inputEvents)
776  return inputEvents->getEventCount();
777 
778  return 0;
779  }
780 
782  virtual bool fireMidiEvents(unsigned int sampleOffset)
783  {
784  if (sampleOffset == 0 && pluginCore)
785  {
786  uint32_t count = proxyMIDIEvents.size();
787  for (uint32_t i = 0; i < count; i++)
788  {
789  pluginCore->processMIDIEvent(proxyMIDIEvents[i]);
790  }
791  }
792 
793  if (!inputEvents)
794  return false;
795 
796  Event e = { 0 };
797  bool eventOccurred = false;
798  bool haveEvents = false;
799  if (inputEvents->getEvent(currentEventIndex, e) == kResultTrue)
800  haveEvents = true;
801  else
802  return false;
803 
804  const unsigned char MIDI_NOTE_OFF = 0x80;
805  const unsigned char MIDI_NOTE_ON = 0x90;
806  const unsigned char MIDI_POLY_PRESSURE = 0xA0;
807 
808  while (haveEvents)
809  {
810  if (inputEvents->getEvent(currentEventIndex, e) == kResultTrue)
811  {
812  if (e.sampleOffset != sampleOffset)
813  return false;
814 
815  // --- process Note On or Note Off messages
816  switch (e.type)
817  {
818  // --- NOTE ON
819  case Event::kNoteOnEvent:
820  {
821  midiEvent event;
822  event.midiMessage = (unsigned int)MIDI_NOTE_ON;
823  event.midiChannel = (unsigned int)e.noteOn.channel;
824  event.midiData1 = (unsigned int)e.noteOn.pitch;
825  event.midiData2 = (unsigned int)(127.0*e.noteOn.velocity);
826  event.midiSampleOffset = e.sampleOffset;
827  eventOccurred = true;
828 
829  // --- send to core for processing
830  if(pluginCore)
832  break;
833  }
834 
835  // --- NOTE OFF
836  case Event::kNoteOffEvent:
837  {
838  // --- get the channel/note/vel
839  midiEvent event;
840  event.midiMessage = (unsigned int)MIDI_NOTE_OFF;
841  event.midiChannel = (unsigned int)e.noteOff.channel;
842  event.midiData1 = (unsigned int)e.noteOff.pitch;
843  event.midiData2 = (unsigned int)(127.0*e.noteOff.velocity);
844  event.midiSampleOffset = e.sampleOffset;
845  eventOccurred = true;
846 
847  // --- send to core for processing
848  if(pluginCore)
850 
851  break;
852  }
853 
854  // --- polyphonic aftertouch 0xAn
855  case Event::kPolyPressureEvent:
856  {
857  midiEvent event;
858  event.midiMessage = (unsigned int)MIDI_POLY_PRESSURE;
859  event.midiChannel = (unsigned int)e.polyPressure.channel;
860  event.midiData1 = (unsigned int)e.polyPressure.pitch;
861  event.midiData2 = (unsigned int)(127.0*e.polyPressure.pressure);
862  event.midiSampleOffset = e.sampleOffset;
863  eventOccurred = true;
864 
865  // --- send to core for processing
866  if(pluginCore)
868 
869  break;
870  }
871  } // switch
872 
873  // --- have next event?
874  if (inputEvents->getEvent(currentEventIndex + 1, e) == kResultTrue)
875  {
876  if (e.sampleOffset == sampleOffset)
877  {
878  // --- avance current index
880  }
881  else
882  {
883  haveEvents = false;
884  currentEventIndex++; // setup for next time
885  }
886  }
887  else
888  haveEvents = false;
889  }
890  }
891 
892  return eventOccurred;
893  }
894 
895 protected:
896  PluginCore* pluginCore = nullptr;
897  IEventList* inputEvents = nullptr;
898  unsigned int currentEventIndex = 0;
899  std::vector<midiEvent> proxyMIDIEvents;
900 
901 };
902 
914 class VST3UpdateHandler: public FObject
915 {
916 public:
917  VST3UpdateHandler(VSTGUI::ControlUpdateReceiver* _receiver, VST3Plugin* _editController){ receiver = _receiver; editController = _editController; }
918  ~VST3UpdateHandler(){}
919 
920  virtual void PLUGIN_API update (FUnknown* changedUnknown, int32 message)
921  {
922  if(message == IDependent::kChanged && receiver && editController)
923  {
924  double normalizedValue = editController->getParamNormalized (receiver->getControlID());
925  receiver->updateControlsWithNormalizedValue(normalizedValue);
926  }
927  }
928 
929 private:
930  VSTGUI::ControlUpdateReceiver* receiver = nullptr;
931  VST3Plugin* editController = nullptr;
932 
933 };
934 
935 
947 class PluginEditor: public CPluginView, public VSTGUI::PluginGUI, public IGUIWindowFrame
948 {
949 public:
950  PluginEditor(VSTGUI::UTF8StringPtr _xmlFile, PluginCore* _pluginCore, GUIPluginConnector* _guiPluginConnector, PluginHostConnector* _pluginHostConnector, VST3Plugin* editController);
951  virtual ~PluginEditor();
952 
953  // --- aet of update handlers, specific to VST3: this will allow us to
954  // remotely update the GUI in a threadsafe and VST-approved manner
955  typedef std::map<int32_t, VST3UpdateHandler*> UpdaterHandlerMap;
956  UpdaterHandlerMap updateHandlers;
957 
958  //---from IPlugView------- VST3 Specific
959  IPlugFrame* plugFrame;
960  const ViewRect& getRect() const { return rect; }
961  void setRect(const ViewRect& r) { rect = r; }
962  bool isAttached() const { return systemWindow != 0; }
963  virtual void attachedToParent() override {}
964  virtual void removedFromParent() override {}
965 
966  virtual tresult PLUGIN_API attached(void* parent, FIDString type) override;
967  virtual tresult PLUGIN_API removed() override;
968  virtual tresult PLUGIN_API onWheel(float distance) override { return kResultFalse; }
969 
970  virtual tresult PLUGIN_API isPlatformTypeSupported(FIDString type) override;
971  virtual tresult PLUGIN_API onSize(ViewRect* newSize) override;
972  virtual tresult PLUGIN_API getSize(ViewRect* size) override;
973 
974  virtual tresult PLUGIN_API onFocus(TBool /*state*/) override { return kResultFalse; }
975  virtual tresult PLUGIN_API setFrame(IPlugFrame* frame) override;// { plugFrame = frame; return kResultTrue; }
976  virtual tresult PLUGIN_API canResize() override{ return kResultFalse /*kResultTrue*/; }
977  virtual tresult PLUGIN_API checkSizeConstraint(ViewRect* rect) override
978  {
979  if (showGUIEditor)
980  return kResultTrue;
981 
982  // --- clamp it
983  ViewRect viewRect = getRect();
984  rect->right = viewRect.right;
985  rect->bottom = viewRect.bottom;
986 
987  return kResultFalse;
988  }
989 
990  virtual bool setWindowFrameSize(double left = 0, double top = 0, double right = 0, double bottom = 0) override //CRect* newSize)
991  {
992  ViewRect vr(0, 0, right, bottom);
993  setRect(vr);
994  if (plugFrame)
995  plugFrame->resizeView(this, &vr);
996  return true;
997  }
998 
999  virtual bool getWindowFrameSize(double& left, double& top, double& right, double& bottom) override
1000  {
1001  ViewRect viewRect = getRect();
1002  left = 0.0;
1003  top = 0.0;
1004  right = viewRect.getWidth();
1005  bottom = viewRect.getHeight();
1006  return true;
1007  }
1008 
1009 protected:
1010  PluginCore* pluginCore = nullptr;
1014 };
1015 
1016 
1017 
1018 }}} // namespaces
1019 
1020 #endif
1021 
1022 
1023 
1024 
1025 
tresult PLUGIN_API getState(IBStream *fileStream) override
This is the WRITE part of the serialization process. We get the stream interface and use it to write ...
Definition: vst3plugin.cpp:654
Information that includes the message code as well as the message data.
Definition: pluginstructures.h:705
static const char * getPluginName()
static function for VST3 clsss factory
Definition: vst3plugin.cpp:1343
unsigned int sampleAccuracy
sample accurate parameter automation
Definition: vst3plugin.h:205
bool doControlUpdate(ProcessData &data)
Find and issue Control Changes.
Definition: vst3plugin.cpp:746
virtual void sendHostMessage(const HostMessageInfo &hostMessageInfo)
process a message; by default it processes sendGUIUpdate to safely send a parameter change event but ...
Definition: vst3plugin.h:378
void setEventList(IEventList *_inputEvents)
Definition: vst3plugin.h:766
tresult PLUGIN_API canProcessSampleSize(int32 symbolicSampleSize) override
Client queries us for our supported sample lengths.
Definition: vst3plugin.cpp:481
The PluginGUI object that maintains the entire GUI operation and has #defines to use with AAX...
Definition: plugingui.h:434
tresult PLUGIN_API setActive(TBool state) override
VST3 plugins may be turned on or off; you are supposed to dynamically delare stuff when activated the...
Definition: vst3plugin.cpp:555
bool getValueAtOffset(long int _sampleOffset, double _previousValue, double &_nextValue)
ASPiK support for sample accurate auatomation.
Definition: vst3plugin.cpp:1645
Interface for VST3 parameter value update queue (sample accurate automation)
Definition: pluginstructures.h:1649
The GUIPluginConnector interface creates a safe message mechanism for the GUI to issue requests to th...
Definition: vst3plugin.h:488
virtual tresult PLUGIN_API isPlatformTypeSupported(FIDString type) override
ASPiK support VST3 GUI - this wraps the ASPiK GUI so that it conforms to the IPlugView interface...
Definition: vst3plugin.cpp:1892
CustomViewController(ICustomView *_customViewIF)
Definition: vst3plugin.h:430
The VSTMIDIEventQueue interface queues incoming MIDI messages and blasts them out during the buffer p...
Definition: vst3plugin.h:743
virtual bool processMIDIEvent(midiEvent &event)
process a MIDI event
Definition: plugincore.cpp:606
uint32_t midiData1
BYTE data 1 as UINT.
Definition: pluginstructures.h:643
IPlugView *PLUGIN_API createView(const char *_name) override
creates the custom GUI view
Definition: vst3plugin.cpp:1054
tresult PLUGIN_API setComponentState(IBStream *fileStream) override
This is the serialization-read function so the GUI can be updated from a preset or startup...
Definition: vst3plugin.cpp:1127
interface file for ASPiK GUI object
void updateHostInfo(ProcessData &data, HostInfo *hostInfo)
update the incoming host data for the plugin core
Definition: vst3plugin.cpp:832
VST3Plugin * editController
parent VST3
Definition: vst3plugin.h:1013
virtual bool guiTimerPing()
Definition: vst3plugin.h:673
uint32_t controlID
ID value.
Definition: pluginstructures.h:352
PluginCore * pluginCore
the core
Definition: vst3plugin.h:1010
The VST3Plugin object is the ASPiK plugin shell for the VST3 API.
Definition: vst3plugin.h:70
bool showGUIEditor
show the GUI designer
Definition: plugingui.h:534
virtual bool processMessage(MessageInfo &messageInfo)
For Custom View and Custom Sub-Controller Operations.
Definition: plugincore.cpp:546
tresult PLUGIN_API terminate() override
object destroyer
Definition: vst3plugin.cpp:362
virtual double getNormalizedPluginParameter(int32_t controlID)
Definition: vst3plugin.h:527
VST3Plugin * editController
our parent plugin
Definition: vst3plugin.h:408
GUIPluginConnector * guiPluginConnector
GUI Plugin interface.
Definition: vst3plugin.h:1011
tresult PLUGIN_API setState(IBStream *fileStream) override
This is the READ part of the serialization process. We get the stream interface and use it to read fr...
Definition: vst3plugin.cpp:592
void updateControlsWithNormalizedValue(float normalizedValue, CControl *control=nullptr)
Definition: plugingui.h:212
virtual ~PluginEditor()
ASPiK support VST3 GUI - this wraps the ASPiK GUI so that it conforms to the IPlugView interface...
Definition: vst3plugin.cpp:1715
uint32 m_uLatencyInSamples
set in constructor with plugin
Definition: vst3plugin.h:165
virtual uint32 PLUGIN_API getTailSamples() override
Returns the tail-time in samples.
Definition: vst3plugin.cpp:528
int needsUpdate(int x, ParamValue &value)
ASPiK support for sample accurate auatomation.
Definition: vst3plugin.cpp:1584
const ICustomView * getCustomViewPtr()
Definition: vst3plugin.h:458
uint32_t midiMessage
BYTE message as UINT.
Definition: pluginstructures.h:641
virtual void updateView()
Definition: vst3plugin.h:434
unsigned int currentEventIndex
index of current event
Definition: vst3plugin.h:898
IEventList * inputEvents
the current event list for this buffer cycle
Definition: vst3plugin.h:897
virtual bool registerCustomView(std::string customViewName, ICustomView *customViewConnector)
Definition: vst3plugin.h:599
CustomViewController * getCustomSubController(ICustomView *customViewConnector)
Definition: vst3plugin.h:715
CustomViewController * getCustomViewController(ICustomView *customViewConnector)
Definition: vst3plugin.h:701
Information about a GUI update message; this is for sending GUI control information from the plugin c...
Definition: pluginstructures.h:443
PluginHostConnector * pluginHostConnector
Plugin Host interface.
Definition: vst3plugin.h:1012
std::map< std::string, CustomViewController * > customViewControllerMap
map of custom view controllers
Definition: vst3plugin.h:697
Custom interface so that GUI can pass information to plugin shell in a thread-safe manner...
Definition: pluginstructures.h:1539
The CustomViewController is part of the safe ICustomView feature in ASPiK. The CustomViewController m...
Definition: vst3plugin.h:426
virtual tresult receiveText(const char8 *text) override
VST3 messaging system - not used in ASPiK but here if you want to play with messaging.
Definition: vst3plugin.cpp:1102
static const char * getVendorURL()
static function for VST3 clsss factory
Definition: vst3plugin.cpp:1375
GUIPluginConnector(PluginCore *_pluginCore, VST3Plugin *_editController)
Definition: vst3plugin.h:492
VSTParamUpdateQueue(void)
ASPiK support for sample accurate auatomation.
Definition: vst3plugin.cpp:1428
virtual bool fireMidiEvents(unsigned int sampleOffset)
Definition: vst3plugin.h:782
virtual bool deRegisterCustomView(ICustomView *customViewConnector)
Definition: vst3plugin.h:627
virtual tresult PLUGIN_API onSize(ViewRect *newSize) override
ASPiK support VST3 GUI - this wraps the ASPiK GUI so that it conforms to the IPlugView interface...
Definition: vst3plugin.cpp:1929
Custom View interface to allow plugin core to create safe communication channels with GUI custom view...
Definition: pluginstructures.h:1461
VST3Plugin()
object constructor: because of class factory, do NOT use this for init; use initialize() instead ...
Definition: vst3plugin.cpp:36
virtual bool guiWillClose()
Definition: vst3plugin.h:655
virtual void pushDataValue(double data)
Definition: vst3plugin.h:441
Definition: pluginstructures.h:485
virtual ~GUIPluginConnector()
Definition: vst3plugin.h:499
Double buffered queue for MIDI messages.
Definition: pluginstructures.h:1627
virtual bool guiParameterChanged(int32_t controlID, double actualValue)
has nothing to do with actual variable or updated variable (binding)
Definition: plugincore.cpp:517
virtual void parameterChanged(int32_t controlID, double actualValue, double normalizedValue)
Definition: vst3plugin.h:512
The GUIPluginConnector interface creates a safe message mechanism for the GUI to issue requests to th...
Definition: AAXPluginParameters.h:599
virtual double getActualPluginParameter(int32_t controlID)
Definition: vst3plugin.h:538
The VST GUI for the plugin. This is needed because VST3 requires an IPlugView GUI, which is VST3 specific (involves VST3 SDK files)
Definition: vst3plugin.h:947
VST3Plugin * editController
the VST3
Definition: vst3plugin.h:693
virtual uint32 PLUGIN_API getLatencySamples() override
Definition: vst3plugin.h:168
void initialize(ParamValue _initialValue, ParamValue _minValue, ParamValue _maxValue, unsigned int *_sampleAccuracy)
ASPiK support for sample accurate auatomation.
Definition: vst3plugin.cpp:1454
virtual tresult PLUGIN_API getProgramName(ProgramListID listId, int32 programIndex, String128 name) override
Get preset name.
Definition: vst3plugin.cpp:1255
bool issueMIDICCProxyMessage(ParamID proxyParamID, ParamValue proxyParamValue)
Find and issue Control Changes.
Definition: vst3plugin.cpp:698
void setParamValueQueue(IParamValueQueue *_paramValueQueue, unsigned int _bufferSize)
ASPiK support for sample accurate auatomation.
Definition: vst3plugin.cpp:1475
virtual bool setWindowFrameSize(double left=0, double top=0, double right=0, double bottom=0) override
Definition: vst3plugin.h:990
virtual bool deRregisterSubcontroller(ICustomView *customViewConnector)
Definition: vst3plugin.h:580
virtual void sendMessage(void *data)
Definition: vst3plugin.h:448
static FUID * getFUID()
static function for VST3 clsss factory
Definition: vst3plugin.cpp:1323
The ControlUpdateReceiver object is the connection mechanism between PluginParameter objects and thei...
Definition: plugingui.h:89
void * inMessageData
incoming message data (interpretation depends on message)
Definition: pluginstructures.h:733
tresult PLUGIN_API setParamNormalizedFromFile(ParamID tag, ParamValue value)
helper function for setComponentState()
Definition: vst3plugin.cpp:1173
PluginCore * pluginCore
the core object
Definition: vst3plugin.h:692
std::vector< GUIParameter > guiParameters
list of updates
Definition: pluginstructures.h:461
tresult PLUGIN_API setupProcessing(ProcessSetup &newSetup) override
we get information about sample rate, bit-depth, etc...
Definition: vst3plugin.cpp:502
static CString getPluginType()
static function for VST3 clsss factory
Definition: vst3plugin.cpp:1407
static const char * getVendorEmail()
static function for VST3 clsss factory
Definition: vst3plugin.cpp:1391
PluginEditor(VSTGUI::UTF8StringPtr _xmlFile, PluginCore *_pluginCore, GUIPluginConnector *_guiPluginConnector, PluginHostConnector *_pluginHostConnector, VST3Plugin *editController)
ASPiK support VST3 GUI - this wraps the ASPiK GUI so that it conforms to the IPlugView interface...
Definition: vst3plugin.cpp:1694
virtual tresult PLUGIN_API getSize(ViewRect *size) override
ASPiK support VST3 GUI - this wraps the ASPiK GUI so that it conforms to the IPlugView interface...
Definition: vst3plugin.cpp:1951
tresult PLUGIN_API initialize(FUnknown *context) override
object initializer
Definition: vst3plugin.cpp:82
virtual unsigned int getEventCount()
Definition: vst3plugin.h:773
Definition: channelformats.h:32
The PluginHostConnector implements the IPluginHostConnector interface for the plugin shell object...
Definition: vst3plugin.h:367
void setCustomViewPtr(ICustomView *_customViewIF)
Definition: vst3plugin.h:455
virtual tresult PLUGIN_API getMidiControllerAssignment(int32 busIndex, int16 channel, CtrlNumber midiControllerNumber, ParamID &id) override
The client queries this 129 times for 130 possible control messages, see ivstsmidicontrollers.h for the VST defines for kPitchBend, kCtrlModWheel, etc... for each MIDI Channel in our Event Bus.
Definition: vst3plugin.cpp:1017
The PluginCore object is the default PluginBase derived object for ASPiK projects. Note that you are fre to change the name of this object (as long as you change it in the compiler settings, etc...)
Definition: plugincore.h:43
void setSlope()
ASPiK support for sample accurate auatomation.
Definition: vst3plugin.cpp:1495
virtual bool getWindowFrameSize(double &left, double &top, double &right, double &bottom) override
Definition: vst3plugin.h:999
virtual void sendMessage(void *data)
Definition: pluginstructures.h:1482
void clearCustomViewPtr()
Definition: vst3plugin.h:461
virtual tresult PLUGIN_API removed() override
ASPiK support VST3 GUI - this wraps the ASPiK GUI so that it conforms to the IPlugView interface...
Definition: vst3plugin.cpp:1847
Information that defines a single GUI parameter&#39;s possible values and ID.
Definition: pluginstructures.h:331
virtual bool registerSubcontroller(std::string subcontrollerName, ICustomView *customViewConnector)
Definition: vst3plugin.h:552
~VST3Plugin()
object destructor: because of class factory, do NOT use this for destruction; use terminate() instead...
Definition: vst3plugin.cpp:63
tresult PLUGIN_API process(ProcessData &data) override
the VST3 audio processing function
Definition: vst3plugin.cpp:861
Custom interface to allow resizing of GUI window; this is mainly used for the GUI designer...
Definition: pluginstructures.h:1496
base class interface file for ASPiK plugincore object
double actualValue
actual value
Definition: pluginstructures.h:353
Information from the host that is updated on each buffer process cycle; includes BPM, time signature, SMPTE and other data. The values in the stock structure are consistent across most APIs, however others may be added (commnted out here)
Definition: pluginstructures.h:973
ParamValue interpolate(int x1, int x2, ParamValue y1, ParamValue y2, int x)
ASPiK support for sample accurate auatomation.
Definition: vst3plugin.cpp:1563
customViewControllerMap customSubControllerMap
map of custom sub-controllers
Definition: vst3plugin.h:712
virtual bool checkNonBoundValueChange(int tag, float normalizedValue)
Definition: vst3plugin.h:681
virtual void updateView()=0
static FUnknown * createInstance(void *context)
Definition: vst3plugin.h:154
std::string inMessageString
incoming message data as a std::string (interpretation depends on message)
Definition: pluginstructures.h:736
Custom interface to send the plugin shell a message from plugin core.
Definition: pluginstructures.h:1609
tresult PLUGIN_API setParamNormalized(ParamID tag, ParamValue value) override
This is overridden for selecting a preset, this is also called when automating parameters.
Definition: vst3plugin.cpp:1200
The PluginHostConnector implements the IPluginHostConnector interface for the plugin shell object...
Definition: AAXPluginParameters.h:479
virtual tresult PLUGIN_API attached(void *parent, FIDString type) override
ASPiK support VST3 GUI - this wraps the ASPiK GUI so that it conforms to the IPlugView interface...
Definition: vst3plugin.cpp:1748
void updateMeters(ProcessData &data, bool forceOff=false)
update the outbound VST3 parameters that correspond to plugin meter variables
Definition: vst3plugin.cpp:978
VSTParamUpdateQueue ** m_pParamUpdateQueueArray
sample accurate parameter automation
Definition: vst3plugin.h:204
static const char * getVendorName()
static function for VST3 clsss factory
Definition: vst3plugin.cpp:1359
Little update handler object for VST-approved GUI updating.
Definition: vst3plugin.h:914
bool getNextValue(double &_nextValue)
ASPiK support for sample accurate auatomation.
Definition: vst3plugin.cpp:1670
bool enableSAAVST3
sample accurate parameter automation
Definition: vst3plugin.h:206
virtual tresult PLUGIN_API setFrame(IPlugFrame *frame) override
ASPiK support VST3 GUI - this wraps the ASPiK GUI so that it conforms to the IPlugView interface...
Definition: vst3plugin.cpp:1731
tresult PLUGIN_API setBusArrangements(SpeakerArrangement *inputs, int32 numIns, SpeakerArrangement *outputs, int32 numOuts) override
Client queries us for our supported Busses; this is where you can modify to support mono...
Definition: vst3plugin.cpp:413
PluginCore * pluginCore
the core object
Definition: vst3plugin.h:896
The VSTParamUpdateQueue object maintains a parameter update queue for one ASPiK PluginParameter objec...
Definition: vst3plugin.h:309
virtual void PLUGIN_API update(FUnknown *changedUnknown, int32 message) override
Toggle preset.
Definition: vst3plugin.cpp:1284
int32_t getControlID()
Definition: plugingui.h:321
virtual void pushDataValue(double data)
Definition: pluginstructures.h:1472
Information about a MIDI event.
Definition: pluginstructures.h:561
unsigned int getParameterIndex()
ASPiK support for sample accurate auatomation.
Definition: vst3plugin.cpp:1629
virtual bool guiDidOpen()
Definition: vst3plugin.h:647