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"
19#include "IPlugAAX_TaperDelegate.h"
20#include "AAX_CNumberDisplayDelegate.h"
21#include "AAX_CUnitDisplayDelegateDecorator.h"
25AAX_CEffectParameters *AAX_CALLBACK IPlugAAX::Create()
27 return MakePlug(InstanceInfo());
30void AAX_CEffectGUI_IPLUG::CreateViewContents()
33 mPlug =
dynamic_cast<IPlugAAX*
>(GetEffectParameters());
36void AAX_CEffectGUI_IPLUG::CreateViewContainer()
40 void* pWindow = GetViewContainerPtr();
42 if (pWindow && mPlug->HasUI())
44 mPlug->OpenWindow(pWindow);
46 IPlugAAXView_Interface* pViewInterface = (IPlugAAXView_Interface*) mPlug->GetAAXViewInterface();
49 pViewInterface->SetViewContainer(GetViewContainer());
53void AAX_CEffectGUI_IPLUG::DeleteViewContainer()
58AAX_Result AAX_CEffectGUI_IPLUG::GetViewSize(AAX_Point* pNewViewSize)
const
62 pNewViewSize->horz = (float) mPlug->GetEditorWidth();
63 pNewViewSize->vert = (float) mPlug->GetEditorHeight();
69AAX_Result AAX_CEffectGUI_IPLUG::ParameterUpdated(AAX_CParamID paramID)
74AAX_IEffectGUI* AAX_CALLBACK AAX_CEffectGUI_IPLUG::Create()
76 return new AAX_CEffectGUI_IPLUG;
79AAX_Result AAX_CEffectGUI_IPLUG::SetControlHighlightInfo(AAX_CParamID paramID, AAX_CBoolean iIsHighlighted, AAX_EHighlightColor iColor)
81 IPlugAAXView_Interface* pViewInterface = (IPlugAAXView_Interface*) mPlug->GetAAXViewInterface();
85 int paramIdx = atoi(paramID) - kAAXParamIdxOffset;
87 if (paramIdx != kNoParameter)
89 pViewInterface->SetPTParameterHighlight(paramIdx, (
bool) iIsHighlighted, (
int) iColor);
95 return AAX_ERROR_INVALID_PARAMETER_ID;
98#pragma mark IPlugAAX Construct
100IPlugAAX::IPlugAAX(
const InstanceInfo& info,
const Config& config)
104 Trace(TRACELOC,
"%s%s", config.pluginName, config.channelIOStr);
106 SetChannelConnections(ERoute::kInput, 0, MaxNChannels(ERoute::kInput),
true);
107 SetChannelConnections(ERoute::kOutput, 0, MaxNChannels(ERoute::kOutput),
true);
109 SetBlockSize(DEFAULT_BLOCK_SIZE);
112 mMaxNChansForMainInputBus = MaxNChannelsForBus(kInput, 0);
119 mParamIDs.Empty(
true);
122AAX_Result IPlugAAX::EffectInit()
129 AAX_CString bypassID = NULL;
130 this->GetMasterBypassParameter(&bypassID);
131 mBypassParameter =
new AAX_CParameter<bool>(bypassID.CString(),
132 AAX_CString(
"Master Bypass"),
134 AAX_CBinaryTaperDelegate<bool>(),
135 AAX_CBinaryDisplayDelegate<bool>(
"bypass",
"on"),
137 mBypassParameter->SetNumberOfSteps(2);
138 mBypassParameter->SetType(AAX_eParameterType_Discrete);
139 mParameterManager.AddParameter(mBypassParameter);
141 for (
int i=0; i<NParams(); i++)
143 IParam* pParam = GetParam(i);
144 AAX_IParameter* pAAXParam =
nullptr;
146 WDL_String* pParamIDStr =
new WDL_String(
"_", 1);
147 pParamIDStr->SetFormatted(MAX_AAX_PARAMID_LEN,
"%i", i+kAAXParamIdxOffset);
148 mParamIDs.Add(pParamIDStr);
150 switch (pParam->
Type())
152 case IParam::kTypeDouble:
154 pAAXParam =
new AAX_CParameter<double>(pParamIDStr->Get(),
155 AAX_CString(pParam->
GetName()),
157 AAX_CIPlugTaperDelegate<double>(*pParam),
158 AAX_CUnitDisplayDelegateDecorator<double>(AAX_CNumberDisplayDelegate<double>(), AAX_CString(pParam->
GetLabel())),
161 pAAXParam->SetNumberOfSteps(128);
162 pAAXParam->SetType(AAX_eParameterType_Continuous);
166 case IParam::kTypeInt:
168 pAAXParam =
new AAX_CParameter<int>(pParamIDStr->Get(),
169 AAX_CString(pParam->
GetName()),
171 AAX_CLinearTaperDelegate<int,1>((
int)pParam->
GetMin(), (
int)pParam->
GetMax()),
172 AAX_CUnitDisplayDelegateDecorator<int>(AAX_CNumberDisplayDelegate<int,0>(), AAX_CString(pParam->
GetLabel())),
175 pAAXParam->SetNumberOfSteps(128);
176 pAAXParam->SetType(AAX_eParameterType_Continuous);
180 case IParam::kTypeEnum:
181 case IParam::kTypeBool:
185 std::map<int, AAX_CString> displayTexts;
192 displayTexts.insert(std::pair<int, AAX_CString>(value, AAX_CString(text)));
195 pAAXParam =
new AAX_CParameter<int>(pParamIDStr->Get(),
196 AAX_CString(pParam->
GetName()),
198 AAX_CLinearTaperDelegate<int,1>((
int) pParam->
GetMin(), (
int) pParam->
GetMax()),
199 AAX_CStringDisplayDelegate<int>(displayTexts),
202 pAAXParam->SetNumberOfSteps(nTexts);
203 pAAXParam->SetType(AAX_eParameterType_Discrete);
211 mParameterManager.AddParameter(pAAXParam);
215 Controller()->GetSampleRate(&sr);
222AAX_Result IPlugAAX::UpdateParameterNormalizedValue(AAX_CParamID paramID,
double iValue, AAX_EUpdateSource iSource)
226 AAX_Result result = AAX_SUCCESS;
228 AAX_IParameter* pAAXParameter = mParameterManager.GetParameterByID(paramID);
230 if (pAAXParameter ==
nullptr)
231 return AAX_ERROR_INVALID_PARAMETER_ID;
234 pAAXParameter->UpdateNormalizedValue(iValue);
236 int paramIdx = atoi(paramID) - kAAXParamIdxOffset;
238 if ((paramIdx > kNoParameter) && (paramIdx < NParams()))
241 GetParam(paramIdx)->SetNormalized(iValue);
243 OnParamChange(paramIdx, kHost);
248 result = mPacketDispatcher.SetDirty(paramID);
255void IPlugAAX::RenderAudio(AAX_SIPlugRenderInfo* pRenderInfo,
const TParamValPair* inSynchronizedParamValues[], int32_t inNumSynchronizedParamValues)
261 mBypassParameter->GetValueAsBool(&bypass);
263 AAX_EStemFormat inFormat, outFormat;
264 Controller()->GetInputStemFormat(&inFormat);
265 Controller()->GetOutputStemFormat(&outFormat);
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;
274 for (
auto i = 0; i<packets_count; i++, pMidiPacket++)
276 IMidiMsg msg(pMidiPacket->mTimestamp, pMidiPacket->mData[0], pMidiPacket->mData[1], pMidiPacket->mData[2]);
278 mMidiMsgsFromProcessor.Push(msg);
282 AAX_IMIDINode* pTransportNode = pRenderInfo->mTransportNode;
283 mTransport = pTransportNode->GetTransport();
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);
291 SetBlockSize(numSamples);
297 SetChannelConnections(ERoute::kInput, 0, numInChannels,
true);
298 SetChannelConnections(ERoute::kInput, numInChannels,
MaxNChannels(ERoute::kInput) - numInChannels,
false);
302 if (sideChainChannel)
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);
309 AttachBuffers(ERoute::kInput, 0, numInChannels, pRenderInfo->mAudioInputs, numSamples);
314 SetChannelConnections(ERoute::kOutput, 0, maxNOutChans,
true);
318 SetChannelConnections(ERoute::kOutput, numOutChannels, maxNOutChans - numOutChannels,
false);
319 AttachBuffers(ERoute::kOutput, 0, maxNOutChans, pRenderInfo->mAudioOutputs, numSamples);
323 AttachBuffers(ERoute::kOutput, 0, maxNOutChans, pRenderInfo->mAudioOutputs, numSamples);
327 PassThroughBuffers(0.0f, numSamples);
331 int64_t ppqPos, samplePos, cStart, cEnd;
334 mTransport->GetCurrentTempo(&timeInfo.mTempo);
335 mTransport->IsTransportPlaying(&timeInfo.mTransportIsRunning);
337 mTransport->GetCurrentMeter(&num, &denom);
338 timeInfo.mNumerator = (int) num;
339 timeInfo.mDenominator = (int) denom;
341 mTransport->GetCurrentTickPosition(&ppqPos);
342 timeInfo.mPPQPos = (double) ppqPos / 960000.0;
344 if(timeInfo.mPPQPos < 0)
345 timeInfo.mPPQPos = 0;
347 mTransport->GetCurrentNativeSampleLocation(&samplePos);
348 timeInfo.mSamplePos = (double) samplePos;
350 mTransport->GetCurrentLoopPosition(&timeInfo.mTransportLoopEnabled, &cStart, &cEnd);
351 timeInfo.mCycleStart = (double) cStart / 960000.0;
352 timeInfo.mCycleEnd = (double) cEnd / 960000.0;
354 SetTimeInfo(timeInfo);
359 while (mMidiMsgsFromEditor.Pop(msg))
365 ProcessBuffers(0.0f, numSamples);
372 AAX_IMIDINode* midiOut = pRenderInfo->mOutputNode;
377 if (!mMidiOutputQueue.Empty())
379 while (!mMidiOutputQueue.Empty())
381 IMidiMsg& msg = mMidiOutputQueue.Peek();
383 AAX_CMidiPacket packet;
385 packet.mIsImmediate =
true;
387 packet.mTimestamp = (uint32_t) msg.mOffset;
390 packet.mData[0] = msg.mStatus;
391 packet.mData[1] = msg.mData1;
392 packet.mData[2] = msg.mData2;
394 midiOut->PostMIDIPacket (&packet);
396 mMidiOutputQueue.Remove();
400 mMidiOutputQueue.Flush(numSamples);
403 if(mSysExDataFromEditor.ElementsAvailable())
405 while (mSysExDataFromEditor.Pop(mSysexBuf))
407 int numPackets = (int) ceil((
float) mSysexBuf.mSize/4.);
410 for (
int p = 0; p < numPackets; p++)
412 AAX_CMidiPacket packet;
414 packet.mTimestamp = (uint32_t) mSysexBuf.mOffset;
415 packet.mIsImmediate =
true;
419 while (b < 4 && bytesPos < mSysexBuf.mSize)
421 packet.mData[b++] = mSysexBuf.mData[bytesPos++];
424 packet.mLength = (uint32_t) b;
426 midiOut->PostMIDIPacket (&packet);
434AAX_Result IPlugAAX::GetChunkIDFromIndex(int32_t index, AAX_CTypeID* pChunkID)
const
438 *pChunkID = AAX_CTypeID(0);
439 return AAX_ERROR_INVALID_CHUNK_INDEX;
447AAX_Result IPlugAAX::GetChunkSize(AAX_CTypeID chunkID, uint32_t* pSize)
const
459 *pSize = chunk.
Size();
467 return AAX_ERROR_INVALID_CHUNK_ID;
471AAX_Result IPlugAAX::GetChunk(AAX_CTypeID chunkID, AAX_SPlugInChunk* pChunk)
const
483 pChunk->fSize = chunk.
Size();
484 memcpy(pChunk->fData, chunk.
GetData(), chunk.
Size());
489 return AAX_ERROR_INVALID_CHUNK_ID;
492AAX_Result IPlugAAX::SetChunk(AAX_CTypeID chunkID,
const AAX_SPlugInChunk* pChunk)
500 chunk.
PutBytes(pChunk->fData, pChunk->fSize);
505 for (
int i = 0; i< NParams(); i++)
506 SetParameterNormalizedValue(mParamIDs.Get(i)->Get(), GetParam(i)->GetNormalized());
514 return AAX_ERROR_INVALID_CHUNK_ID;
517AAX_Result IPlugAAX::CompareActiveChunk(
const AAX_SPlugInChunk* pChunk, AAX_CBoolean* pIsEqual)
const
527 *pIsEqual =
CompareState((
const unsigned char*) pChunk->fData, 0);
532AAX_Result IPlugAAX::NotificationReceived (AAX_CTypeID type,
const void* pData, uint32_t size)
536 case AAX_eNotificationEvent_TrackNameChanged:
538 mTrackName.Set(
static_cast<const AAX_IString*
>(pData)->Get());
544 case AAX_eNotificationEvent_EnteringOfflineMode:
545 SetRenderingOffline(
true);
547 case AAX_eNotificationEvent_ExitingOfflineMode:
548 SetRenderingOffline(
false);
559 return AAX_CEffectParameters::NotificationReceived (type, pData, size);
565 TouchParameter(mParamIDs.Get(idx)->Get());
571 SetParameterNormalizedValue(mParamIDs.Get(idx)->Get(), normalizedValue);
577 ReleaseParameter(mParamIDs.Get(idx)->Get());
585 AAX_Point oEffectViewSize;
587 oEffectViewSize.horz = (float) viewWidth;
588 oEffectViewSize.vert = (float) viewHeight;
590 if (pViewInterface && (viewWidth != GetEditorWidth() || viewHeight != GetEditorHeight()))
592 auto* viewContainer = pViewInterface->GetViewContainer();
595 viewContainer->SetViewSize(oEffectViewSize);
598 SetEditorSize(viewWidth, viewHeight);
606 Controller()->SetSignalLatency(latency);
613 mMidiOutputQueue.Add(msg);
Manages a block of memory, for plug-in settings store/recall.
int PutBytes(const void *pSrc, int nBytesToCopy)
Copies data into the chunk, placing it at the end, resizing if necessary.
uint8_t * GetData()
Gets a ptr to the chunk data.
int Size() const
Returns the current size of the chunk.
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.
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!
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...
void InformHostOfParamChange(int idx, double normalizedValue) override
Implemented by the API class, called by the UI via SetParameterValue() with the value of a parameter ...
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...
void SetLatency(int samples) override
Call this if the latency of your plug-in changes after initialization (perhaps from OnReset() ) This ...
bool EditorResize(int viewWidth, int viewHeight) override
Implementations call into the APIs resize hooks returns a bool to indicate whether the DAW or plugin ...
The base class of an IPlug plug-in, which interacts with the different plug-in APIs.
virtual void * GetAAXViewInterface()
You need to implement this method if you are not using IGraphics and you want to support AAX's view i...
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...
int MaxNChannels(ERoute direction) 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.
virtual bool SerializeState(IByteChunk &chunk) const
Override this method to serialize custom state data, if your plugin does state chunks.
Encapsulates information about the host transport state.
Encapsulates a MIDI message and provides helper functions.