Logo Search packages:      
Sourcecode: csound version File versions  Download package

vsthost.cpp

//  vst4cs: VST HOST OPCODES FOR CSOUND
//
//  Uses code by Hermann Seib from his Vst Host program
//  and from the vst~ object by Thomas Grill,
//  which in turn borrows from the Psycle tracker.
//  VST is a trademark of Steinberg Media Technologies GmbH.
//  VST Plug-In Technology by Steinberg.
//
//  Copyright (C) 2004 Andres Cabrera, Michael Gogins
//
//  The vst4cs library is free software; you can redistribute it
//  and/or modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  The vst4cs library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with The vst4cs library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
//  02111-1307 USA

#include "vsthost.h"
#include <cmath>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/x.H>
#ifdef _WIN32
  #pragma warning(disable:4786) //gab
#endif

#ifdef MSVC
#define round int
#endif

std::map<long, std::string> VSTPlugin::masterOpcodes;
std::map<long, std::string> VSTPlugin::dispatchOpcodes;
size_t  VSTPlugin::opcodeRefCount = 0;

void VSTPlugin::initializeOpcodes()
{
    if (opcodeRefCount) {
      opcodeRefCount++;
        return;
    }
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effOpen, "effOpen"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effClose, "effClose"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effSetProgram, "effSetProgram"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effGetProgram, "effGetProgram"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effSetProgramName, "effSetProgramName"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effGetProgramName, "effGetProgramName"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effGetParamLabel, "effGetParamLabel"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effGetParamDisplay, "effGetParamDisplay"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effGetParamName, "effGetParamName"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effGetVu, "effGetVu"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effSetSampleRate, "effSetSampleRate"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effSetBlockSize, "effSetBlockSize"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effMainsChanged, "effMainsChanged"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effEditGetRect, "effEditGetRect"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effEditOpen, "effEditOpen"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effEditClose, "effEditClose"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effEditDraw, "effEditDraw"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effEditMouse, "effEditMouse"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effEditKey, "effEditKey"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effEditIdle, "effEditIdle"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effEditTop, "effEditTop"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effEditSleep, "effEditSleep"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effIdentify, "effIdentify"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effGetChunk, "effGetChunk"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effSetChunk, "effSetChunk"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effProcessEvents, "effProcessEvents"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effCanBeAutomated, "effCanBeAutomated"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effString2Parameter, "effString2Parameter"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effGetNumProgramCategories, "effGetNumProgramCategories"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effGetProgramNameIndexed, "effGetProgramNameIndexed"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effCopyProgram, "effCopyProgram"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effConnectInput, "effConnectInput"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effConnectOutput, "effConnectOutput"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effGetInputProperties, "effGetInputProperties"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effGetOutputProperties, "effGetOutputProperties"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effGetPlugCategory, "effGetPlugCategory"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effGetCurrentPosition, "effGetCurrentPosition"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effGetDestinationBuffer, "effGetDestinationBuffer"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effOfflineNotify, "effOfflineNotify"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effOfflinePrepare, "effOfflinePrepare"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effOfflineRun, "effOfflineRun"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effProcessVarIo, "effProcessVarIo"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effSetSpeakerArrangement, "effSetSpeakerArrangement"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effSetBlockSizeAndSampleRate, "effSetBlockSizeAndSampleRate"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effSetBypass, "effSetBypass"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effGetEffectName, "effGetEffectName"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effGetErrorText, "effGetErrorText"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effGetVendorString, "effGetVendorString"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effGetProductString, "effGetProductString"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effGetVendorVersion, "effGetVendorVersion"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effVendorSpecific, "effVendorSpecific"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effCanDo, "effCanDo"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effGetTailSize, "effGetTailSize"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effIdle, "effIdle"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effGetIcon, "effGetIcon"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effSetViewPosition, "effSetViewPosition"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effGetParameterProperties, "effGetParameterProperties"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effKeysRequired, "effKeysRequired"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effGetVstVersion, "effGetVstVersion"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effEditKeyDown, "effEditKeyDown"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effEditKeyUp, "effEditKeyUp"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effSetEditKnobMode, "effSetEditKnobMode"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effGetMidiProgramName, "effGetMidiProgramName"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effGetCurrentMidiProgram, "effGetCurrentMidiProgram"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effGetMidiProgramCategory, "effGetMidiProgramCategory"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effHasMidiProgramsChanged, "effHasMidiProgramsChanged"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effGetMidiKeyName, "effGetMidiKeyName"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effBeginSetProgram, "effBeginSetProgram"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effEndSetProgram, "effEndSetProgram"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effGetSpeakerArrangement, "effGetSpeakerArrangement"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effShellGetNextPlugin, "effShellGetNextPlugin"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effStartProcess, "effStartProcess"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effStopProcess, "effStopProcess"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effSetTotalSampleToProcess, "effSetTotalSampleToProcess"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effSetPanLaw, "effSetPanLaw"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effBeginLoadBank, "effBeginLoadBank"));
    dispatchOpcodes.insert(std::pair<long, std::string>(
        (long) effBeginLoadProgram, "effBeginLoadProgram"));

    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterAutomate, "audioMasterAutomate"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterVersion, "audioMasterVersion"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterCurrentId, "audioMasterCurrentId"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterIdle, "audioMasterIdle"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterPinConnected, "audioMasterPinConnected"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterWantMidi, "audioMasterWantMidi"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterGetTime, "audioMasterGetTime"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterProcessEvents, "audioMasterProcessEvents"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterSetTime, "audioMasterSetTime"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterTempoAt, "audioMasterTempoAt"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterGetNumAutomatableParameters,
        "audioMasterGetNumAutomatableParameters"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterGetParameterQuantization,
        "audioMasterGetParameterQuantization"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterIOChanged, "audioMasterIOChanged"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterNeedIdle, "audioMasterNeedIdle"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterSizeWindow, "audioMasterSizeWindow"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterGetSampleRate, "audioMasterGetSampleRate"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterGetBlockSize, "audioMasterGetBlockSize"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterGetInputLatency, "audioMasterGetInputLatency"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterGetOutputLatency, "audioMasterGetOutputLatency"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterGetPreviousPlug, "audioMasterGetPreviousPlug"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterGetNextPlug, "audioMasterGetNextPlug"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterWillReplaceOrAccumulate,
        "audioMasterWillReplaceOrAccumulate"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterGetCurrentProcessLevel,
        "audioMasterGetCurrentProcessLevel"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterGetAutomationState, "audioMasterGetAutomationState"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterOfflineStart, "audioMasterOfflineStart"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterOfflineRead, "audioMasterOfflineRead"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterOfflineWrite, "audioMasterOfflineWrite"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterOfflineGetCurrentPass,
        "audioMasterOfflineGetCurrentPass"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterOfflineGetCurrentMetaPass,
        "audioMasterOfflineGetCurrentMetaPass"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterSetOutputSampleRate,
        "audioMasterSetOutputSampleRate"));
//     masterOpcodes.insert(std::pair<long, std::string>(
//         (long) audioMasterGetSpeakerArrangement,
//         "audioMasterGetSpeakerArrangement"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterGetOutputSpeakerArrangement,
        "audioMasterGetOutputSpeakerArrangement"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterGetVendorString, "audioMasterGetVendorString"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterGetProductString, "audioMasterGetProductString"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterGetVendorVersion, "audioMasterGetVendorVersion"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterVendorSpecific, "audioMasterVendorSpecific"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterSetIcon, "audioMasterSetIcon"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterCanDo, "audioMasterCanDo"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterGetLanguage, "audioMasterGetLanguage"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterOpenWindow, "audioMasterOpenWindow"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterCloseWindow, "audioMasterCloseWindow"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterGetDirectory, "audioMasterGetDirectory"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterUpdateDisplay, "audioMasterUpdateDisplay"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterBeginEdit, "audioMasterBeginEdit"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterEndEdit, "audioMasterEndEdit"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterOpenFileSelector, "audioMasterOpenFileSelector"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterCloseFileSelector, "audioMasterCloseFileSelector"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterEditFile, "audioMasterEditFile"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterGetChunkFile, "audioMasterGetChunkFile"));
    masterOpcodes.insert(std::pair<long, std::string>(
        (long) audioMasterGetInputSpeakerArrangement,
        "audioMasterGetInputSpeakerArrangement"));

    opcodeRefCount++;
}

VSTPlugin::VSTPlugin(CSOUND *csound_)
  : csound(csound_),
  libraryHandle(0),
    aeffect(0),
    hasEditor(false),
    editor(0),
    window(0),
    windowHandle(0),
    pluginIsSynth(true),
    overwrite(false),
    edited(false),
    showParameters(false),
    framesPerSecond(0),
    framesPerBlock(0)
{
    memset(&vstTimeInfo, 0, sizeof(VstTimeInfo));
    initializeOpcodes();
}

VSTPlugin::~VSTPlugin()
{
    Free();
    opcodeRefCount--;
    if (!opcodeRefCount) {
      masterOpcodes.clear();
      dispatchOpcodes.clear();
    }
}

bool VSTPlugin::AddMIDI(int data, int deltaFrames, int detune)
{
    if (!aeffect)
      return false;

    vstMidiEvents.resize(vstMidiEvents.size() + 1);
    VstMidiEvent& vstMidiEvent = vstMidiEvents.back();

    vstMidiEvent.type = kVstMidiType;
    vstMidiEvent.byteSize = 24;
    vstMidiEvent.deltaFrames = deltaFrames;
    vstMidiEvent.flags = 0;
    vstMidiEvent.detune = detune;
    vstMidiEvent.noteLength = 0;
    vstMidiEvent.noteOffset = 0;
    vstMidiEvent.reserved1 = 0;
    vstMidiEvent.reserved2 = 0;
    vstMidiEvent.noteOffVelocity = 0;
    vstMidiEvent.midiData[0] = data & 255;
    if ((data & 240) == 144) {
      if (!(data & (int) 0x7F0000)) {
        vstMidiEvent.midiData[0] -= 16;
        data |= (int) 0x400000;
      }
    }
    vstMidiEvent.midiData[1] = (data >> 8) & 127;
    vstMidiEvent.midiData[2] = (data >> 16) & 127;
    vstMidiEvent.midiData[3] = 0;
    return true;
}

void VSTPlugin::SendMidi()
{
    if (aeffect && vstMidiEvents.size() > 0) {
      vstEventsBuffer.resize(sizeof(VstEvents) +
                             (sizeof(VstEvent *) * vstMidiEvents.size()));
      VstEvents *vstEvents = (VstEvents *) &vstEventsBuffer.front();

      vstEvents->numEvents = vstMidiEvents.size();
      vstEvents->reserved = 0;
      for (size_t i = 0, n = vstEvents->numEvents; i < n; i++) {
        vstEvents->events[i] = (VstEvent *) &vstMidiEvents[i];
        Debug("VSTPlugin::SendMidi(queue size %d status %d data1 %d "
              "data2 %d detune %d delta %d\n",
              vstEvents->numEvents,
              ((VstMidiEvent *)vstEvents->events[i])->midiData[0],
              ((VstMidiEvent *)vstEvents->events[i])->midiData[1],
              ((VstMidiEvent *)vstEvents->events[i])->midiData[2],
              ((VstMidiEvent *)vstEvents->events[i])->detune,
              ((VstMidiEvent *)vstEvents->events[i])->deltaFrames);
      }
      Dispatch(effProcessEvents, 0, 0, vstEvents, 0.0f);
      vstMidiEvents.resize(0);
    }
}

bool VSTPlugin::DescribeValue(int parameter, char *value)
{
    Debug("VSTPlugin::DescribeValue.\n");
    if (aeffect) {
      if (parameter < aeffect->numParams) {
        char par_display[0x100];
        char par_label[0x100];
        Dispatch(effGetParamDisplay,parameter,0,par_display,0.0f);
        Dispatch(effGetParamLabel,parameter,0,par_label,0.0f);
        strcpy(value, par_display);
        return true;
      }
    }
    return false;
}

int VSTPlugin::Instantiate(const char *libraryName_)
{
    Debug("VSTPlugin::Instance.\n");
#ifdef __MACH__
    CFStringRef vstBundlePath =
      CFStringCreateWithCString(kCFAllocatorDefault,
                                libraryName_, kCFStringEncodingMacRoman );
    CFURLRef vstBundleURL =
      CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
                                    vstBundlePath,
                                    kCFURLPOSIXPathStyle,
                                    true);
    CFBundleRef vstBundle = CFBundleCreate(kCFAllocatorDefault, vstBundleURL);

    CFRelease(vstBundlePath);
    CFRelease(vstBundleURL);

    if (vstBundle == NULL)
#else
      if (csound->OpenLibrary(&libraryHandle, libraryName_) != 0)
#endif
        {
          Log("WARNING! '%s' was not found or is invalid.\n", libraryName_);
          return VSTINSTANCE_ERR_NO_VALID_FILE;
        }
    Debug("Loaded plugin library '%s'.\n", libraryName_);

#ifdef __MACH__
    short bundleRes = CFBundleOpenBundleResourceMap(vstBundle);
      /* For VST SDK 2.4 and later. */
    PVSTMAIN main =
      (PVSTMAIN) CFBundleGetFunctionPointerForName(vstBundle,
                                                   CFSTR("VSTPluginMain"));
      /* For VST SDK 2.3 and earlier. */
    if (!main) {
      main = CFBundleGetFunctionPointerForName(vstBundle, CFSTR("main_macho"));
    }
#else
    /* For VST SDK 2.4 and later. */
    PVSTMAIN main = (PVSTMAIN) csound->GetLibrarySymbol(libraryHandle, "VSTPluginMain");
    if (!main) {
      /* For VST SDK 2.3 and earlier. */
      main = (PVSTMAIN) csound->GetLibrarySymbol(libraryHandle, "main");
    }
#endif
    if (!main) {
      Log("Failed to find 'main' function.\n");
      csound->CloseLibrary(libraryHandle);
      aeffect = NULL;
      return VSTINSTANCE_ERR_NO_VST_PLUGIN;
    }
    Debug("Found 'main' function at 0x%x.\n", main);
    aeffect = main((audioMasterCallback) VSTPlugin::Master);
    aeffect->user = this;
    if (!aeffect) {
      Log("VST plugin: unable to create effect.\n");
      csound->CloseLibrary(libraryHandle);
      return VSTINSTANCE_ERR_REJECTED;
    }
    Debug("Created effect '%x'.\n", aeffect);
    if (aeffect->magic != kEffectMagic) {
      Log("VST plugin: Instance query rejected by 0x%x\n", aeffect);
      csound->CloseLibrary(libraryHandle);
      aeffect = NULL;
      return VSTINSTANCE_ERR_REJECTED;
    }
    if (!Dispatch(effGetProductString, 0, 0, &productName, 0.0f)) {
      strcpy(productName, libraryName);
    }
    return VSTINSTANCE_NO_ERROR;
}

void VSTPlugin::Info()
{
    int i =0;
    Log("====================================================\n");
    Log("Loaded plugin: %s\n", productName);
    if (!aeffect->dispatcher(aeffect,
                             effGetVendorString, 0, 0, &vendorName, 0.0f)) {
      strcpy(vendorName, "Unknown vendor");
    }
    Log("Vendor name: %s \n", vendorName);
    pluginVersion = aeffect->version;
    Log("Version: %d \n", pluginVersion);
    pluginIsSynth = (aeffect->flags & effFlagsIsSynth)?true:false;
    Log("Is synthesizer? %s\n",(pluginIsSynth==true?"Yes":"No"));
    overwrite = (aeffect->flags & effFlagsCanReplacing)?true:false;
    hasEditor = (aeffect->flags & effFlagsHasEditor)?true:false;
    Log("Number of inputs: %i\n", getNumInputs());
    Log("Number of outputs: %i\n", getNumOutputs());
    long nparams=NumParameters();
    Log("Number of parameters: %d\n",nparams);
    char buffer[256];
    for (i = 0; i < nparams; i++) {
      strcpy(buffer, "No parameter");
      GetParamName(i, buffer);
      if (strcmp("unused",buffer)==1)
        Log("  Parameter%5i: %s\n",i, buffer);
    }
    csound->Message(csound, "Number of programs: %d\n",
                    (int) aeffect->numPrograms);
    for (i = 0; i < aeffect->numPrograms; i++) {
      strcpy(buffer, "No program");
      GetProgramName(0, i, buffer);
      if (strcmp("default",buffer)==1)
        Log("  Program%7i: %s\n", i, buffer);
    }
    csound->Message(csound,
                    "----------------------------------------------------\n");
}

int VSTPlugin::getNumInputs(void)
{
    Debug("VSTPlugin::getNumInputs.\n");
    return aeffect->numInputs;
}

int VSTPlugin::getNumOutputs(void)
{
    Debug("VSTPlugin::getNumOutputs.\n");
    return aeffect->numOutputs;
}

void VSTPlugin::Free() // Called also in destruction
{
    Debug("VSTPlugin::Free.\n");
    CloseEditor();
    if (aeffect) {
      Dispatch(effMainsChanged, 0, 0, NULL, 0.0f);
      Dispatch(effClose,        0, 0, NULL, 0.0f);
      aeffect->user = 0;
      aeffect = 0;
#ifndef __MACH__
      csound->CloseLibrary(libraryHandle);
#endif
      libraryHandle = 0;
    }
}

void VSTPlugin::Init()
{
    size_t i;
    Debug("VSTPlugin::Init.\n");
    framesPerSecond = (size_t) ((long) (csound->esr + FL(0.5)));
    framesPerBlock = csound->ksmps;
    Log("VSTPlugin::Init framesPerSecond %d framesPerBlock %d "
        "channels %d in / %d out.\n",
        framesPerSecond, framesPerBlock, getNumInputs(), getNumOutputs());
    inputs_.resize((size_t) getNumInputs());
    outputs_.resize((size_t) getNumOutputs());
    for (i = 0; i < inputs_.size(); i++) {
      inputs_[i].resize(framesPerBlock);
      inputs.push_back(&inputs_[i].front());
    }
    for (i = 0; i < outputs_.size(); i++) {
      outputs_[i].resize(framesPerBlock);
      outputs.push_back(&outputs_[i].front());
    }
    Dispatch(effOpen        ,  0, 0, NULL, 0.0f);
    Dispatch(effSetProgram  ,  0, 0, NULL, 0.0f);
    Dispatch(effMainsChanged,  0, 1, NULL, 0.0f);
    Dispatch(effSetSampleRate, 0, 0, 0, (float) framesPerSecond );
    Dispatch(effSetBlockSize,  0, framesPerBlock, NULL, 0.0f );
}

bool VSTPlugin::SetParameter(int parameter, float value)
{
    Debug("VSTPlugin::SetParameter(%d, %f).\n", parameter, value);
    if (aeffect) {
      if ((parameter >= 0) && (parameter <= aeffect->numParams)) {
        aeffect->setParameter(aeffect, parameter, value);
        return true;
      }
      else return false;
    }
    return false;
}

bool VSTPlugin::SetParameter(int parameter, int value)
{
    Debug("VSTPlugin::SetParameter(%d, %d).\n", parameter, value);
    return SetParameter(parameter,value/65535.0f);
}

int VSTPlugin::GetCurrentProgram()
{
    Debug("VSTPlugin::GetCurrentProgram.\n");
    if (aeffect)
      return Dispatch(effGetProgram, 0, 0, NULL, 0.0f);
    else
      return 0;
}

void VSTPlugin::SetCurrentProgram(int prg)
{
    Debug("VSTPlugin::SetCurrentProgram((%d).\n", prg);
    if (aeffect)
      Dispatch(effSetProgram, 0, prg, NULL, 0.0f);
}

bool VSTPlugin::replace()
{
    return overwrite;
}

void VSTPlugin::EditorIdle()
{
    Dispatch(effEditIdle, 0, 0, windowHandle, 0.0f);
}

ERect VSTPlugin::GetEditorRect()
{
    ERect *rect_ = 0;
    Dispatch(effEditGetRect,0,0, &rect_,0.0f);
    if (rect_)
      rect = *rect_;
    else {
      rect.right = 600;
      rect.bottom = 400;
    }
    return rect;
}

void VSTPlugin::OpenEditor()
{
    if (windowHandle)
      return;
    if (aeffect->flags & effFlagsHasEditor == 1) {
      GetEditorRect();
      Debug("ERect top %d left %d right %d bottom %d.\n", rect.top, rect.left,
            rect.right, rect.bottom);
      window = new Fl_Window(rect.right, rect.bottom, GetName());
      Debug("Window 0x%x.\n", window);
      window->show();
#ifdef WIN32
      windowHandle = fl_xid(window);
      Debug("windowHandle 0x%x.\n", windowHandle);
      SetEditWindow(windowHandle);
#elif defined (LINUX)
      //TODO: Fill appropriate code here
//       windowHandle = (void *) fl_find(fl_xid(ST(fl_windows)[panelNum].panel));
      Log("vstedit not implemented on Linux yet.\n");
#elif defined (MACOSX)
      //TODO: Fill appropriate code here
      Log("vstedit not implemented on Mac yet.\n");
#endif
    }
    else
      Log("Plugin:%s has no GUI.\n", productName);
}

void VSTPlugin::CloseEditor()
{
    if (!windowHandle)
      return;
    OnEditorClose();
    if (aeffect->flags & effFlagsHasEditor == 1) {
      OnEditorClose();
      //window->hide();
      //delete window;
      //window = 0;
      windowHandle = 0;
    }
}

void VSTPlugin::SetEditWindow(void *h)
{
    windowHandle = h;
    Dispatch(effEditOpen,0,0, windowHandle,0.0f);
}

void VSTPlugin::OnEditorClose()
{
    Dispatch(effEditClose,0,0, windowHandle,0.0f);
}

void VSTPlugin::SetShowParameters(bool s)
{
    showParameters = s;
}

bool VSTPlugin::ShowParams()
{
    return showParameters;
}

bool VSTPlugin::GetProgramName(int cat, int parameter, char *buf)
{
    if (aeffect) {
      if (parameter < NumPrograms()) {
        Dispatch(effGetProgramNameIndexed, parameter, cat, buf, 0.0f);
        return true;
      }
    }
    return false;
}

int VSTPlugin::GetNumCategories()
{
    if (aeffect)
      return Dispatch(effGetNumProgramCategories, 0, 0, NULL, 0.0f);
    else
      return 0;
}

void VSTPlugin::StopEditing()
{
    edited = false;
}

void VSTPlugin::Log(const char *format, ...)
{
    va_list args;

    va_start(args, format);
    if (csound) {
      csound->MessageV(csound, 0, format, args);
    }
    else {
      vfprintf(stdout, format, args);
    }
    va_end(args);
}

void VSTPlugin::Debug(const char *format, ...)
{
    va_list args;

    va_start(args, format);
    if (csound) {
      if ((csound->GetMessageLevel(csound) & 7) == 7 ||
          csound->GetDebug(csound)) {
        csound->MessageV(csound, 0, format, args);
      }
    }
    else {
      vfprintf(stdout, format, args);
    }
    va_end(args);
}

long VSTPlugin::OnGetVersion(AEffect *effect)
{
#if defined(VST_2_3_EXTENSIONS)
    return 2300L;
#elif defined(VST_2_2_EXTENSIONS)
    return 2200L;
#elif defined(VST_2_1_EXTENSIONS)
    return 2100L;
#else
    return 2L;
#endif
}

int VSTPlugin::GetNumParams(void)
{
    return aeffect->numParams;
}

void VSTPlugin::GetParamName(int numparam, char *name)
{
    if (numparam < aeffect->numParams)
      Dispatch(effGetParamName, numparam, 0, name, 0.0f);
    else
      strcpy(name, "Parameter out of range.");
}

float VSTPlugin::GetParamValue(int numparam)
{
    if (numparam < aeffect->numParams)
      return (aeffect->getParameter(aeffect, numparam));
    else
      return -1.0;
}

char* VSTPlugin::GetName(void)
{
    return productName;
}

unsigned long VSTPlugin::GetVersion(void)
{
    return pluginVersion;
}

char* VSTPlugin::GetVendorName(void)
{
    return vendorName;
}

char* VSTPlugin::GetDllName(void)
{
    return libraryName;
}

long VSTPlugin::NumParameters(void)
{
    return aeffect->numParams;
}

float VSTPlugin::GetParameter(long parameter)
{
    return aeffect->getParameter(aeffect, parameter);
}

int VSTPlugin::NumPrograms(void)
{
    return aeffect->numPrograms;
}

VstTimeInfo *VSTPlugin::GetTime(void)
{
    Debug("VSGPlugin::GetTime().\n");
    if (csound)
      vstTimeInfo.samplePos = csound->icurTime;
    else
      vstTimeInfo.samplePos = 0;
    vstTimeInfo.sampleRate = framesPerSecond;
    Debug("&vstTimeInfo 0x%x sampleRate %f samplePos %f.\n",
          &vstTimeInfo, vstTimeInfo.sampleRate, vstTimeInfo.samplePos);
    return &vstTimeInfo;
}

bool VSTPlugin::IsSynth()
{
    return pluginIsSynth;
}

bool VSTPlugin::OnCanDo(const char *ptr)
{
    // printf("Can do call: %s.\n", ptr);
    if ((!strcmp(ptr, "sendVstMidiEvent")) ||
        (!strcmp(ptr, "receiveVstMidiEvent")) ||
        (!strcmp(ptr, "sendVstEvents")) ||
        (!strcmp(ptr, "receiveVstEvents")) ||
        (!strcmp(ptr, "sendVstTimeInfo")) /*||
        (!strcmp(ptr, "sizeWindow"))*/)
      return true;
    return false;
}

bool VSTPlugin::OnInputConnected(AEffect *effect, long input)
{
    return true;
}

bool VSTPlugin::OnOutputConnected(AEffect *effect, long output)
{
    return true;
}

long VSTPlugin::Master(AEffect *effect, long opcode, long index,
                       long value, void *ptr, float opt)
{
    VSTPlugin *plugin = 0;
    CSOUND *csound = 0;
    if (effect) {
      plugin = (VSTPlugin *) effect->user;
      if (plugin) {
        csound = plugin->csound;
      }
    }
    std::string opcodeName;
    if (masterOpcodes.find(opcode) != masterOpcodes.end()) {
      opcodeName = masterOpcodes[opcode];
    }
    // These messages are to tell Csound what the plugin wants it to do.
    if (plugin) {
      plugin->Debug("VSTPlugin::Master(AEffect 0x%p, opcode %ld %s, index %ld, "
                    "value %dl, ptr 0x%p, opt %f)\n",
                    effect, opcode, opcodeName.c_str(), index, value, ptr, opt);
    }
    else {
      fprintf(stdout, "VSTPlugin::Master(AEffect 0x%p, opcode %ld %s, index %ld, "
              "value %ld, ptr 0x%p, opt %f)\n",
              effect, opcode, opcodeName.c_str(), index, value, ptr, opt);
    }
    switch (opcode) {
    case audioMasterAutomate:
      return true;
    case audioMasterVersion:
      return OnGetVersion(effect);
    case audioMasterCurrentId:
      if (effect)
        return effect->uniqueID;
      else
        return -1;
    case audioMasterIdle:
      if (plugin) {
        plugin->Dispatch(effEditIdle, 0, 0, NULL, 0.0f);
      }
      return 0;
    case audioMasterPinConnected:
      return !((value) ?  OnOutputConnected(effect, index) :
               OnInputConnected(effect, index));
    case audioMasterWantMidi:
      return false;
    case audioMasterProcessEvents:
      return false;
    case audioMasterGetTime:
      if (plugin)
        return (long) plugin->GetTime();
      else {
        //static VstTimeInfo vstTimeInfo;
        //memset(&vstTimeInfo, 0, sizeof(VstTimeInfo));
        //return (long) &vstTimeInfo;
      }
      return 0;
    case audioMasterTempoAt:
      return 0;
    case audioMasterNeedIdle:
      if (plugin)
        return plugin->Dispatch(effIdle, 0, 0, NULL, 0.0f);
      return false;
    case audioMasterGetSampleRate:
      if (plugin)
        return plugin->framesPerSecond;
      else
        return 44100;
    case audioMasterGetVendorString:
      strcpy((char *)ptr, "vst4cs");
      return 0;
    case audioMasterGetVendorVersion:
      return 5000;
    case audioMasterGetProductString:
      strcpy((char*)ptr,"vst4cs");
      return 0;
    case audioMasterGetLanguage:
      return kVstLangEnglish;
    case audioMasterUpdateDisplay:
      if (plugin) {
        plugin->Dispatch(effEditIdle, 0, 0, NULL, 0.0f);
        //return 0;
      }
      else
        return 1;
    case audioMasterGetNextPlug:
      return 1;
    case audioMasterWillReplaceOrAccumulate:
      return 1;
    case audioMasterGetCurrentProcessLevel:
      return 0;
    case audioMasterCanDo:
      //if(plugin)
      return OnCanDo((char *)ptr);
      //else printf("No instance");
    default:
      break;
    }
    return 0;
}


Generated by  Doxygen 1.6.0   Back to index