예제 #1
0
ComponentResult IPlugProcess::SetChunk(OSType chunkID, SFicPlugInChunk *chunk)
{
  TRACE;

  if (chunkID == mPluginID)
  {
    int dataSize = chunk->fSize - sizeof(SFicPlugInChunkHeader);

    ByteChunk IPlugChunk;
    IPlugChunk.PutBytes(chunk->fData, dataSize);
    mPlug->UnserializeState(&IPlugChunk, 0);
    
    for (int i = 0; i< mPlug->NParams(); i++)
    {
      IParam *p = mPlug->GetParam(i);
      int idx = i+kPTParamIdxOffset;
      
      switch (p->Type())
      {
        case IParam::kTypeDouble:
        {
          CPluginControl_Continuous *control = dynamic_cast<CPluginControl_Continuous*>(GetControl(idx));
          SetControlValue(idx, control->ConvertContinuousToControl( p->Value() ));
          break;
        }
        case IParam::kTypeInt:
        case IParam::kTypeEnum:
        case IParam::kTypeBool:
        {
          CPluginControl_Discrete *control = dynamic_cast<CPluginControl_Discrete*>(GetControl(idx));
          SetControlValue(idx, control->ConvertDiscreteToControl( p->Int() ));
          break;
        }
        default:
          break;
      }
    }
    
    fNumPlugInChanges++;
    
    return noErr;
  }

  return kChunkRangeErr;
}
예제 #2
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;
    }
      //could implement effGetParameterProperties to group parameters, but can't find a host that supports it
//    case effGetParameterProperties:
//    {
//      if (idx >= 0 && idx < _this->NParams())
//      {
//        VstParameterProperties* props = (VstParameterProperties*) ptr;
//        
//        props->flags = kVstParameterSupportsDisplayCategory;
//        props->category = idx+1;
//        props->numParametersInCategory = 1;
//        strcpy(props->categoryLabel, "test");
//      }
//      return 1;
//    }
    case effGetParameterProperties:
    {
      if (idx >= 0 && idx < _this->NParams())
      {
        VstParameterProperties* props = (VstParameterProperties*) ptr;
        props->flags = 0;
        IParam* pParam = _this->GetParam(idx);
        if (pParam->Type() == IParam::kTypeBool) {
          props->flags |= kVstParameterIsSwitch;
        }
        if (pParam->Type() == IParam::kTypeEnum || pParam->Type() == IParam::kTypeInt) {
          props->flags |= kVstParameterUsesFloatStep;
          int possibleValuesCount = (int) (pParam->GetMax() - pParam->GetMin());
          props->stepFloat = 1.0 / possibleValuesCount;
          props->smallStepFloat = props->stepFloat;
          props->largeStepFloat = props->stepFloat;
        }
      }
      return 1;
    }
    case effString2Parameter:
    {
      if (idx >= 0 && idx < _this->NParams())
      {
        if (ptr)
        {
          double v;
          IParam* pParam = _this->GetParam(idx);
          if (pParam->GetNDisplayTexts())
          {
            int vi;
            if (!pParam->MapDisplayText((char*)ptr, &vi)) return 0;
            v = (double)vi;
          }
          else
          {
            v = atof((char*)ptr);
            if (pParam->DisplayIsNegated()) v = -v;
          }
          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)
      {
        #ifdef _WIN32
          if (!pGraphics->OpenWindow(ptr)) pGraphics=0;
        #else   // OSX, check if we are in a Cocoa VST host
          #if defined(__LP64__)
          if (!pGraphics->OpenWindow(ptr)) pGraphics=0;
          #else
          bool iscocoa = (_this->mHasVSTExtensions&VSTEXT_COCOA);
          if (iscocoa && !pGraphics->OpenWindow(ptr)) pGraphics=0;
          if (!iscocoa && !pGraphics->OpenWindow(ptr, 0)) pGraphics=0;
          #endif
        #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));
        _this->InitChunkWithIPlugVer(pChunk);
        bool savedOK = true;
        
        if (isBank)
        {
          _this->ModifyCurrentPreset();
          savedOK = _this->SerializePresets(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 = _this->GetIPlugVerFromChunk(pChunk, &pos);
        isBank &= (iplugVer >= 0x010000);
        
        if (isBank)
        {
          pos = _this->UnserializePresets(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;
        }

        if (_this->GetInputLabel(idx)->GetLength())
        {
          sprintf(pp->label, "%s", _this->GetInputLabel(idx)->Get());
        }
        else
        {
          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;
        }

        if (_this->GetOutputLabel(idx)->GetLength())
        {
          sprintf(pp->label, "%s", _this->GetOutputLabel(idx)->Get());
        }
        else
        {
          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 effCanDo:
    {
      if (ptr)
      {
        Trace(TRACELOC, "VSTCanDo(%s)", (char*) ptr);
        if (!strcmp((char*) ptr, "receiveVstTimeInfo"))
        {
          return 1;
        }
        if (_this->DoesMIDI())
        {
          if (!strcmp((char*) ptr, "sendVstEvents") ||
              !strcmp((char*) ptr, "sendVstMidiEvent") ||
              !strcmp((char*) ptr, "receiveVstEvents") ||
              !strcmp((char*) ptr, "receiveVstMidiEvent"))   // ||
          {
            //!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 effGetTailSize:
    {
      return _this->GetTailSize();
    }
    case effVendorSpecific:
    {
      // Support Reaper VST extensions: http://www.reaper.fm/sdk/vst/
      if (idx == effGetParamDisplay && ptr)
      {
        if (value >= 0 && value < _this->NParams())
        {
          _this->GetParam(value)->GetDisplayForHost((double) opt, true, (char*) ptr);
        }
        return 0xbeef;
      }

      if (idx == kVstParameterUsesIntStep)
      {
        if (value >= 0 && value < _this->NParams())
        {
          if (_this->GetParam(value)->Type() != IParam::kTypeDouble)
          {
            return 0xbeef;
          }
        }
      }

      return 0;
    }
    case effGetProgram:
    {
      return _this->GetCurrentPresetIdx();
    }
    case effSetProgram:
    {
      if (_this->DoesStateChunks() == false)
      {
        _this->ModifyCurrentPreset(); // TODO: test, something is funny about this http://forum.cockos.com/showpost.php?p=485113&postcount=22
      }
      _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);
        _this->PresetsChangedByHost();
      }
      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 effEndSetProgram:
    case effBeginSetProgram:
    case effGetMidiProgramName:
    case effHasMidiProgramsChanged:
    case effGetMidiProgramCategory:
    case effGetCurrentMidiProgram:
    case effSetBypass:
    default:
    {
      return 0;
    }
  }
}
예제 #3
0
void IPlugProcess::EffectInit()
{
  TRACE;

  if (mPlug)
  {
    AddControl(new CPluginControl_OnOff('bypa', "Master Bypass\nMastrByp\nMByp\nByp", false, true)); // Default to off
    DefineMasterBypassControlIndex(1);

    int paramCount = mPlug->NParams();

    for (int i=0; i<paramCount; i++)
    {
      IParam *p = mPlug->GetParam(i);

      switch (p->Type())
      {
        case IParam::kTypeDouble:
          AddControl(new CPluginControl_Linear(' ld '+i, p->GetNameForHost(), p->GetMin(), p->GetMax(), p->GetStep(), p->GetDefault(), p->GetCanAutomate()));
          break;
        case IParam::kTypeInt:
          AddControl(new CPluginControl_Discrete(' ld '+i, p->GetNameForHost(), (long) p->GetMin(), (long) p->GetMax(), (long) p->GetDefault(), p->GetCanAutomate()));
          break;
        case IParam::kTypeEnum:
        case IParam::kTypeBool:
        {
          std::vector<std::string> displayTexts;
          
          for (int j=0; j<p->GetNDisplayTexts(); j++)
          {
            displayTexts.push_back(p->GetDisplayTextAtIdx(j));
          }

          assert(displayTexts.size());
          AddControl(new CPluginControl_List(' ld '+i, p->GetNameForHost(), displayTexts, (long) p->GetDefault(), p->GetCanAutomate()));
          break;
        }
        default:
          break;
      }

    }

#if PLUG_DOES_MIDI
    if (!IsAS())
    {
      ComponentResult result = noErr;

      Cmn_Int32 requestedVersion = 7;

      std::string midiNodeName(PLUG_NAME" Midi");

      while (requestedVersion)
      {
        result = DirectMidi_RegisterClient(requestedVersion, this, reinterpret_cast<Cmn_UInt32>(this), (void **)&mDirectMidiInterface);

        if (result == noErr && mDirectMidiInterface != NULL)
        {
          mDirectMidiInterface->CreateRTASBufferedMidiNode(0, const_cast<char *>(midiNodeName.c_str()), 1);

          break;
        }

        requestedVersion--;
      }
    }
#endif

    mPlug->SetIO(GetNumInputs(), GetNumOutputs());
    mPlug->SetSampleRate(GetSampleRate());
    mPlug->Reset();
  }
}
tresult PLUGIN_API IPlugVST3Plugin::initialize (FUnknown* context)
{
  TRACE;

  tresult result = SingleComponentEffect::initialize(context);

  String128 tmpStringBuf;
  char hostNameCString[128];
  FUnknownPtr<IHostApplication>app(context);

  if (app)
  {
    app->getName(tmpStringBuf);
    Steinberg::UString(tmpStringBuf, 128).toAscii(hostNameCString, 128);
    SetHost(hostNameCString, 0); // Can't get version in VST3
  }

  if (result == kResultOk)
  {
    int maxInputs = getSpeakerArrForChans(NInChannels()-mScChans);
    if(maxInputs < 0) maxInputs = 0;

    // add io buses with the maximum i/o to start with

    if (maxInputs)
    {
      Steinberg::UString(tmpStringBuf, 128).fromAscii(GetInputBusLabel(0)->Get(), 128);
      addAudioInput(tmpStringBuf, maxInputs);
    }

    if(!mIsInst) // if effect, just add one output bus with max chan count
    {
      Steinberg::UString(tmpStringBuf, 128).fromAscii(GetOutputBusLabel(0)->Get(), 128);
      addAudioOutput(tmpStringBuf, getSpeakerArrForChans(NOutChannels()) );
    }
    else
    {
      for (int i = 0, busIdx = 0; i < NOutChannels(); i+=2, busIdx++)
      {
        Steinberg::UString(tmpStringBuf, 128).fromAscii(GetOutputBusLabel(busIdx)->Get(), 128);
        addAudioOutput(tmpStringBuf, SpeakerArr::kStereo );
      }
    }

    if (mScChans)
    {
      if (mScChans > 2) mScChans = 2;
      Steinberg::UString(tmpStringBuf, 128).fromAscii(GetInputBusLabel(1)->Get(), 128);
      addAudioInput(tmpStringBuf, getSpeakerArrForChans(mScChans), kAux, 0);
    }

    if(DoesMIDI())
    {
      addEventInput (STR16("MIDI Input"), 1);
      //addEventOutput(STR16("MIDI Output"), 1);
    }

    if (NPresets())
    {
      parameters.addParameter(new Parameter(STR16("Preset"),
                                            kPresetParam,
                                            STR16(""),
                                            0,
                                            NPresets(),
                                            ParameterInfo::kIsProgramChange));
    }

    if(!mIsInst)
    {
      StringListParameter * bypass = new StringListParameter(STR16("Bypass"),
                                                            kBypassParam,
                                                            0,
                                                            ParameterInfo::kCanAutomate | ParameterInfo::kIsBypass | ParameterInfo::kIsList);
      bypass->appendString(STR16("off"));
      bypass->appendString(STR16("on"));
      parameters.addParameter(bypass);
    }

    for (int i=0; i<NParams(); i++)
    {
      IParam *p = GetParam(i);

      int32 flags = 0;
      UnitID unitID = kRootUnitId;
      
      const char* paramGroupName = p->GetParamGroupForHost();

      if (CSTR_NOT_EMPTY(paramGroupName))
      {        
        for(int j = 0; j < mParamGroups.GetSize(); j++)
        {
          if(strcmp(paramGroupName, mParamGroups.Get(j)) == 0)
          {
            unitID = j+1;
          }
        }
        
        if (unitID == kRootUnitId) // new unit, nothing found, so add it
        {
          mParamGroups.Add(paramGroupName);
          unitID = mParamGroups.GetSize();
        }
      }

      if (p->GetCanAutomate())
      {
        flags |= ParameterInfo::kCanAutomate;
      }

      switch (p->Type())
      {
        case IParam::kTypeDouble:
        case IParam::kTypeInt:
        {
          Parameter* param = new RangeParameter( STR16(p->GetNameForHost()),
                                                 i,
                                                 STR16(p->GetLabelForHost()),
                                                 p->GetMin(),
                                                 p->GetMax(),
                                                 p->GetDefault(),
                                                 0, // continuous
                                                 flags,
                                                 unitID);

          param->setPrecision (p->GetPrecision());
          parameters.addParameter(param);

          break;
        }
        case IParam::kTypeEnum:
        case IParam::kTypeBool:
        {
          StringListParameter* param = new StringListParameter (STR16(p->GetNameForHost()),
                                                                i,
                                                                STR16(p->GetLabelForHost()),
                                                                flags | ParameterInfo::kIsList,
                                                                unitID);

          int nDisplayTexts = p->GetNDisplayTexts();

          assert(nDisplayTexts);

          for (int j=0; j<nDisplayTexts; j++)
          {
            param->appendString(STR16(p->GetDisplayText(j)));
          }

          parameters.addParameter(param);
          break;
        }
        default:
          break;
      }
    }
  }

  OnHostIdentified();
  RestorePreset(0);
  
  return result;
}
예제 #5
0
파일: IPlugVST.cpp 프로젝트: TaleTN/WDL
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;
    }
	}
}
예제 #6
0
// static
LRESULT CALLBACK IGraphicsWin::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  if (msg == WM_CREATE) {
    LPCREATESTRUCT lpcs = (LPCREATESTRUCT) lParam;
    SetWindowLongPtr(hWnd, GWLP_USERDATA, (LPARAM) (lpcs->lpCreateParams));
		int mSec = int(1000.0 / sFPS);
		SetTimer(hWnd, IPLUG_TIMER_ID, mSec, NULL);
		SetFocus(hWnd);
		return 0;
	}

	IGraphicsWin* pGraphics = (IGraphicsWin*) GetWindowLongPtr(hWnd, GWLP_USERDATA);
	char txt[MAX_EDIT_LEN];

	if (!pGraphics || hWnd != pGraphics->mPlugWnd) {
		return DefWindowProc(hWnd, msg, wParam, lParam);
	}
	if (pGraphics->mParamEditWnd && pGraphics->mParamEditMsg == kEditing) {
		if (msg == WM_RBUTTONDOWN) {
			pGraphics->mParamEditMsg = kCancel;
			return 0;
		}
		return DefWindowProc(hWnd, msg, wParam, lParam);
	}

	switch (msg) {

		case WM_TIMER: {
			if (wParam == IPLUG_TIMER_ID) {

				if (pGraphics->mParamEditWnd && pGraphics->mParamEditMsg != kNone) {
					switch (pGraphics->mParamEditMsg) {
            case kUpdate: {
            				if (!pGraphics->mEdParam) break;
							pGraphics->mEdParam->GetDisplayForHost(txt);
							char currentText[MAX_PARAM_LEN];
							SendMessage(pGraphics->mParamEditWnd, WM_GETTEXT, MAX_PARAM_LEN, (LPARAM) currentText);
							if (strcmp(txt, currentText))
							{
								IParam* pParam = pGraphics->mEdParam;
								if (pParam->GetNDisplayTexts() && (pParam->Type() == IParam::kTypeEnum || pParam->Type() == IParam::kTypeBool))
									SendMessage(pGraphics->mParamEditWnd, CB_SELECTSTRING, -1, (LPARAM) txt);
								else
									SendMessage(pGraphics->mParamEditWnd, WM_SETTEXT, 0, (LPARAM) txt);
							}
							break;
            }
            case kCommit: {
							SendMessage(pGraphics->mParamEditWnd, WM_GETTEXT, MAX_EDIT_LEN, (LPARAM) txt);
							pGraphics->SetFromStringAfterPrompt(pGraphics->mEdControl, pGraphics->mEdParam, txt);
							// Fall through.
            }
            case kCancel:
			      {
							SetWindowLongPtr(pGraphics->mParamEditWnd, GWLP_WNDPROC, (LPARAM) pGraphics->mDefEditProc);
							DestroyWindow(pGraphics->mParamEditWnd);
							pGraphics->mParamEditWnd = 0;
							pGraphics->mEdParam = 0;
							pGraphics->mEdControl = 0;
							pGraphics->mDefEditProc = 0;
            }
            break;            
          }
					pGraphics->mParamEditMsg = kNone;
					//return 0;
				}

        IRECT dirtyR;
        if (pGraphics->IsDirty(&dirtyR)) {
          RECT r = { dirtyR.L, dirtyR.T, dirtyR.R, dirtyR.B };
          InvalidateRect(hWnd, &r, FALSE);
          UpdateWindow(hWnd);
          if (pGraphics->mParamEditWnd) {
            pGraphics->mParamEditMsg = kUpdate;
          }
        }
      }
      return 0;
    }
    case WM_RBUTTONDOWN: {
			if (pGraphics->mParamEditWnd) {
				pGraphics->mParamEditMsg = kCancel;
				return 0;
			}
			// Else fall through.
    }
    case WM_LBUTTONDOWN: {
			if (pGraphics->mParamEditWnd) pGraphics->mParamEditMsg = kCommit;
			SetCapture(hWnd);
			pGraphics->OnMouseDown(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), &GetMouseMod(wParam));
			return 0;
    }
    case WM_MOUSEMOVE: {
			if (!(wParam & (MK_LBUTTON | MK_RBUTTON))) { 
        if (pGraphics->OnMouseOver(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), &GetMouseMod(wParam))) {
          TRACKMOUSEEVENT eventTrack = { sizeof(TRACKMOUSEEVENT), TME_LEAVE, hWnd, HOVER_DEFAULT };
          TrackMouseEvent(&eventTrack);
        }
			}
      else
			if (GetCapture() == hWnd) {
				pGraphics->OnMouseDrag(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), &GetMouseMod(wParam));
			}
			return 0;
    }
    case WM_MOUSELEAVE: {
      pGraphics->OnMouseOut();
      return 0;
    }
    case WM_LBUTTONUP:
    case WM_RBUTTONUP: {
      ReleaseCapture();
			pGraphics->OnMouseUp(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), &GetMouseMod(wParam));
			return 0;
    }
    case WM_LBUTTONDBLCLK: {
      if (pGraphics->OnMouseDblClick(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), &GetMouseMod(wParam))) {
        SetCapture(hWnd);
      }
			return 0;
    }
		case WM_MOUSEACTIVATE: {
			SetFocus(hWnd);
			return MA_ACTIVATE;
		}
		case WM_MOUSEWHEEL: {
			int d = GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA;
			int x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam);
			RECT r;
			GetWindowRect(hWnd, &r);
			pGraphics->OnMouseWheel(x - r.left, y - r.top, &GetMouseMod(wParam), d);
			return 0;
		}

    case WM_KEYDOWN:
    {
      bool ok = true;
      int key;     

      if (wParam == VK_SPACE) key = KEY_SPACE;
      else if (wParam == VK_UP) key = KEY_UPARROW;
      else if (wParam == VK_DOWN) key = KEY_DOWNARROW;
      else if (wParam == VK_LEFT) key = KEY_LEFTARROW;
      else if (wParam == VK_RIGHT) key = KEY_RIGHTARROW;
      else if (wParam >= '0' && wParam <= '9') key = KEY_DIGIT_0+wParam-'0';
      else if (wParam >= 'A' && wParam <= 'Z') key = KEY_ALPHA_A+wParam-'A';
      else if (wParam >= 'a' && wParam <= 'z') key = KEY_ALPHA_A+wParam-'a';
      else ok = false;

      if (ok)
      {
        POINT p;
        GetCursorPos(&p); 
        ScreenToClient(hWnd, &p);
        pGraphics->OnKeyDown(p.x, p.y, key);
      }
    }
    return 0;

		case WM_PAINT: {
      RECT r;
      if (GetUpdateRect(hWnd, &r, FALSE)) {
        IRECT ir(r.left, r.top, r.right, r.bottom);
        pGraphics->Draw(&ir);
      }
			return 0;
		}

		//case WM_CTLCOLOREDIT: {
		//	// An edit control just opened.
		//	HDC dc = (HDC) wParam;
		//	SetTextColor(dc, ///);
		//	return 0;
		//}

		case WM_CLOSE: {
			pGraphics->CloseWindow();
			return 0;
		}
	}
	return DefWindowProc(hWnd, msg, wParam, lParam);
}
예제 #7
0
tresult PLUGIN_API IPlugVST3::initialize (FUnknown* context)
{
  TRACE;
  
  tresult result = SingleComponentEffect::initialize (context);
  
  if (result == kResultOk)
  {
    addAudioInput (STR16("Audio Input"), getSpeakerArrForChans(NInChannels()) );
    addAudioOutput (STR16("Audio Output"), getSpeakerArrForChans(NOutChannels()) );
    
    if (mScChans == 1)
      addAudioInput(STR16("Sidechain Input"), SpeakerArr::kMono, kAux, 0);
    else if (mScChans >= 2)
    {
      mScChans = 2;
      addAudioInput(STR16("Sidechain Input"), SpeakerArr::kStereo, kAux, 0);
    }
        
    if(mDoesMidi) {
      addEventInput (STR16("MIDI In"), 1);
      addEventOutput(STR16("MIDI Out"), 1);
    }
    
    for (int i=0;i<NParams();i++)
    {
      IParam *p = GetParam(i);
      
      int32 flags = 0;
      
      if (p->GetCanAutomate()) {
        flags |= ParameterInfo::kCanAutomate;
      }
            
      switch (p->Type()) {
        case IParam::kTypeDouble:
        case IParam::kTypeInt:
        {
          Parameter* param = new RangeParameter ( STR16(p->GetNameForHost()), 
                                                  i, 
                                                  STR16(p->GetLabelForHost()), 
                                                  p->GetMin(), 
                                                  p->GetMax(), 
                                                  p->GetDefault(),
                                                  p->GetStep(),
                                                  flags);
          
          param->setPrecision (p->GetPrecision());
          parameters.addParameter (param);

          break;
        }
        case IParam::kTypeEnum:
        case IParam::kTypeBool: 
        {
          StringListParameter* param = new StringListParameter (STR16(p->GetNameForHost()), 
                                                                i,
                                                                STR16(p->GetLabelForHost()),
                                                                flags | ParameterInfo::kIsList);
          
          int nDisplayTexts = p->GetNDisplayTexts();
          
          assert(nDisplayTexts);

          for (int j=0; j<nDisplayTexts; j++) 
          {
            param->appendString(STR16(p->GetDisplayText(j)));
          }
          
          parameters.addParameter (param);
          break; 
        }
        default:
          break;
      }
      
    }
  }
  
  return result;
}
예제 #8
0
AAX_Result IPlugAAX::EffectInit()
{ 
  TRACE;

  AAX_CString bypassID = NULL;
  this->GetMasterBypassParameter( &bypassID );
  mBypassParameter = new AAX_CParameter<bool>(bypassID.CString(), 
                                              AAX_CString("Master Bypass"), 
                                              false, 
                                              AAX_CBinaryTaperDelegate<bool>(),
                                              AAX_CBinaryDisplayDelegate<bool>("bypass", "on"), 
                                              true);
  mBypassParameter->SetNumberOfSteps( 2 );
  mBypassParameter->SetType( AAX_eParameterType_Discrete );
  mParameterManager.AddParameter(mBypassParameter);
      
  for (int i=0;i<NParams();i++)
  {
    IParam *p = GetParam(i);
    AAX_IParameter* param = 0;
    
    WDL_String* paramID = new WDL_String("_", 1);
    paramID->SetFormatted(32, "%i", i+kAAXParamIdxOffset);
    mParamIDs.Add(paramID);
    
    switch (p->Type()) 
    {
      case IParam::kTypeDouble:
      {
        param = new AAX_CParameter<double>(paramID->Get(), 
                                          AAX_CString(p->GetNameForHost()), 
                                          p->GetDefault(), 
                                          AAX_CIPlugTaperDelegate<double>(p->GetMin(), p->GetMax(), p->GetShape()),
                                          AAX_CUnitDisplayDelegateDecorator<double>( AAX_CNumberDisplayDelegate<double>(), AAX_CString(p->GetLabelForHost())), 
                                          p->GetCanAutomate());
        
        param->SetNumberOfSteps(128); // TODO: check this https://developer.digidesign.com/index.php?L1=5&L2=13&L3=56
        param->SetType(AAX_eParameterType_Continuous);

        break;
      }
      case IParam::kTypeInt:
      {
        param = new AAX_CParameter<int>(paramID->Get(), 
                                        AAX_CString(p->GetNameForHost()), 
                                        (int)p->GetDefault(), 
                                        AAX_CLinearTaperDelegate<int>((int)p->GetMin(), (int)p->GetMax()), 
                                        AAX_CUnitDisplayDelegateDecorator<int>( AAX_CNumberDisplayDelegate<int>(), AAX_CString(p->GetLabelForHost())), 
                                        p->GetCanAutomate());
        
        param->SetNumberOfSteps(128);
        param->SetType(AAX_eParameterType_Continuous);

        break;
      }
      case IParam::kTypeEnum:
      case IParam::kTypeBool: 
      {
        int nTexts = p->GetNDisplayTexts();
        
        std::map<int, AAX_CString> displayTexts;
        
        for (int j=0; j<p->GetNDisplayTexts(); j++) 
        {
          int value;
          const char* text = p->GetDisplayTextAtIdx(j, &value);
          
          displayTexts.insert(std::pair<int, AAX_CString>(value, AAX_CString(text)) );
        }
        
        param = new AAX_CParameter<int>(paramID->Get(), 
                                        AAX_CString(p->GetNameForHost()), 
                                        (int)p->GetDefault(), 
                                        AAX_CLinearTaperDelegate<int>((int)p->GetMin(), (int)p->GetMax()), 
                                        AAX_CStringDisplayDelegate<int>(displayTexts),
                                        p->GetCanAutomate());
        
        param->SetNumberOfSteps(nTexts);
        param->SetType(AAX_eParameterType_Discrete);
                
        break; 
      }
      default:
        break;
    }
    
    mParameterManager.AddParameter(param);    
  }
  
  AAX_CSampleRate sr;
  Controller()->GetSampleRate(&sr);
  SetSampleRate(sr);
  Reset();
  
  return AAX_SUCCESS;
}