iPlug2 - C++ Audio Plug-in Framework
Loading...
Searching...
No Matches
IPlugAAX.cpp
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
11#include "IPlugAAX.h"
12#include "IPlugAAX_view_interface.h"
13#include "AAX_CBinaryTaperDelegate.h"
14#include "AAX_CBinaryDisplayDelegate.h"
15#include "AAX_CStringDisplayDelegate.h"
16#include "AAX_CLinearTaperDelegate.h"
17
18// custom taper for IParam::kTypeDouble
19#include "IPlugAAX_TaperDelegate.h"
20#include "AAX_CNumberDisplayDelegate.h"
21#include "AAX_CUnitDisplayDelegateDecorator.h"
22
23using namespace iplug;
24
25AAX_CEffectParameters *AAX_CALLBACK IPlugAAX::Create()
26{
27 return MakePlug(InstanceInfo());
28}
29
30void AAX_CEffectGUI_IPLUG::CreateViewContents()
31{
32 TRACE
33 mPlug = dynamic_cast<IPlugAAX*>(GetEffectParameters());
34}
35
36void AAX_CEffectGUI_IPLUG::CreateViewContainer()
37{
38 TRACE
39
40 void* pWindow = GetViewContainerPtr();
41
42 if (pWindow && mPlug->HasUI())
43 {
44 mPlug->OpenWindow(pWindow);
45
46 IPlugAAXView_Interface* pViewInterface = (IPlugAAXView_Interface*) mPlug->GetAAXViewInterface();
47
48 if(pViewInterface)
49 pViewInterface->SetViewContainer(GetViewContainer());
50 }
51}
52
53void AAX_CEffectGUI_IPLUG::DeleteViewContainer()
54{
55 mPlug->CloseWindow();
56}
57
58AAX_Result AAX_CEffectGUI_IPLUG::GetViewSize(AAX_Point* pNewViewSize) const
59{
60 if (mPlug->HasUI())
61 {
62 pNewViewSize->horz = (float) mPlug->GetEditorWidth();
63 pNewViewSize->vert = (float) mPlug->GetEditorHeight();
64 }
65
66 return AAX_SUCCESS;
67}
68
69AAX_Result AAX_CEffectGUI_IPLUG::ParameterUpdated(AAX_CParamID paramID)
70{
71 return AAX_SUCCESS;
72}
73
74AAX_IEffectGUI* AAX_CALLBACK AAX_CEffectGUI_IPLUG::Create()
75{
76 return new AAX_CEffectGUI_IPLUG;
77}
78
79AAX_Result AAX_CEffectGUI_IPLUG::SetControlHighlightInfo(AAX_CParamID paramID, AAX_CBoolean iIsHighlighted, AAX_EHighlightColor iColor)
80{
81 IPlugAAXView_Interface* pViewInterface = (IPlugAAXView_Interface*) mPlug->GetAAXViewInterface();
82
83 if (pViewInterface)
84 {
85 int paramIdx = atoi(paramID) - kAAXParamIdxOffset;
86
87 if (paramIdx != kNoParameter)
88 {
89 pViewInterface->SetPTParameterHighlight(paramIdx, (bool) iIsHighlighted, (int) iColor);
90 }
91
92 return AAX_SUCCESS;
93 }
94
95 return AAX_ERROR_INVALID_PARAMETER_ID;
96}
97
98#pragma mark IPlugAAX Construct
99
100IPlugAAX::IPlugAAX(const InstanceInfo& info, const Config& config)
101: IPlugAPIBase(config, kAPIAAX)
102, IPlugProcessor(config, kAPIAAX)
103{
104 Trace(TRACELOC, "%s%s", config.pluginName, config.channelIOStr);
105
106 SetChannelConnections(ERoute::kInput, 0, MaxNChannels(ERoute::kInput), true);
107 SetChannelConnections(ERoute::kOutput, 0, MaxNChannels(ERoute::kOutput), true);
108
109 SetBlockSize(DEFAULT_BLOCK_SIZE);
110 InitLatencyDelay();
111
112 mMaxNChansForMainInputBus = MaxNChannelsForBus(kInput, 0);
113
114 CreateTimer();
115}
116
117IPlugAAX::~IPlugAAX()
118{
119 mParamIDs.Empty(true);
120}
121
122AAX_Result IPlugAAX::EffectInit()
123{
124 TRACE
125
126 if (GetHost() == kHostUninit)
127 SetHost("ProTools", 0); // TODO:vendor version correct?
128
129 AAX_CString bypassID = NULL;
130 this->GetMasterBypassParameter(&bypassID);
131 mBypassParameter = new AAX_CParameter<bool>(bypassID.CString(),
132 AAX_CString("Master Bypass"),
133 false,
134 AAX_CBinaryTaperDelegate<bool>(),
135 AAX_CBinaryDisplayDelegate<bool>("bypass", "on"),
136 true);
137 mBypassParameter->SetNumberOfSteps(2);
138 mBypassParameter->SetType(AAX_eParameterType_Discrete);
139 mParameterManager.AddParameter(mBypassParameter);
140
141 for (int i=0; i<NParams(); i++)
142 {
143 IParam* pParam = GetParam(i);
144 AAX_IParameter* pAAXParam = nullptr;
145
146 WDL_String* pParamIDStr = new WDL_String("_", 1);
147 pParamIDStr->SetFormatted(MAX_AAX_PARAMID_LEN, "%i", i+kAAXParamIdxOffset);
148 mParamIDs.Add(pParamIDStr);
149
150 switch (pParam->Type())
151 {
152 case IParam::kTypeDouble:
153 {
154 pAAXParam = new AAX_CParameter<double>(pParamIDStr->Get(),
155 AAX_CString(pParam->GetName()),
156 pParam->GetDefault(),
157 AAX_CIPlugTaperDelegate<double>(*pParam),
158 AAX_CUnitDisplayDelegateDecorator<double>(AAX_CNumberDisplayDelegate<double>(), AAX_CString(pParam->GetLabel())),
159 pParam->GetCanAutomate());
160
161 pAAXParam->SetNumberOfSteps(128); // TODO: check this https://developer.digidesign.com/index.php?L1=5&L2=13&L3=56
162 pAAXParam->SetType(AAX_eParameterType_Continuous);
163
164 break;
165 }
166 case IParam::kTypeInt:
167 {
168 pAAXParam = new AAX_CParameter<int>(pParamIDStr->Get(),
169 AAX_CString(pParam->GetName()),
170 (int)pParam->GetDefault(),
171 AAX_CLinearTaperDelegate<int,1>((int)pParam->GetMin(), (int)pParam->GetMax()),
172 AAX_CUnitDisplayDelegateDecorator<int>(AAX_CNumberDisplayDelegate<int,0>(), AAX_CString(pParam->GetLabel())),
173 pParam->GetCanAutomate());
174
175 pAAXParam->SetNumberOfSteps(128);
176 pAAXParam->SetType(AAX_eParameterType_Continuous);
177
178 break;
179 }
180 case IParam::kTypeEnum:
181 case IParam::kTypeBool:
182 {
183 int nTexts = pParam->NDisplayTexts();
184
185 std::map<int, AAX_CString> displayTexts;
186
187 for (int j=0; j<pParam->NDisplayTexts(); j++)
188 {
189 double value;
190 const char* text = pParam->GetDisplayTextAtIdx(j, &value);
191
192 displayTexts.insert(std::pair<int, AAX_CString>(value, AAX_CString(text)));
193 }
194
195 pAAXParam = new AAX_CParameter<int>(pParamIDStr->Get(),
196 AAX_CString(pParam->GetName()),
197 (int)pParam->GetDefault(),
198 AAX_CLinearTaperDelegate<int,1>((int) pParam->GetMin(), (int) pParam->GetMax()),
199 AAX_CStringDisplayDelegate<int>(displayTexts),
200 pParam->GetCanAutomate());
201
202 pAAXParam->SetNumberOfSteps(nTexts);
203 pAAXParam->SetType(AAX_eParameterType_Discrete);
204
205 break;
206 }
207 default:
208 break;
209 }
210
211 mParameterManager.AddParameter(pAAXParam);
212 }
213
214 AAX_CSampleRate sr;
215 Controller()->GetSampleRate(&sr);
216 SetSampleRate(sr);
217 OnReset();
218
219 return AAX_SUCCESS;
220}
221
222AAX_Result IPlugAAX::UpdateParameterNormalizedValue(AAX_CParamID paramID, double iValue, AAX_EUpdateSource iSource)
223{
224 TRACE
225
226 AAX_Result result = AAX_SUCCESS;
227
228 AAX_IParameter* pAAXParameter = mParameterManager.GetParameterByID(paramID);
229
230 if (pAAXParameter == nullptr)
231 return AAX_ERROR_INVALID_PARAMETER_ID;
232
233 // Store the value into the AAX parameter
234 pAAXParameter->UpdateNormalizedValue(iValue);
235
236 int paramIdx = atoi(paramID) - kAAXParamIdxOffset;
237
238 if ((paramIdx > kNoParameter) && (paramIdx < NParams()))
239 {
240 ENTER_PARAMS_MUTEX
241 GetParam(paramIdx)->SetNormalized(iValue);
242 SendParameterValueFromAPI(paramIdx, iValue, true);
243 OnParamChange(paramIdx, kHost);
244 LEAVE_PARAMS_MUTEX
245 }
246
247 // Now the control has changed
248 result = mPacketDispatcher.SetDirty(paramID);
249
250 mNumPlugInChanges++;
251
252 return result;
253}
254
255void IPlugAAX::RenderAudio(AAX_SIPlugRenderInfo* pRenderInfo, const TParamValPair* inSynchronizedParamValues[], int32_t inNumSynchronizedParamValues)
256{
257 TRACE
258
259 // Get bypass parameter value
260 bool bypass;
261 mBypassParameter->GetValueAsBool(&bypass);
262
263 AAX_EStemFormat inFormat, outFormat;
264 Controller()->GetInputStemFormat(&inFormat);
265 Controller()->GetOutputStemFormat(&outFormat);
266
267 if (DoesMIDIIn())
268 {
269 AAX_IMIDINode* pMidiIn = pRenderInfo->mInputNode;
270 AAX_CMidiStream* pMidiBuffer = pMidiIn->GetNodeBuffer();
271 AAX_CMidiPacket* pMidiPacket = pMidiBuffer->mBuffer;
272 uint32_t packets_count = pMidiBuffer->mBufferSize;
273
274 for (auto i = 0; i<packets_count; i++, pMidiPacket++)
275 {
276 IMidiMsg msg(pMidiPacket->mTimestamp, pMidiPacket->mData[0], pMidiPacket->mData[1], pMidiPacket->mData[2]);
277 ProcessMidiMsg(msg);
278 mMidiMsgsFromProcessor.Push(msg);
279 }
280 }
281
282 AAX_IMIDINode* pTransportNode = pRenderInfo->mTransportNode;
283 mTransport = pTransportNode->GetTransport();
284
285 int32_t numSamples = *(pRenderInfo->mNumSamples);
286 int32_t numInChannels = AAX_STEM_FORMAT_CHANNEL_COUNT(inFormat);
287 int32_t numOutChannels = AAX_STEM_FORMAT_CHANNEL_COUNT(outFormat);
288
289 if (numSamples > GetBlockSize())
290 {
291 SetBlockSize(numSamples);
292 OnReset();
293 }
294
295 if (!IsInstrument())
296 {
297 SetChannelConnections(ERoute::kInput, 0, numInChannels, true);
298 SetChannelConnections(ERoute::kInput, numInChannels, MaxNChannels(ERoute::kInput) - numInChannels, false);
299
300 int sideChainChannel = HasSidechainInput() ? *pRenderInfo->mSideChainP : 0;
301
302 if (sideChainChannel)
303 {
304 SetChannelConnections(ERoute::kInput, mMaxNChansForMainInputBus, 1, true);
305 AttachBuffers(ERoute::kInput, 0, numInChannels, pRenderInfo->mAudioInputs, numSamples);
306 AttachBuffers(ERoute::kInput, mMaxNChansForMainInputBus, 1, pRenderInfo->mAudioInputs + sideChainChannel, numSamples);
307 }
308 else
309 AttachBuffers(ERoute::kInput, 0, numInChannels, pRenderInfo->mAudioInputs, numSamples);
310 }
311
312 int maxNOutChans = MaxNChannels(ERoute::kOutput);
313
314 SetChannelConnections(ERoute::kOutput, 0, maxNOutChans, true);
315
316 if (MaxNBuses(kOutput) == 1) // single output bus, only connect available channels
317 {
318 SetChannelConnections(ERoute::kOutput, numOutChannels, maxNOutChans - numOutChannels, false);
319 AttachBuffers(ERoute::kOutput, 0, maxNOutChans, pRenderInfo->mAudioOutputs, numSamples);
320 }
321 else // multi output buses, connect all buffers including AOS
322 {
323 AttachBuffers(ERoute::kOutput, 0, maxNOutChans, pRenderInfo->mAudioOutputs, numSamples);
324 }
325
326 if (bypass)
327 PassThroughBuffers(0.0f, numSamples);
328 else
329 {
330 int32_t num, denom;
331 int64_t ppqPos, samplePos, cStart, cEnd;
332 ITimeInfo timeInfo;
333
334 mTransport->GetCurrentTempo(&timeInfo.mTempo);
335 mTransport->IsTransportPlaying(&timeInfo.mTransportIsRunning);
336
337 mTransport->GetCurrentMeter(&num, &denom);
338 timeInfo.mNumerator = (int) num;
339 timeInfo.mDenominator = (int) denom;
340
341 mTransport->GetCurrentTickPosition(&ppqPos);
342 timeInfo.mPPQPos = (double) ppqPos / 960000.0;
343
344 if(timeInfo.mPPQPos < 0)
345 timeInfo.mPPQPos = 0;
346
347 mTransport->GetCurrentNativeSampleLocation(&samplePos);
348 timeInfo.mSamplePos = (double) samplePos;
349
350 mTransport->GetCurrentLoopPosition(&timeInfo.mTransportLoopEnabled, &cStart, &cEnd);
351 timeInfo.mCycleStart = (double) cStart / 960000.0;
352 timeInfo.mCycleEnd = (double) cEnd / 960000.0;
353
354 SetTimeInfo(timeInfo);
355 //timeInfo.mLastBar ??
356
357 IMidiMsg msg;
358
359 while (mMidiMsgsFromEditor.Pop(msg))
360 {
361 ProcessMidiMsg(msg);
362 }
363
364 ENTER_PARAMS_MUTEX
365 ProcessBuffers(0.0f, numSamples);
366 LEAVE_PARAMS_MUTEX
367 }
368
369 // Midi Out
370 if (DoesMIDIOut())
371 {
372 AAX_IMIDINode* midiOut = pRenderInfo->mOutputNode;
373
374 if(midiOut)
375 {
376 //MIDI
377 if (!mMidiOutputQueue.Empty())
378 {
379 while (!mMidiOutputQueue.Empty())
380 {
381 IMidiMsg& msg = mMidiOutputQueue.Peek();
382
383 AAX_CMidiPacket packet;
384
385 packet.mIsImmediate = true; // TODO: how does this affect sample accuracy?
386
387 packet.mTimestamp = (uint32_t) msg.mOffset;
388 packet.mLength = 3;
389
390 packet.mData[0] = msg.mStatus;
391 packet.mData[1] = msg.mData1;
392 packet.mData[2] = msg.mData2;
393
394 midiOut->PostMIDIPacket (&packet);
395
396 mMidiOutputQueue.Remove();
397 }
398 }
399
400 mMidiOutputQueue.Flush(numSamples);
401
402 //Output SYSEX from the editor, which has bypassed ProcessSysEx()
403 if(mSysExDataFromEditor.ElementsAvailable())
404 {
405 while (mSysExDataFromEditor.Pop(mSysexBuf))
406 {
407 int numPackets = (int) ceil((float) mSysexBuf.mSize/4.); // each packet can store 4 bytes of data
408 int bytesPos = 0;
409
410 for (int p = 0; p < numPackets; p++)
411 {
412 AAX_CMidiPacket packet;
413
414 packet.mTimestamp = (uint32_t) mSysexBuf.mOffset;
415 packet.mIsImmediate = true;
416
417 int b = 0;
418
419 while (b < 4 && bytesPos < mSysexBuf.mSize)
420 {
421 packet.mData[b++] = mSysexBuf.mData[bytesPos++];
422 }
423
424 packet.mLength = (uint32_t) b;
425
426 midiOut->PostMIDIPacket (&packet);
427 }
428 }
429 }
430 }
431 }
432}
433
434AAX_Result IPlugAAX::GetChunkIDFromIndex(int32_t index, AAX_CTypeID* pChunkID) const
435{
436 if (index != 0)
437 {
438 *pChunkID = AAX_CTypeID(0);
439 return AAX_ERROR_INVALID_CHUNK_INDEX;
440 }
441
442 *pChunkID = GetUniqueID();
443
444 return AAX_SUCCESS;
445}
446
447AAX_Result IPlugAAX::GetChunkSize(AAX_CTypeID chunkID, uint32_t* pSize) const
448{
449 TRACE
450
451 if (chunkID == GetUniqueID())
452 {
453 IByteChunk chunk;
454
455 //IByteChunk::InitChunkWithIPlugVer(&IPlugChunk);
456
457 if (SerializeState(chunk))
458 {
459 *pSize = chunk.Size();
460 }
461
462 return AAX_SUCCESS;
463 }
464 else
465 {
466 *pSize = 0;
467 return AAX_ERROR_INVALID_CHUNK_ID;
468 }
469}
470
471AAX_Result IPlugAAX::GetChunk(AAX_CTypeID chunkID, AAX_SPlugInChunk* pChunk) const
472{
473 TRACE
474
475 if (chunkID == GetUniqueID())
476 {
477 IByteChunk chunk;
478
479 //IByteChunk::InitChunkWithIPlugVer(&IPlugChunk); // TODO: IPlugVer should be in chunk!
480
481 if (SerializeState(chunk))
482 {
483 pChunk->fSize = chunk.Size();
484 memcpy(pChunk->fData, chunk.GetData(), chunk.Size());
485 return AAX_SUCCESS;
486 }
487 }
488
489 return AAX_ERROR_INVALID_CHUNK_ID;
490}
491
492AAX_Result IPlugAAX::SetChunk(AAX_CTypeID chunkID, const AAX_SPlugInChunk* pChunk)
493{
494 TRACE
495 // TODO: UI thread only?
496
497 if (chunkID == GetUniqueID())
498 {
499 IByteChunk chunk;
500 chunk.PutBytes(pChunk->fData, pChunk->fSize);
501 int pos = 0;
502 //IByteChunk::GetIPlugVerFromChunk(chunk, pos); // TODO: IPlugVer should be in chunk!
503 pos = UnserializeState(chunk, pos);
504
505 for (int i = 0; i< NParams(); i++)
506 SetParameterNormalizedValue(mParamIDs.Get(i)->Get(), GetParam(i)->GetNormalized());
507
508 OnRestoreState();
509 mNumPlugInChanges++; // necessary in order to cause CompareActiveChunk() to get called again and turn off the compare light
510
511 return AAX_SUCCESS;
512 }
513
514 return AAX_ERROR_INVALID_CHUNK_ID;
515}
516
517AAX_Result IPlugAAX::CompareActiveChunk(const AAX_SPlugInChunk* pChunk, AAX_CBoolean* pIsEqual) const
518{
519 TRACE
520
521 if (pChunk->fChunkID != GetUniqueID())
522 {
523 *pIsEqual = true;
524 return AAX_SUCCESS;
525 }
526
527 *pIsEqual = CompareState((const unsigned char*) pChunk->fData, 0);
528
529 return AAX_SUCCESS;
530}
531
532AAX_Result IPlugAAX::NotificationReceived (AAX_CTypeID type, const void* pData, uint32_t size)
533{
534 switch (type)
535 {
536 case AAX_eNotificationEvent_TrackNameChanged:
537 if (pData)
538 mTrackName.Set(static_cast<const AAX_IString*>(pData)->Get());
539 break;
540// case AAX_eNotificationEvent_SessionBeingOpened:
541// break;
542// case AAX_eNotificationEvent_PresetOpened:
543// break;
544 case AAX_eNotificationEvent_EnteringOfflineMode:
545 SetRenderingOffline(true);
546 break;
547 case AAX_eNotificationEvent_ExitingOfflineMode:
548 SetRenderingOffline(false);
549 break;
550// case AAX_eNotificationEvent_SideChainBeingConnected:
551// break;
552// case AAX_eNotificationEvent_SideChainBeingDisconnected:
553// break;
554// case AAX_eNotificationEvent_SignalLatencyChanged:
555 default:
556 break;
557 }
558
559 return AAX_CEffectParameters::NotificationReceived (type, pData, size);
560}
561
563{
564 TRACE
565 TouchParameter(mParamIDs.Get(idx)->Get());
566}
567
568void IPlugAAX::InformHostOfParamChange(int idx, double normalizedValue)
569{
570 TRACE
571 SetParameterNormalizedValue(mParamIDs.Get(idx)->Get(), normalizedValue);
572}
573
575{
576 TRACE
577 ReleaseParameter(mParamIDs.Get(idx)->Get());
578}
579
580bool IPlugAAX::EditorResize(int viewWidth, int viewHeight)
581{
582 if (HasUI())
583 {
584 IPlugAAXView_Interface* pViewInterface = (IPlugAAXView_Interface*) GetAAXViewInterface();
585 AAX_Point oEffectViewSize;
586
587 oEffectViewSize.horz = (float) viewWidth;
588 oEffectViewSize.vert = (float) viewHeight;
589
590 if (pViewInterface && (viewWidth != GetEditorWidth() || viewHeight != GetEditorHeight()))
591 {
592 auto* viewContainer = pViewInterface->GetViewContainer();
593
594 if (viewContainer)
595 viewContainer->SetViewSize(oEffectViewSize);
596 }
597
598 SetEditorSize(viewWidth, viewHeight);
599 }
600
601 return true;
602}
603
604void IPlugAAX::SetLatency(int latency)
605{
606 Controller()->SetSignalLatency(latency);
607
608 IPlugProcessor::SetLatency(latency); // will update delay time
609}
610
612{
613 mMidiOutputQueue.Add(msg);
614 return true;
615}
Manages a block of memory, for plug-in settings store/recall.
Definition: IPlugStructs.h:112
int PutBytes(const void *pSrc, int nBytesToCopy)
Copies data into the chunk, placing it at the end, resizing if necessary.
Definition: IPlugStructs.h:147
uint8_t * GetData()
Gets a ptr to the chunk data.
Definition: IPlugStructs.h:242
int Size() const
Returns the current size of the chunk.
Definition: IPlugStructs.h:221
IPlug's parameter class.
double GetDefault(bool normalized=false) const
Returns the parameter's default value.
EParamType Type() const
Get the parameter's type.
bool GetCanAutomate() const
double GetMin() const
Returns the parameter's minimum value.
const char * GetLabel() const
Returns the parameter's label.
const char * GetName() const
Returns the parameter's name.
const char * GetDisplayTextAtIdx(int idx, double *pValue=nullptr) const
Get the display text at a particular index.
int NDisplayTexts() const
Get the number of display texts for the parameter.
double GetMax() const
Returns the parameter's maximum value.
AAX API base class for an IPlug plug-in.
Definition: IPlugAAX.h:80
bool SendMidiMsg(const IMidiMsg &msg) override
Send a single MIDI message // TODO: info about what thread should this be called on or not called on!
Definition: IPlugAAX.cpp:611
void EndInformHostOfParamChange(int idx) override
Implemented by the API class, called by the UI (or by a delegate) at the end of a parameter change ge...
Definition: IPlugAAX.cpp:574
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:568
void BeginInformHostOfParamChange(int idx) override
Implemented by the API class, called by the UI (or by a delegate) at the beginning of a parameter cha...
Definition: IPlugAAX.cpp:562
void SetLatency(int samples) override
Call this if the latency of your plug-in changes after initialization (perhaps from OnReset() ) This ...
Definition: IPlugAAX.cpp:604
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:580
The base class of an IPlug plug-in, which interacts with the different plug-in APIs.
Definition: IPlugAPIBase.h:43
virtual void * GetAAXViewInterface()
You need to implement this method if you are not using IGraphics and you want to support AAX's view i...
Definition: IPlugAPIBase.h:101
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...
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 SetHost(const char *host, int version)
Called to set the name of the current host, if known (calls on to HostSpecificInit() and OnHostIdenti...
The base class for IPlug Audio Processing.
virtual void ProcessMidiMsg(const IMidiMsg &msg)
Override this method to handle incoming MIDI messages.
bool HasSidechainInput() const
virtual void SetLatency(int latency)
Call this if the latency of your plug-in changes after initialization (perhaps from OnReset() ) This ...
bool IsInstrument() const
int MaxNBuses(ERoute direction, int *pConfigIdxWithTheMostBuses=nullptr) const
Used to determine the maximum number of input or output buses based on what was specified in the chan...
bool DoesMIDIIn() const
int GetBlockSize() const
int MaxNChannels(ERoute direction) const
bool DoesMIDIOut() const
virtual void OnReset()
Override this method in your plug-in class to do something prior to playback etc.
virtual int UnserializeState(const IByteChunk &chunk, int startPos)
Override this method to unserialize custom state data, if your plugin does state chunks.
bool HasUI() const
int GetUniqueID() const
virtual bool SerializeState(IByteChunk &chunk) const
Override this method to serialize custom state data, if your plugin does state chunks.
EHost GetHost() const
Encapsulates information about the host transport state.
Definition: IPlugStructs.h:585
Encapsulates a MIDI message and provides helper functions.
Definition: IPlugMidi.h:31