void IGraphics::SetParameterFromPlug(int paramIdx, double value, bool normalized) { if (!normalized) { IParam* pParam = mPlug->GetParam(paramIdx); value = pParam->GetNormalized(value); } int i, n = mControls.GetSize(); IControl** ppControl = mControls.GetList(); for (i = 0; i < n; ++i, ++ppControl) { IControl* pControl = *ppControl; if (pControl->ParamIdx() == paramIdx) { //WDL_MutexLock lock(&mMutex); pControl->SetValueFromPlug(value); // Could be more than one, don't break until we check them all. } // now look for any auxilliary parameters int auxParamIdx = pControl->AuxParamIdx(paramIdx); if (auxParamIdx > -1) // there are aux params { pControl->SetAuxParamValueFromPlug(auxParamIdx, value); } } }
ParamValue PLUGIN_API IPlugVST3Plugin::plainParamToNormalized(ParamID tag, ParamValue plainValue) { IParam* param = GetParam(tag); if (param) { return param->GetNormalized(plainValue); } return plainValue; }
ParamValue PLUGIN_API IPlugVST3::getParamNormalized(ParamID tag) { IParam* param = GetParam(tag); if (param) { return param->GetNormalized(); } return 0.0; }
void IGraphics::SetParameterFromPlug(int paramIdx, double value, bool normalized) { if (!normalized) { IParam* pParam = mPlug->GetParam(paramIdx); value = pParam->GetNormalized(value); } int i, n = mControls.GetSize(); IControl** ppControl = mControls.GetList(); for (i = 0; i < n; ++i, ++ppControl) { IControl* pControl = *ppControl; if (pControl->ParamIdx() == paramIdx) { //WDL_MutexLock lock(&mMutex); pControl->SetValueFromPlug(value); // Could be more than one, don't break until we check them all. } } }
void IGraphics::ClampControl(int paramIdx, double lo, double hi, bool normalized) { if (!normalized) { IParam* pParam = mPlug->GetParam(paramIdx); lo = pParam->GetNormalized(lo); hi = pParam->GetNormalized(hi); } int i, n = mControls.GetSize(); IControl** ppControl = mControls.GetList(); for (i = 0; i < n; ++i, ++ppControl) { IControl* pControl = *ppControl; if (pControl->ParamIdx() == paramIdx) { pControl->Clamp(lo, hi); } // Could be more than one, don't break until we check them all. } }
ParamValue PLUGIN_API IPlugVST3Plugin::getParamNormalized(ParamID tag) { if (tag == kBypassParam) { return (ParamValue) mIsBypassed; } // else if (tag == kPresetParam) // { // return (ParamValue) ToNormalizedParam(mCurrentPresetIdx, 0, NPresets(), 1.); // } IParam* param = GetParam(tag); if (param) { return param->GetNormalized(); } return 0.0; }
VstIntPtr VSTCALLBACK IPlugVST::VSTDispatcher(AEffect *pEffect, VstInt32 opCode, VstInt32 idx, VstIntPtr value, void *ptr, float opt) { // VSTDispatcher is an IPlugVST class member, we can access anything in IPlugVST from here. IPlugVST* _this = (IPlugVST*) pEffect->object; if (!_this) { return 0; } IPlugBase::IMutexLock lock(_this); // Handle a couple of opcodes here to make debugging easier. switch (opCode) { case effEditIdle: case __effIdleDeprecated: #ifdef USE_IDLE_CALLS _this->OnIdle(); #endif return 0; } Trace(TRACELOC, "%d(%s):%d:%d", opCode, VSTOpcodeStr(opCode), idx, (int) value); switch (opCode) { case effOpen: { _this->HostSpecificInit(); _this->OnParamReset(); return 0; } case effClose: { lock.Destroy(); DELETE_NULL(_this); return 0; } case effGetParamLabel: { if (idx >= 0 && idx < _this->NParams()) { strcpy((char*) ptr, _this->GetParam(idx)->GetLabelForHost()); } return 0; } case effGetParamDisplay: { if (idx >= 0 && idx < _this->NParams()) { _this->GetParam(idx)->GetDisplayForHost((char*) ptr); } return 0; } case effGetParamName: { if (idx >= 0 && idx < _this->NParams()) { strcpy((char*) ptr, _this->GetParam(idx)->GetNameForHost()); } return 0; } case effString2Parameter: { if (idx >= 0 && idx < _this->NParams()) { if (ptr) { IParam* pParam = _this->GetParam(idx); double v = VSTString2Parameter(pParam, (char*)ptr); if (_this->GetGUI()) _this->GetGUI()->SetParameterFromPlug(idx, v, false); pParam->Set(v); _this->OnParamChange(idx); } return 1; } return 0; } case effSetSampleRate: { _this->SetSampleRate(opt); _this->Reset(); return 0; } case effSetBlockSize: { _this->SetBlockSize(value); _this->Reset(); return 0; } case effMainsChanged: { if (!value) { _this->OnActivate(false); _this->Reset(); } else { _this->OnActivate(true); } return 0; } case effEditGetRect: { if (ptr && _this->GetGUI()) { *(ERect**) ptr = &(_this->mEditRect); return 1; } ptr = 0; return 0; } case effEditOpen: { IGraphics* pGraphics = _this->GetGUI(); if (pGraphics) { #if defined(_WIN32) || defined(IPLUG_NO_CARBON_SUPPORT) if (!pGraphics->OpenWindow(ptr)) pGraphics=0; #else // OSX, check if we are in a Cocoa VST host bool iscocoa = (_this->mHasVSTExtensions&VSTEXT_COCOA); if (iscocoa && !pGraphics->OpenWindow(ptr)) pGraphics=0; if (!iscocoa && !pGraphics->OpenWindow(ptr, 0)) pGraphics=0; #endif if (pGraphics) { _this->OnGUIOpen(); return 1; } } return 0; } case effEditClose: { if (_this->GetGUI()) { _this->OnGUIClose(); _this->GetGUI()->CloseWindow(); return 1; } return 0; } case __effIdentifyDeprecated: { return 'NvEf'; // Random deprecated magic. } case effGetChunk: { BYTE** ppData = (BYTE**) ptr; if (ppData) { bool isBank = (!idx); ByteChunk* pChunk = (isBank ? &(_this->mBankState) : &(_this->mState)); InitializeVSTChunk(pChunk); bool savedOK = true; if (isBank) { _this->ModifyCurrentPreset(); savedOK = _this->SerializePresets(pChunk); //savedOK = _this->SerializeState(pChunk); } else { savedOK = _this->SerializeState(pChunk); } if (savedOK && pChunk->Size()) { *ppData = pChunk->GetBytes(); return pChunk->Size(); } } return 0; } case effSetChunk: { if (ptr) { bool isBank = (!idx); ByteChunk* pChunk = (isBank ? &(_this->mBankState) : &(_this->mState)); pChunk->Resize(value); memcpy(pChunk->GetBytes(), ptr, value); int pos = 0; int iplugVer = GetIPlugVerFromChunk(pChunk, &pos); isBank &= (iplugVer >= 0x010000); if (isBank) { pos = _this->UnserializePresets(pChunk, pos); //pos = _this->UnserializeState(pChunk, pos); } else { pos = _this->UnserializeState(pChunk, pos); _this->ModifyCurrentPreset(); } if (pos >= 0) { _this->RedrawParamControls(); return 1; } } return 0; } case effProcessEvents: { VstEvents* pEvents = (VstEvents*) ptr; if (pEvents && pEvents->events) { for (int i = 0; i < pEvents->numEvents; ++i) { VstEvent* pEvent = pEvents->events[i]; if (pEvent) { if (pEvent->type == kVstMidiType) { VstMidiEvent* pME = (VstMidiEvent*) pEvent; IMidiMsg msg(pME->deltaFrames, pME->midiData[0], pME->midiData[1], pME->midiData[2]); _this->ProcessMidiMsg(&msg); //#ifdef TRACER_BUILD // msg.LogMsg(); //#endif } else if (pEvent->type == kVstSysExType) { VstMidiSysexEvent* pSE = (VstMidiSysexEvent*) pEvent; ISysEx sysex(pSE->deltaFrames, (const BYTE*)pSE->sysexDump, pSE->dumpBytes); _this->ProcessSysEx(&sysex); } } } return 1; } return 0; } case effCanBeAutomated: { return 1; } case effGetInputProperties: { if (ptr && idx >= 0 && idx < _this->NInChannels()) { VstPinProperties* pp = (VstPinProperties*) ptr; pp->flags = kVstPinIsActive; if (!(idx%2) && idx < _this->NInChannels()-1) { pp->flags |= kVstPinIsStereo; } sprintf(pp->label, "Input %d", idx + 1); return 1; } return 0; } case effGetOutputProperties: { if (ptr && idx >= 0 && idx < _this->NOutChannels()) { VstPinProperties* pp = (VstPinProperties*) ptr; pp->flags = kVstPinIsActive; if (!(idx%2) && idx < _this->NOutChannels()-1) { pp->flags |= kVstPinIsStereo; } sprintf(pp->label, "Output %d", idx + 1); return 1; } return 0; } case effGetPlugCategory: { if (_this->IsInst()) return kPlugCategSynth; return kPlugCategEffect; } case effProcessVarIo: { // VstVariableIo* pIO = (VstVariableIo*) ptr; // For offline processing (of audio files?) return 0; } case effSetSpeakerArrangement: { VstSpeakerArrangement* pInputArr = (VstSpeakerArrangement*) value; VstSpeakerArrangement* pOutputArr = (VstSpeakerArrangement*) ptr; if (pInputArr) { int n = pInputArr->numChannels; _this->SetInputChannelConnections(0, n, true); _this->SetInputChannelConnections(n, _this->NInChannels() - n, false); } if (pOutputArr) { int n = pOutputArr->numChannels; _this->SetOutputChannelConnections(0, n, true); _this->SetOutputChannelConnections(n, _this->NOutChannels() - n, false); } return 1; } case effGetSpeakerArrangement: { VstSpeakerArrangement** ppInputArr = (VstSpeakerArrangement**) value; VstSpeakerArrangement** ppOutputArr = (VstSpeakerArrangement**) ptr; if (ppInputArr) { *ppInputArr = &(_this->mInputSpkrArr); } if (ppOutputArr) { *ppOutputArr = &(_this->mOutputSpkrArr); } return 1; } case effGetEffectName: { if (ptr) { strcpy((char*) ptr, _this->GetEffectName()); return 1; } return 0; } case effGetProductString: { if (ptr) { strcpy((char*) ptr, _this->GetProductName()); return 1; } return 0; } case effGetVendorString: { if (ptr) { strcpy((char*) ptr, _this->GetMfrName()); return 1; } return 0; } case effGetVendorVersion: { return _this->GetEffectVersion(true); } case effCanDo: { if (ptr) { Trace(TRACELOC, "VSTCanDo(%s)", (char*) ptr); if (!strcmp((char*) ptr, "receiveVstTimeInfo")) { return 1; } if (_this->DoesMIDI()) { if (_this->DoesMIDI() & 1) { if (!strcmp((char*) ptr, "sendVstEvents") || !strcmp((char*) ptr, "sendVstMidiEvent")) { return 1; } } if (_this->DoesMIDI() <= 2) { if (!strcmp((char*) ptr, "receiveVstEvents") || !strcmp((char*) ptr, "receiveVstMidiEvent")) { return 1; } } //if (!strcmp((char*) ptr, "midiProgramNames")) { // return 1; //} } // Support Reaper VST extensions: http://www.reaper.fm/sdk/vst/ if (!strcmp((char*) ptr, "hasCockosExtensions")) { _this->mHasVSTExtensions |= VSTEXT_COCKOS; return 0xbeef0000; } else if (!strcmp((char*) ptr, "hasCockosViewAsConfig")) { _this->mHasVSTExtensions |= VSTEXT_COCOA; return 0xbeef0000; } } return 0; } case effVendorSpecific: { switch (idx) { // Mouse wheel case 0x73744341: { if (value == 0x57686565) { IGraphics* pGraphics = _this->GetGUI(); if (pGraphics) { return pGraphics->ProcessMouseWheel(opt); } } break; } // Support Reaper VST extensions: http://www.reaper.fm/sdk/vst/ case effGetParamDisplay: { if (ptr) { if (value >= 0 && value < _this->NParams()) { _this->GetParam(value)->GetDisplayForHost((double) opt, true, (char*) ptr); } return 0xbeef; } break; } case effString2Parameter: { if (ptr && value >= 0 && value < _this->NParams()) { if (*(char*) ptr != '\0') { IParam* pParam = _this->GetParam(value); sprintf((char*) ptr, "%.17f", pParam->GetNormalized(VSTString2Parameter(pParam, (char*) ptr))); } return 0xbeef; } break; } case kVstParameterUsesIntStep: { if (value >= 0 && value < _this->NParams()) { IParam* pParam = _this->GetParam(value); switch (pParam->Type()) { case IParam::kTypeBool: { return 0xbeef; } case IParam::kTypeInt: case IParam::kTypeEnum: { double min, max; pParam->GetBounds(&min, &max); if (fabs(max - min) < 1.5) { return 0xbeef; } break; } } } break; } } return 0; } case effGetProgram: { return _this->GetCurrentPresetIdx(); } case effSetProgram: { //if (!(_this->DoesStateChunks())) { _this->ModifyCurrentPreset(); //} _this->RestorePreset((int) value); return 0; } case effGetProgramNameIndexed: { strcpy((char*) ptr, _this->GetPresetName(idx)); return (CSTR_NOT_EMPTY((char*) ptr) ? 1 : 0); } case effSetProgramName: { if (ptr) { _this->ModifyCurrentPreset((char*) ptr); } return 0; } case effGetProgramName: { if (ptr) { int idx = _this->GetCurrentPresetIdx(); strcpy((char*) ptr, _this->GetPresetName(idx)); } return 0; } case effGetMidiKeyName: { if (ptr) { MidiKeyName* pMKN = (MidiKeyName*) ptr; pMKN->keyName[0] = '\0'; if (_this->MidiNoteName(pMKN->thisKeyNumber, pMKN->keyName)) { return 1; } } return 0; } case effGetVstVersion: { return VST_VERSION; } case effBeginSetProgram: case effEndSetProgram: case effGetMidiProgramName: case effHasMidiProgramsChanged: case effGetMidiProgramCategory: case effGetCurrentMidiProgram: case effSetBypass: default: { return 0; } } }