17static const int VST_VERSION = 2400;
19static int VSTSpkrArrType(
int nchan)
21 if (!nchan)
return kSpeakerArrEmpty;
22 if (nchan == 1)
return kSpeakerArrMono;
23 if (nchan == 2)
return kSpeakerArrStereo;
24 return kSpeakerArrUserDefined;
27static int AsciiToVK(
int ascii)
30 HKL layout = GetKeyboardLayout(0);
31 return VkKeyScanExA((CHAR)ascii, layout);
34 if ((ascii >= 0x30 && ascii <= 0x39) || (ascii >= 0x41 && ascii <= 0x5A))
40 if (ascii >= 0x61 && ascii <= 0x7A)
49static int VSTKeyCodeToVK(
int code,
int ascii)
53 if (code == 0 || code == VKEY_EQUALS)
55 return AsciiToVK(ascii);
60 case VKEY_BACK:
return kVK_BACK;
61 case VKEY_TAB:
return kVK_TAB;
62 case VKEY_CLEAR:
return kVK_CLEAR;
63 case VKEY_RETURN:
return kVK_RETURN;
64 case VKEY_PAUSE:
return kVK_PAUSE;
65 case VKEY_ESCAPE:
return kVK_ESCAPE;
66 case VKEY_SPACE:
return kVK_SPACE;
67 case VKEY_NEXT:
return kVK_NEXT;
68 case VKEY_END:
return kVK_END;
69 case VKEY_HOME:
return kVK_HOME;
70 case VKEY_LEFT:
return kVK_LEFT;
71 case VKEY_UP:
return kVK_UP;
72 case VKEY_RIGHT:
return kVK_RIGHT;
73 case VKEY_DOWN:
return kVK_DOWN;
74 case VKEY_PAGEUP:
return kVK_PRIOR;
75 case VKEY_PAGEDOWN:
return kVK_NEXT;
76 case VKEY_SELECT:
return kVK_SELECT;
77 case VKEY_PRINT:
return kVK_PRINT;
78 case VKEY_ENTER:
return kVK_RETURN;
79 case VKEY_SNAPSHOT:
return kVK_SNAPSHOT;
80 case VKEY_INSERT:
return kVK_INSERT;
81 case VKEY_DELETE:
return kVK_DELETE;
82 case VKEY_HELP:
return kVK_HELP;
83 case VKEY_NUMPAD0:
return kVK_NUMPAD0;
84 case VKEY_NUMPAD1:
return kVK_NUMPAD1;
85 case VKEY_NUMPAD2:
return kVK_NUMPAD2;
86 case VKEY_NUMPAD3:
return kVK_NUMPAD3;
87 case VKEY_NUMPAD4:
return kVK_NUMPAD4;
88 case VKEY_NUMPAD5:
return kVK_NUMPAD5;
89 case VKEY_NUMPAD6:
return kVK_NUMPAD6;
90 case VKEY_NUMPAD7:
return kVK_NUMPAD7;
91 case VKEY_NUMPAD8:
return kVK_NUMPAD8;
92 case VKEY_NUMPAD9:
return kVK_NUMPAD9;
93 case VKEY_MULTIPLY:
return kVK_MULTIPLY;
94 case VKEY_ADD:
return kVK_ADD;
95 case VKEY_SEPARATOR:
return kVK_SEPARATOR;
96 case VKEY_SUBTRACT:
return kVK_SUBTRACT;
97 case VKEY_DECIMAL:
return kVK_DECIMAL;
98 case VKEY_DIVIDE:
return kVK_DIVIDE;
99 case VKEY_F1:
return kVK_F1;
100 case VKEY_F2:
return kVK_F2;
101 case VKEY_F3:
return kVK_F3;
102 case VKEY_F4:
return kVK_F4;
103 case VKEY_F5:
return kVK_F5;
104 case VKEY_F6:
return kVK_F6;
105 case VKEY_F7:
return kVK_F7;
106 case VKEY_F8:
return kVK_F8;
107 case VKEY_F9:
return kVK_F9;
108 case VKEY_F10:
return kVK_F10;
109 case VKEY_F11:
return kVK_F11;
110 case VKEY_F12:
return kVK_F12;
111 case VKEY_NUMLOCK:
return kVK_NUMLOCK;
112 case VKEY_SCROLL:
return kVK_SCROLL;
113 case VKEY_SHIFT:
return kVK_SHIFT;
114 case VKEY_CONTROL:
return kVK_CONTROL;
115 case VKEY_ALT:
return kVK_MENU;
116 case VKEY_EQUALS:
return kVK_NONE;
122IPlugVST2::IPlugVST2(
const InstanceInfo& info,
const Config& config)
125 , mHostCallback(info.mVSTHostCallback)
127 Trace(TRACELOC,
"%s", config.pluginName);
129 mHasVSTExtensions = VSTEXT_NONE;
131 int nInputs = MaxNChannels(ERoute::kInput), nOutputs = MaxNChannels(ERoute::kOutput);
133 memset(&mAEffect, 0,
sizeof(AEffect));
134 mAEffect.object =
this;
135 mAEffect.magic = kEffectMagic;
136 mAEffect.dispatcher = VSTDispatcher;
137 mAEffect.getParameter = VSTGetParameter;
138 mAEffect.setParameter = VSTSetParameter;
139 mAEffect.numPrograms = config.nPresets;
140 mAEffect.numParams = config.nParams;
141 mAEffect.numInputs = nInputs;
142 mAEffect.numOutputs = nOutputs;
143 mAEffect.uniqueID = config.uniqueID;
144 mAEffect.version = GetPluginVersion(
true);
145 mAEffect.__ioRatioDeprecated = 1.0f;
146 mAEffect.__processDeprecated = VSTProcess;
147 mAEffect.processReplacing = VSTProcessReplacing;
148 mAEffect.processDoubleReplacing = VSTProcessDoubleReplacing;
149 mAEffect.initialDelay = config.latency;
150 mAEffect.flags = effFlagsCanReplacing | effFlagsCanDoubleReplacing;
152 if (config.plugDoesChunks) { mAEffect.flags |= effFlagsProgramChunks; }
153 if (LegalIO(1, -1)) { mAEffect.flags |= __effFlagsCanMonoDeprecated; }
154 if (config.plugType == EIPlugPluginType::kInstrument) { mAEffect.flags |= effFlagsIsSynth; }
156 memset(&mEditRect, 0,
sizeof(ERect));
157 memset(&mInputSpkrArr, 0,
sizeof(VstSpeakerArrangement));
158 memset(&mOutputSpkrArr, 0,
sizeof(VstSpeakerArrangement));
159 mInputSpkrArr.numChannels = nInputs;
160 mOutputSpkrArr.numChannels = nOutputs;
161 mInputSpkrArr.type = VSTSpkrArrType(nInputs);
162 mOutputSpkrArr.type = VSTSpkrArrType(nOutputs);
165 SetChannelConnections(ERoute::kInput, 0, nInputs,
true);
166 SetChannelConnections(ERoute::kOutput, 0, nOutputs,
true);
168 SetBlockSize(DEFAULT_BLOCK_SIZE);
170 if (config.plugHasUI)
172 mAEffect.flags |= effFlagsHasEditor;
181 mHostCallback(&mAEffect, audioMasterBeginEdit, idx, 0, 0, 0.0f);
186 mHostCallback(&mAEffect, audioMasterAutomate, idx, 0, 0, (
float) normalizedValue);
191 mHostCallback(&mAEffect, audioMasterEndEdit, idx, 0, 0, 0.0f);
196 mHostCallback(&mAEffect, audioMasterUpdateDisplay, 0, 0, 0, 0.0f);
201 bool resized =
false;
205 if (viewWidth != GetEditorWidth() || viewHeight != GetEditorHeight())
207 SetEditorSize(viewWidth, viewHeight);
210 resized = mHostCallback(&mAEffect, audioMasterSizeWindow, viewWidth, viewHeight, 0, 0.f);
217void IPlugVST2::UpdateEditRect()
219 mEditRect.left = mEditRect.top = 0;
220 mEditRect.right = GetEditorWidth();
221 mEditRect.bottom = GetEditorHeight();
226 mAEffect.initialDelay = samples;
228 mHostCallback(&mAEffect, audioMasterIOChanged, 0, 0, 0, 0.0f);
231bool IPlugVST2::SendVSTEvent(VstEvent& event)
237 memset(&events, 0,
sizeof(VstEvents));
238 events.numEvents = 1;
239 events.events[0] = &event;
240 return (mHostCallback(&mAEffect, audioMasterProcessEvents, 0, 0, &events, 0.0f) == 1);
245 VstMidiEvent midiEvent;
246 memset(&midiEvent, 0,
sizeof(VstMidiEvent));
248 midiEvent.type = kVstMidiType;
249 midiEvent.byteSize =
sizeof(VstMidiEvent);
250 midiEvent.deltaFrames = msg.mOffset;
251 midiEvent.midiData[0] = msg.mStatus;
252 midiEvent.midiData[1] = msg.mData1;
253 midiEvent.midiData[2] = msg.mData2;
255 return SendVSTEvent((VstEvent&) midiEvent);
260 VstMidiSysexEvent sysexEvent;
261 memset(&sysexEvent, 0,
sizeof(VstMidiSysexEvent));
263 sysexEvent.type = kVstSysExType;
264 sysexEvent.byteSize =
sizeof(VstMidiSysexEvent);
265 sysexEvent.deltaFrames = msg.mOffset;
266 sysexEvent.dumpBytes = msg.mSize;
267 sysexEvent.sysexDump = (
char*) msg.mData;
269 return SendVSTEvent((VstEvent&) sysexEvent);
288 mAEffect.numInputs = mInputSpkrArr.numChannels =
MaxNChannels(ERoute::kInput);
289 mAEffect.numOutputs = mOutputSpkrArr.numChannels =
MaxNChannels(ERoute::kOutput);
292VstIntPtr VSTCALLBACK IPlugVST2::VSTDispatcher(AEffect *pEffect, VstInt32 opCode, VstInt32 idx, VstIntPtr value,
void *ptr,
float opt)
312 Trace(TRACELOC,
"%d(%s):%d:%d", opCode, VSTOpcodeStr(opCode), idx, (
int) value);
318 if (_this->
GetHost() == kHostUninit)
320 char productStr[256];
321 productStr[0] =
'\0';
323 _this->mHostCallback(&_this->mAEffect, audioMasterGetProductString, 0, 0, productStr, 0.0f);
325 if (CStringHasContents(productStr))
327 int decVer = (int) _this->mHostCallback(&_this->mAEffect, audioMasterGetVendorVersion, 0, 0, 0, 0.0f);
328 int ver = decVer / 10000;
329 int rmaj = (decVer - 10000 * ver) / 100;
330 int rmin = (decVer - 10000 * ver - 100 * rmaj);
331 version = (ver << 16) + (rmaj << 8) + rmin;
334 _this->
SetHost(productStr, version);
336 _this->OnParamReset(kReset);
344 case effGetParamLabel:
346 if (idx >= 0 && idx < _this->NParams())
348 ENTER_PARAMS_MUTEX_STATIC
349 strcpy((
char*) ptr, _this->GetParam(idx)->GetLabel());
350 LEAVE_PARAMS_MUTEX_STATIC
354 case effGetParamDisplay:
356 if (idx >= 0 && idx < _this->NParams())
358 ENTER_PARAMS_MUTEX_STATIC
359 _this->GetParam(idx)->GetDisplay(_this->mParamDisplayStr);
360 LEAVE_PARAMS_MUTEX_STATIC
361 strcpy((
char*) ptr, _this->mParamDisplayStr.Get());
365 case effGetParamName:
367 if (idx >= 0 && idx < _this->NParams())
369 ENTER_PARAMS_MUTEX_STATIC
370 strcpy((
char*) ptr, _this->GetParam(idx)->GetName());
371 LEAVE_PARAMS_MUTEX_STATIC
375 case effGetParameterProperties:
377 if (idx >= 0 && idx < _this->NParams())
379 VstParameterProperties* props = (VstParameterProperties*) ptr;
381 ENTER_PARAMS_MUTEX_STATIC
382 IParam* pParam = _this->GetParam(idx);
383 switch (pParam->Type())
385 case IParam::kTypeInt:
386 case IParam::kTypeEnum:
387 props->flags = kVstParameterUsesIntStep | kVstParameterUsesIntegerMinMax;
388 props->minInteger = (int) pParam->GetMin();
389 props->maxInteger = (int) pParam->GetMax();
390 props->stepInteger = props->largeStepInteger = 1;
392 case IParam::kTypeBool:
393 props->flags = kVstParameterIsSwitch;
395 case IParam::kTypeDouble:
397 props->flags = kVstParameterUsesFloatStep;
398 props->largeStepFloat = props->smallStepFloat = props->stepFloat = (float) pParam->GetStep();
402 strcpy(props->label, pParam->GetLabel());
403 LEAVE_PARAMS_MUTEX_STATIC
409 case effString2Parameter:
411 if (idx >= 0 && idx < _this->NParams())
415 ENTER_PARAMS_MUTEX_STATIC
416 IParam* pParam = _this->GetParam(idx);
417 const double v = pParam->StringToValue((
const char *)ptr);
420 _this->OnParamChange(idx, kHost);
421 LEAVE_PARAMS_MUTEX_STATIC
427 case effSetSampleRate:
429 _this->SetSampleRate(opt);
433 case effSetBlockSize:
435 _this->SetBlockSize((
int) value);
439 case effMainsChanged:
454 if (ptr && _this->
HasUI())
456 _this->UpdateEditRect();
457 *(ERect**) ptr = &(_this->mEditRect);
465#if defined OS_WIN || defined ARCH_64BIT
466 if (_this->OpenWindow(ptr))
471 bool iscocoa = (_this->mHasVSTExtensions&VSTEXT_COCOA);
472 if (iscocoa && _this->OpenWindow(ptr))
483 _this->CloseWindow();
488 case __effIdentifyDeprecated:
494 uint8_t** ppData = (uint8_t**) ptr;
497 bool isBank = (!idx);
498 IByteChunk& chunk = (isBank ? _this->mBankState : _this->mState);
512 if (savedOK && chunk.
Size())
524 bool isBank = (!idx);
525 IByteChunk& chunk = (isBank ? _this->mBankState : _this->mState);
526 chunk.
Resize((
int) value);
527 memcpy(chunk.
GetData(), ptr, value);
530 isBank &= (iplugVer >= 0x010000);
544 _this->OnRestoreState();
550 case effProcessEvents:
552 VstEvents* pEvents = (VstEvents*) ptr;
555 for (
int i = 0; i < pEvents->numEvents; ++i)
557 VstEvent* pEvent = pEvents->events[i];
560 if (pEvent->type == kVstMidiType)
562 VstMidiEvent* pME = (VstMidiEvent*) pEvent;
563 IMidiMsg msg(pME->deltaFrames, pME->midiData[0], pME->midiData[1], pME->midiData[2]);
565 _this->mMidiMsgsFromProcessor.Push(msg);
571 else if (pEvent->type == kVstSysExType)
573 VstMidiSysexEvent* pSE = (VstMidiSysexEvent*) pEvent;
574 ISysEx sysex(pSE->deltaFrames, (
const uint8_t*)pSE->sysexDump, pSE->dumpBytes);
583 case effCanBeAutomated:
585 if (idx >= 0 && idx < _this->NParams())
587 return _this->GetParam(idx)->GetCanAutomate();
590 case effGetInputProperties:
592 if (ptr && idx >= 0 && idx < _this->
MaxNChannels(ERoute::kInput))
594 VstPinProperties* pp = (VstPinProperties*) ptr;
595 pp->flags = kVstPinIsActive;
597 if (!(idx%2) && idx < _this->
MaxNChannels(ERoute::kInput)-1)
598 pp->flags |= kVstPinIsStereo;
600 if (_this->GetChannelLabel(ERoute::kInput, idx).GetLength())
601 sprintf(pp->label,
"%s", _this->GetChannelLabel(ERoute::kInput, idx).Get());
603 sprintf(pp->label,
"Input %d", idx + 1);
609 case effGetOutputProperties:
611 if (ptr && idx >= 0 && idx < _this->
MaxNChannels(ERoute::kOutput))
613 VstPinProperties* pp = (VstPinProperties*) ptr;
614 pp->flags = kVstPinIsActive;
616 if (!(idx%2) && idx < _this->
MaxNChannels(ERoute::kOutput)-1)
617 pp->flags |= kVstPinIsStereo;
619 if (_this->GetChannelLabel(ERoute::kOutput, idx).GetLength())
620 sprintf(pp->label,
"%s", _this->GetChannelLabel(ERoute::kOutput, idx).Get());
622 sprintf(pp->label,
"Output %d", idx + 1);
628 case effGetPlugCategory:
631 return kPlugCategEffect;
633 case effProcessVarIo:
638 case effSetSpeakerArrangement:
640 VstSpeakerArrangement* pInputArr = (VstSpeakerArrangement*) value;
641 VstSpeakerArrangement* pOutputArr = (VstSpeakerArrangement*) ptr;
645 int n = pInputArr->numChannels;
648 if (n > _this->mAEffect.numInputs)
651 _this->SetChannelConnections(ERoute::kInput, 0, n,
true);
652 _this->SetChannelConnections(ERoute::kInput, n, _this->
MaxNChannels(ERoute::kInput) - n,
false);
656 int n = pOutputArr->numChannels;
659 if (n > _this->mAEffect.numOutputs)
662 _this->SetChannelConnections(ERoute::kOutput, 0, n,
true);
663 _this->SetChannelConnections(ERoute::kOutput, n, _this->
MaxNChannels(ERoute::kOutput) - n,
false);
667 case effGetSpeakerArrangement:
669 VstSpeakerArrangement** ppInputArr = (VstSpeakerArrangement**) value;
670 VstSpeakerArrangement** ppOutputArr = (VstSpeakerArrangement**) ptr;
673 *ppInputArr = &(_this->mInputSpkrArr);
677 *ppOutputArr = &(_this->mOutputSpkrArr);
681 case effGetEffectName:
690 case effGetProductString:
699 case effGetVendorString:
708 case effGetVendorVersion:
716 Trace(TRACELOC,
"VSTCanDo(%s)", (
char*) ptr);
717 if (!strcmp((
char*) ptr,
"receiveVstTimeInfo"))
723 if (!strcmp((
char*) ptr,
"receiveVstEvents") ||
724 !strcmp((
char*) ptr,
"receiveVstMidiEvent"))
731 if (!strcmp((
char*) ptr,
"sendVstEvents") ||
732 !strcmp((
char*) ptr,
"sendVstMidiEvent"))
738 if (!strcmp((
char*) ptr,
"hasCockosExtensions"))
740 _this->mHasVSTExtensions |= VSTEXT_COCKOS;
744 if (!strcmp((
char*) ptr,
"hasCockosViewAsConfig"))
746 _this->mHasVSTExtensions |= VSTEXT_COCOA;
750 if (!strcmp((
char*) ptr,
"wantsChannelCountNotifications"))
755 if (!strcmp((
char*)ptr,
"MPE"))
757 return _this->
DoesMPE() ? 1 : 0;
760 return _this->VSTCanDo((
char *) ptr);
767 return _this->
GetTailIsInfinite() ? std::numeric_limits<int>::max() : (tailSize ? std::min(2, tailSize) : 1);
769 case effVendorSpecific:
786 case effGetParamDisplay:
790 if (value >= 0 && value < _this->NParams())
792 _this->GetParam((
int) value)->GetDisplay((
double) opt,
true, _this->mParamDisplayStr);
793 strcpy((
char*) ptr, _this->mParamDisplayStr.Get());
799 case effString2Parameter:
801 if (ptr && value >= 0 && value < _this->NParams())
803 if (*(
char*) ptr !=
'\0')
805 IParam* pParam = _this->GetParam((
int) value);
812 case kVstParameterUsesIntStep:
814 if (value >= 0 && value < _this->NParams())
816 IParam* pParam = _this->GetParam((
int) value);
817 switch (pParam->
Type())
819 case IParam::kTypeBool:
821 case IParam::kTypeInt:
822 case IParam::kTypeEnum:
826 if (std::fabs(max - min) < 1.5)
838 return _this->VSTVendorSpecific(idx, value, ptr, opt);
853 case effGetProgramNameIndexed:
856 return (CStringHasContents((
char*) ptr) ? 1 : 0);
858 case effSetProgramName:
867 case effGetProgramName:
876 case effGetMidiKeyName:
880 MidiKeyName* pMKN = (MidiKeyName*) ptr;
881 pMKN->keyName[0] =
'\0';
889 case effGetVstVersion:
897 str[0] =
static_cast<char>(idx);
901 if (_this->
GetHost() == iplug::EHost::kHostReaper && value != VKEY_SPACE)
906 int vk = VSTKeyCodeToVK(
static_cast<int>(value), idx);
907 int modifiers = (int)opt;
909 IKeyPress keyPress{ str,
static_cast<int>(vk),
910 static_cast<bool>(modifiers & MODIFIER_SHIFT),
911 static_cast<bool>(modifiers & MODIFIER_CONTROL),
912 static_cast<bool>(modifiers & MODIFIER_ALTERNATE) };
915 if (opCode == effEditKeyDown)
916 handled = _this->OnKeyDown(keyPress);
918 handled = _this->OnKeyUp(keyPress);
920 return handled ? 1 : 0;
922 case effEndSetProgram:
923 case effBeginSetProgram:
924 case effGetMidiProgramName:
925 case effHasMidiProgramsChanged:
926 case effGetMidiProgramCategory:
927 case effGetCurrentMidiProgram:
936template <
class SAMPLETYPE>
937void IPlugVST2::VSTPreProcess(SAMPLETYPE** inputs, SAMPLETYPE** outputs, VstInt32 nFrames)
940 mHostCallback(&mAEffect, __audioMasterWantMidiDeprecated, 0, 0, 0, 0.0f);
942 AttachBuffers(ERoute::kInput, 0,
MaxNChannels(ERoute::kInput), inputs, nFrames);
943 AttachBuffers(ERoute::kOutput, 0,
MaxNChannels(ERoute::kOutput), outputs, nFrames);
945 VstTimeInfo* pTI = (VstTimeInfo*) mHostCallback(&mAEffect, audioMasterGetTime, 0, kVstPpqPosValid | kVstTempoValid | kVstBarsValid | kVstCyclePosValid | kVstTimeSigValid, 0, 0);
951 timeInfo.mSamplePos = pTI->samplePos;
953 if ((pTI->flags & kVstPpqPosValid) && pTI->ppqPos >= 0.0) timeInfo.mPPQPos = pTI->ppqPos;
954 if ((pTI->flags & kVstTempoValid) && pTI->tempo > 0.0) timeInfo.mTempo = pTI->tempo;
955 if ((pTI->flags & kVstBarsValid) && pTI->barStartPos >= 0.0) timeInfo.mLastBar = pTI->barStartPos;
956 if ((pTI->flags & kVstCyclePosValid) && pTI->cycleStartPos >= 0.0 && pTI->cycleEndPos >= 0.0)
958 timeInfo.mCycleStart = pTI->cycleStartPos;
959 timeInfo.mCycleEnd = pTI->cycleEndPos;
961 if ((pTI->flags & kVstTimeSigValid) && pTI->timeSigNumerator > 0.0 && pTI->timeSigDenominator > 0.0)
963 timeInfo.mNumerator = pTI->timeSigNumerator;
964 timeInfo.mDenominator = pTI->timeSigDenominator;
966 timeInfo.mTransportIsRunning = pTI->flags & kVstTransportPlaying;
967 timeInfo.mTransportLoopEnabled = pTI->flags & kVstTransportCycleActive;
970 const bool renderingOffline = mHostCallback(&mAEffect, audioMasterGetCurrentProcessLevel, 0, 0, 0, 0.0f) == kVstProcessLevelOffline;
972 SetTimeInfo(timeInfo);
973 SetRenderingOffline(renderingOffline);
977 while (mMidiMsgsFromEditor.Pop(msg))
984void VSTCALLBACK IPlugVST2::VSTProcess(AEffect* pEffect,
float** inputs,
float** outputs, VstInt32 nFrames)
988 _this->VSTPreProcess(inputs, outputs, nFrames);
989 ENTER_PARAMS_MUTEX_STATIC
990 _this->ProcessBuffersAccumulating(nFrames);
991 LEAVE_PARAMS_MUTEX_STATIC
992 _this->OutputSysexFromEditor();
995void VSTCALLBACK IPlugVST2::VSTProcessReplacing(AEffect* pEffect,
float** inputs,
float** outputs, VstInt32 nFrames)
999 _this->VSTPreProcess(inputs, outputs, nFrames);
1000 ENTER_PARAMS_MUTEX_STATIC
1001 _this->ProcessBuffers((
float) 0.0f, nFrames);
1002 LEAVE_PARAMS_MUTEX_STATIC
1003 _this->OutputSysexFromEditor();
1006void VSTCALLBACK IPlugVST2::VSTProcessDoubleReplacing(AEffect* pEffect,
double** inputs,
double** outputs, VstInt32 nFrames)
1010 _this->VSTPreProcess(inputs, outputs, nFrames);
1011 ENTER_PARAMS_MUTEX_STATIC
1012 _this->ProcessBuffers((
double) 0.0, nFrames);
1013 LEAVE_PARAMS_MUTEX_STATIC
1014 _this->OutputSysexFromEditor();
1017float VSTCALLBACK IPlugVST2::VSTGetParameter(AEffect *pEffect, VstInt32 idx)
1019 Trace(TRACELOC,
"%d", idx);
1021 if (idx >= 0 && idx < _this->NParams())
1023 ENTER_PARAMS_MUTEX_STATIC
1024 const float val = (float) _this->GetParam(idx)->GetNormalized();
1025 LEAVE_PARAMS_MUTEX_STATIC
1032void VSTCALLBACK IPlugVST2::VSTSetParameter(AEffect *pEffect, VstInt32 idx,
float value)
1034 Trace(TRACELOC,
"%d:%f", idx, value);
1036 if (idx >= 0 && idx < _this->NParams())
1038 ENTER_PARAMS_MUTEX_STATIC
1039 _this->GetParam(idx)->SetNormalized(value);
1041 _this->OnParamChange(idx, kHost);
1042 LEAVE_PARAMS_MUTEX_STATIC
1046void IPlugVST2::OutputSysexFromEditor()
1049 if(mSysExDataFromEditor.ElementsAvailable())
1051 while (mSysExDataFromEditor.Pop(mSysexBuf))
1053 ISysEx smsg {mSysexBuf.mOffset, mSysexBuf.mData, mSysexBuf.mSize};
Manages a block of memory, for plug-in settings store/recall.
static int GetIPlugVerFromChunk(const IByteChunk &chunk, int &position)
Helper method to retrieve the IPlug version number from the beginning of the byte chunk.
uint8_t * GetData()
Gets a ptr to the chunk data.
static void InitChunkWithIPlugVer(IByteChunk &chunk)
This method is used in order to place the IPlug version number in the chunk when serialising data.
int Size() const
Returns the current size of the chunk.
int Resize(int newSize)
Resizes the chunk.
EParamType Type() const
Get the parameter's type.
double ToNormalized(double nonNormalizedValue) const
Convert a real value to normalized value for this parameter.
void GetBounds(double &lo, double &hi) const
Get the minimum and maximum real value of the parameter's range in one method call.
double StringToValue(const char *str) const
Convert a textual representation of the parameter value to a double (real value)
The base class of an IPlug plug-in, which interacts with the different plug-in APIs.
virtual bool GetMidiNoteText(int noteNumber, char *str) const
Override this method to provide custom text linked to MIDI note numbers in API classes that support t...
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.
bool GetTailIsInfinite() const
virtual void ProcessMidiMsg(const IMidiMsg &msg)
Override this method to handle incoming MIDI messages.
virtual void SetLatency(int latency)
Call this if the latency of your plug-in changes after initialization (perhaps from OnReset() ) This ...
bool IsInstrument() const
virtual void ProcessSysEx(const ISysEx &msg)
Override this method to handle incoming MIDI System Exclusive (SysEx) messages.
int MaxNChannels(ERoute direction) const
void LimitToStereoIO()
This is called by IPlugVST in order to limit a plug-in to stereo I/O for certain picky hosts.
virtual void OnActivate(bool active)
Override OnActivate() which should be called by the API class when a plug-in is "switched on" by the ...
virtual void OnReset()
Override this method in your plug-in class to do something prior to playback etc.
VST2.4 API base class for an IPlug plug-in.
void InformHostOfParamChange(int idx, double normalizedValue) override
Implemented by the API class, called by the UI via SetParameterValue() with the value of a parameter ...
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 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 ...
void HostSpecificInit() override
This method is implemented in some API classes, in order to do specific initialisation for particular...
bool SendSysEx(const ISysEx &msg) override
Send a single MIDI System Exclusive (SysEx) message // TODO: info about what thread should this be ca...
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 InformHostOfPresetChange() override
Implemented by the API class, called by the UI (etc) when the plug-in initiates a program/preset chan...
Base class that contains plug-in info and state manipulation methods.
virtual int UnserializeState(const IByteChunk &chunk, int startPos)
Override this method to unserialize custom state data, if your plugin does state chunks.
const char * GetPluginName() const
int GetPluginVersion(bool decimal) const
Get the plug-in version number.
int UnserializePresets(const IByteChunk &chunk, int startPos)
[VST2 only] Called when the VST2 host calls effSetChunk for a bank *
virtual bool SerializeState(IByteChunk &chunk) const
Override this method to serialize custom state data, if your plugin does state chunks.
bool DoesStateChunks() const
void ModifyCurrentPreset(const char *name=0)
This method should update the current preset with current values NOTE: This is only relevant for VST2...
int GetCurrentPresetIdx() const
Get the index of the current, active preset.
const char * GetMfrName() const
Get the manufacturer name as a CString.
bool RestorePreset(int idx)
Restore a preset by index.
bool SerializePresets(IByteChunk &chunk) const
[VST2 only] Called when the VST2 host calls effGetChunk for a bank *
const char * GetPresetName(int idx) const
Get the name a preset.
virtual void OnPresetsModified()
[VST2 only] Called when the preset name is changed by the host
const char * GetProductName() const
Get the product name as a CString.
Encapsulates information about the host transport state.
Used for key press info, such as ASCII representation, virtual key (mapped to win32 codes) and modifi...
Encapsulates a MIDI message and provides helper functions.
A struct for dealing with SysEx messages.