iPlug2 - C++ Audio Plug-in Framework
IPlugAPIBase.cpp
Go to the documentation of this file.
1 /*
2  ==============================================================================
3 
4  This file is part of the iPlug 2 library. Copyright (C) the iPlug 2 developers.
5 
6  See LICENSE.txt for more info.
7 
8  ==============================================================================
9 */
10 
16 #include <cmath>
17 #include <cstdio>
18 #include <ctime>
19 #include <cassert>
20 
21 #include "IPlugAPIBase.h"
22 
23 using namespace iplug;
24 
25 IPlugAPIBase::IPlugAPIBase(Config c, EAPI plugAPI)
26  : IPluginBase(c.nParams, c.nPresets)
27 {
28  mUniqueID = c.uniqueID;
29  mMfrID = c.mfrID;
30  mVersion = c.vendorVersion;
31  mPluginName.Set(c.pluginName, MAX_PLUGIN_NAME_LEN);
32  mProductName.Set(c.productName, MAX_PLUGIN_NAME_LEN);
33  mMfrName.Set(c.mfrName, MAX_PLUGIN_NAME_LEN);
34  mHasUI = c.plugHasUI;
35  mHostResize = c.plugHostResize;
36  SetEditorSize(c.plugWidth, c.plugHeight);
37  SetSizeConstraints(c.plugMinWidth, c.plugMaxWidth, c.plugMinHeight, c.plugMaxHeight);
38  mStateChunks = c.plugDoesChunks;
39  mAPI = plugAPI;
40  mBundleID.Set(c.bundleID);
41 
42  Trace(TRACELOC, "%s:%s", c.pluginName, CurrentTime());
43 
44  mParamDisplayStr.Set("", MAX_PARAM_DISPLAY_LEN);
45 }
46 
47 IPlugAPIBase::~IPlugAPIBase()
48 {
49  if(mTimer)
50  {
51  mTimer->Stop();
52  }
53 
54  TRACE
55 }
56 
57 void IPlugAPIBase::OnHostRequestingImportantParameters(int count, WDL_TypedBuf<int>& results)
58 {
59  if(NParams() > count)
60  {
61  for (int i = 0; i < count; i++)
62  results.Add(i);
63  }
64 }
65 
67 {
68  mTimer = std::unique_ptr<Timer>(Timer::Create(std::bind(&IPlugAPIBase::OnTimer, this, std::placeholders::_1), IDLE_TIMER_RATE));
69 }
70 
71 bool IPlugAPIBase::CompareState(const uint8_t* pIncomingState, int startPos) const
72 {
73  bool isEqual = true;
74 
75  const double* data = (const double*) pIncomingState + startPos;
76 
77  // dirty hack here because protools treats param values as 32 bit int and in IPlug they are 64bit float
78  // if we memcmp() the incoming state with the current they may have tiny differences due to the quantization
79  for (int i = 0; i < NParams(); i++)
80  {
81  float v = (float) GetParam(i)->Value();
82  float vi = (float) *(data++);
83 
84  isEqual &= (std::fabs(v - vi) < 0.00001);
85  }
86 
87  return isEqual;
88 }
89 
90 bool IPlugAPIBase::EditorResizeFromUI(int viewWidth, int viewHeight, bool needsPlatformResize)
91 {
92  if (needsPlatformResize)
93  return EditorResize(viewWidth, viewHeight);
94  else
95  return true;
96 }
97 
98 #pragma mark -
99 
100 void IPlugAPIBase::SetHost(const char* host, int version)
101 {
102  assert(mHost == kHostUninit);
103 
104  mHost = LookUpHost(host);
105  mHostVersion = version;
106 
107  WDL_String vStr;
108  GetVersionStr(version, vStr);
109  Trace(TRACELOC, "host_%sknown:%s:%s", (mHost == kHostUnknown ? "un" : ""), host, vStr.Get());
110 
113 }
114 
115 void IPlugAPIBase::SetParameterValue(int idx, double normalizedValue)
116 {
117  Trace(TRACELOC, "%d:%f", idx, normalizedValue);
118  GetParam(idx)->SetNormalized(normalizedValue);
119  InformHostOfParamChange(idx, normalizedValue);
120  OnParamChange(idx, kUI);
121 }
122 
124 {
125  for (int p = 0; p < NParams(); p++)
126  {
127  double normalizedValue = GetParam(p)->GetNormalized();
128  InformHostOfParamChange(p, normalizedValue);
129  }
130 }
131 
132 void IPlugAPIBase::SendParameterValueFromAPI(int paramIdx, double value, bool normalized)
133 {
134  if (normalized)
135  value = GetParam(paramIdx)->FromNormalized(value);
136 
137  mParamChangeFromProcessor.Push(ParamTuple { paramIdx, value } );
138 }
139 
140 void IPlugAPIBase::OnTimer(Timer& t)
141 {
142  if(HasUI())
143  {
144 // VST3 ********************************************************************************
145 #if defined VST3P_API || defined VST3_API
146  while (mMidiMsgsFromProcessor.ElementsAvailable())
147  {
148  IMidiMsg msg;
149  mMidiMsgsFromProcessor.Pop(msg);
150 #ifdef VST3P_API // distributed
151  TransmitMidiMsgFromProcessor(msg);
152 #else
153  SendMidiMsgFromDelegate(msg);
154 #endif
155  }
156 
157  while (mSysExDataFromProcessor.ElementsAvailable())
158  {
159  SysExData msg;
160  mSysExDataFromProcessor.Pop(msg);
161 #ifdef VST3P_API // distributed
162  TransmitSysExDataFromProcessor(msg);
163 #else
164  SendSysexMsgFromDelegate({msg.mOffset, msg.mData, msg.mSize});
165 #endif
166  }
167 // !VST3 ******************************************************************************
168 #else
169  while(mParamChangeFromProcessor.ElementsAvailable())
170  {
171  ParamTuple p;
172  mParamChangeFromProcessor.Pop(p);
173  SendParameterValueFromDelegate(p.idx, p.value, false);
174  }
175 
176  while (mMidiMsgsFromProcessor.ElementsAvailable())
177  {
178  IMidiMsg msg;
179  mMidiMsgsFromProcessor.Pop(msg);
180  SendMidiMsgFromDelegate(msg);
181  }
182 
183  while (mSysExDataFromProcessor.ElementsAvailable())
184  {
185  SysExData msg;
186  mSysExDataFromProcessor.Pop(msg);
187  SendSysexMsgFromDelegate({msg.mOffset, msg.mData, msg.mSize});
188  }
189 #endif
190  }
191 
192  OnIdle();
193 }
194 
195 void IPlugAPIBase::SendMidiMsgFromUI(const IMidiMsg& msg)
196 {
197  DeferMidiMsg(msg); // queue the message so that it will be handled by the processor
198  EDITOR_DELEGATE_CLASS::SendMidiMsgFromUI(msg); // for remote editors
199 }
200 
201 void IPlugAPIBase::SendSysexMsgFromUI(const ISysEx& msg)
202 {
203  DeferSysexMsg(msg); // queue the message so that it will be handled by the processor
204  EDITOR_DELEGATE_CLASS::SendSysexMsgFromUI(msg); // for remote editors
205 }
206 
207 void IPlugAPIBase::SendArbitraryMsgFromUI(int msgTag, int ctrlTag, int dataSize, const void* pData)
208 {
209  OnMessage(msgTag, ctrlTag, dataSize, pData); // IPlugAPIBase implementation handles non distributed plug-ins - just call OnMessage() directly
210 
211  EDITOR_DELEGATE_CLASS::SendArbitraryMsgFromUI(msgTag, ctrlTag, dataSize, pData);
212 }
virtual void OnHostRequestingImportantParameters(int count, WDL_TypedBuf< int > &results)
Called by AUv3 plug-ins to get the "overview parameters".
Encapsulates a MIDI message and provides helper functions.
Definition: IPlugMidi.h:30
virtual void SendParameterValueFromAPI(int paramIdx, double value, bool normalized)
This is called from the plug-in API class in order to update UI controls linked to plug-in parameters...
void InformHostOfParamChange(int idx, double normalizedValue) override
Implemented by the API class, called by the UI via SetParameterValue() with the value of a parameter ...
Definition: IPlugAAX.cpp:569
virtual void HostSpecificInit()
This method is implemented in some API classes, in order to do specific initialisation for particular...
Definition: IPlugAPIBase.h:151
bool EditorResize(int viewWidth, int viewHeight) override
Implementations call into the APIs resize hooks returns a bool to indicate whether the DAW or plugin ...
Definition: IPlugAAX.cpp:581
Base class for timer.
Definition: IPlugTimer.h:39
virtual bool CompareState(const uint8_t *pIncomingState, int startPos) const
Override this method to implement a custom comparison of incoming state data with your plug-ins state...
void CreateTimer()
Called by the API class to create the timer that pumps the parameter/message queues.
virtual void DirtyParametersFromUI() override
In a distributed VST3 or WAM plugin, if you modify the parameters on the UI side (e.g.
static void GetVersionStr(int versionInteger, WDL_String &str)
Helper function to get the semantic version number as a string from an integer.
In certain cases we need to queue parameter changes for transferral between threads.
Definition: IPlugStructs.h:32
virtual void OnIdle()
Override this method to get an "idle"" call on the main thread.
Definition: IPlugAPIBase.h:107
The base class of an IPlug plug-in, which interacts with the different plug-in APIs.
bool HasUI() const
A struct for dealing with SysEx messages.
Definition: IPlugMidi.h:538
This structure is used when queueing Sysex messages.
Definition: IPlugStructs.h:44
static EHost LookUpHost(const char *inHost)
Gets the host ID from a human-readable name.
void SetParameterValue(int paramIdx, double normalizedValue)
SetParameterValue is called from the UI in the middle of a parameter change gesture (possibly via del...
Base class that contains plug-in info and state manipulation methods.
void SetHost(const char *host, int version)
Called to set the name of the current host, if known (calls on to HostSpecificInit() and OnHostIdenti...
virtual void OnHostIdentified()
Implement this to do something specific when IPlug becomes aware of the particular host that is hosti...
Definition: IPlugAPIBase.h:69