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.