summaryrefslogtreecommitdiff
path: root/muse_qt4_evolution/muse/vst.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'muse_qt4_evolution/muse/vst.cpp')
-rw-r--r--muse_qt4_evolution/muse/vst.cpp1063
1 files changed, 1063 insertions, 0 deletions
diff --git a/muse_qt4_evolution/muse/vst.cpp b/muse_qt4_evolution/muse/vst.cpp
new file mode 100644
index 00000000..f91d1322
--- /dev/null
+++ b/muse_qt4_evolution/muse/vst.cpp
@@ -0,0 +1,1063 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+// This code is based on jack_fst:
+// Copyright (C) 2004 Paul Davis <paul@linuxaudiosystems.com>
+// Torben Hohn <torbenh@informatik.uni-bremen.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "config.h"
+
+#ifdef VST_SUPPORT
+
+#include "al/al.h"
+#include <fst.h>
+#include <vst/aeffectx.h>
+#include <jack/jack.h>
+
+#include "vst.h"
+#include "globals.h"
+#include "synth.h"
+#include "jackaudio.h"
+#include "midi.h"
+#include "al/xml.h"
+#include "song.h"
+#include "audio.h"
+#include "widgets/utils.h"
+
+extern "C" void fst_error(const char *fmt, ...);
+extern JackAudio* jackAudio;
+
+//---------------------------------------------------------
+// jfstReserveMem
+//---------------------------------------------------------
+
+static void jfstReserveMem(int size)
+ {
+ char buf[size];
+
+ for (int i = 0; i < size; ++i)
+ buf[i] = (char)(i % 256);
+ }
+
+//---------------------------------------------------------
+// vstHostCallback
+//---------------------------------------------------------
+
+static long vstHostCallback(AEffect* effect,
+ long opcode, long index, long value, void* ptr, float opt)
+ {
+ static VstTimeInfo _timeInfo;
+
+ VstPluginIF* pluginIF = effect ? (VstPluginIF*) effect->user : 0;
+
+ jack_position_t jack_pos;
+ jack_transport_state_t tstate;
+
+ switch (opcode) {
+ case audioMasterAutomate:
+ // index, value, returns 0
+ if (pluginIF) {
+ PluginI* pi = pluginIF->pluginInstance();
+ // pi->setParam(index, opt);
+ CVal cval;
+ cval.f = opt;
+ song->setControllerVal(pi->track(), pi->controller(index), cval);
+ }
+ return 0;
+
+ case audioMasterVersion:
+ // vst version, currently 2 (0 for older)
+ return 2200;
+
+ case audioMasterCurrentId:
+ // returns the unique id of a plug that's currently
+ // loading
+ return 0;
+
+ case audioMasterIdle:
+ // call application idle routine (this will
+ // call effEditIdle for all open editors too)
+ effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f);
+ return 0;
+
+ case audioMasterPinConnected:
+ // inquire if an input or output is beeing connected;
+ // index enumerates input or output counting from zero:
+ // value is 0 for input and != 0 otherwise. note: the
+ // return value is 0 for <true> such that older versions
+ // will always return true.
+ return 1;
+
+ case audioMasterWantMidi:
+ // <value> is a filter which is currently ignored
+ return 0;
+
+ case audioMasterGetTime:
+ // returns const VstTimeInfo* (or 0 if not supported)
+ // <value> should contain a mask indicating which fields are required
+ // (see valid masks above), as some items may require extensive
+ // conversions
+
+ memset(&_timeInfo, 0, sizeof(_timeInfo));
+
+ if (effect) {
+ tstate = jackAudio->transportQuery(&jack_pos);
+
+ _timeInfo.samplePos = jack_pos.frame;
+ _timeInfo.sampleRate = jack_pos.frame_rate;
+ _timeInfo.flags = 0;
+
+ if ((value & (kVstBarsValid|kVstTempoValid)) && (jack_pos.valid & JackPositionBBT)) {
+ _timeInfo.tempo = jack_pos.beats_per_minute;
+ _timeInfo.timeSigNumerator = (long) floor (jack_pos.beats_per_bar);
+ _timeInfo.timeSigDenominator = (long) floor (jack_pos.beat_type);
+ _timeInfo.flags |= (kVstBarsValid|kVstTempoValid);
+ }
+ if (tstate == JackTransportRolling) {
+ _timeInfo.flags |= kVstTransportPlaying;
+ }
+ }
+ else {
+ _timeInfo.samplePos = 0;
+ _timeInfo.sampleRate = AL::sampleRate;
+ }
+ return (long)&_timeInfo;
+
+ case audioMasterProcessEvents:
+ // VstEvents* in <ptr>
+ return 0;
+
+ case audioMasterSetTime:
+ // VstTimenfo* in <ptr>, filter in <value>, not supported
+
+ case audioMasterTempoAt:
+ // returns tempo (in bpm * 10000) at sample frame location passed in <value>
+ return 0;
+
+ case audioMasterGetNumAutomatableParameters:
+ return 0;
+
+ case audioMasterGetParameterQuantization:
+ // returns the integer value for +1.0 representation,
+ // or 1 if full single float precision is maintained
+ // in automation. parameter index in <value> (-1: all, any)
+ return 0;
+
+ case audioMasterIOChanged:
+ // numInputs and/or numOutputs has changed
+ return 0;
+
+ case audioMasterNeedIdle:
+ // plug needs idle calls (outside its editor window)
+ return 0;
+
+ case audioMasterSizeWindow:
+ // index: width, value: height
+ return 0;
+
+ case audioMasterGetSampleRate:
+ return 0;
+
+ case audioMasterGetBlockSize:
+ return 0;
+
+ case audioMasterGetInputLatency:
+ return 0;
+
+ case audioMasterGetOutputLatency:
+ return 0;
+
+ case audioMasterGetPreviousPlug:
+ // input pin in <value> (-1: first to come), returns cEffect*
+ return 0;
+
+ case audioMasterGetNextPlug:
+ // output pin in <value> (-1: first to come), returns cEffect*
+
+ case audioMasterWillReplaceOrAccumulate:
+ // returns: 0: not supported, 1: replace, 2: accumulate
+ return 0;
+
+ case audioMasterGetCurrentProcessLevel:
+ // returns: 0: not supported,
+ // 1: currently in user thread (gui)
+ // 2: currently in audio thread (where process is called)
+ // 3: currently in 'sequencer' thread (midi, timer etc)
+ // 4: currently offline processing and thus in user thread
+ // other: not defined, but probably pre-empting user thread.
+ return 0;
+
+ case audioMasterGetAutomationState:
+ // returns 0: not supported, 1: off, 2:read, 3:write, 4:read/write
+ // offline
+ return 0;
+
+ case audioMasterOfflineStart:
+ case audioMasterOfflineRead:
+ // ptr points to offline structure, see below. return 0: error, 1 ok
+ return 0;
+
+ case audioMasterOfflineWrite:
+ // same as read
+ return 0;
+
+ case audioMasterOfflineGetCurrentPass:
+ case audioMasterOfflineGetCurrentMetaPass:
+ return 0;
+
+ case audioMasterSetOutputSampleRate:
+ // for variable i/o, sample rate in <opt>
+ return 0;
+
+ case audioMasterGetSpeakerArrangement:
+ // (long)input in <value>, output in <ptr>
+ return 0;
+
+ case audioMasterGetVendorString:
+ // fills <ptr> with a string identifying the vendor (max 64 char)
+ strcpy ((char*) ptr, "LAD");
+ return 0;
+
+ case audioMasterGetProductString:
+ // fills <ptr> with a string with product name (max 64 char)
+ strcpy ((char*) ptr, "FreeST");
+
+ case audioMasterGetVendorVersion:
+ // returns vendor-specific version
+ return 1000;
+
+ case audioMasterVendorSpecific:
+ // no definition, vendor specific handling
+ return 0;
+
+ case audioMasterSetIcon:
+ // void* in <ptr>, format not defined yet
+ return 0;
+
+ case audioMasterCanDo:
+ // string in ptr, see below
+ return 0;
+
+ case audioMasterGetLanguage:
+ // see enum
+ return 0;
+
+ case audioMasterOpenWindow:
+ // returns platform specific ptr
+ return 0;
+
+ case audioMasterCloseWindow:
+ // close window, platform specific handle in <ptr>
+ return 0;
+
+ case audioMasterGetDirectory:
+ // get plug directory, FSSpec on MAC, else char*
+ return 0;
+
+ case audioMasterUpdateDisplay:
+ // something has changed, update 'multi-fx' display
+ effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f);
+ return 0;
+
+ case audioMasterBeginEdit:
+ // begin of automation session (when mouse down), parameter index in <index>
+ return 0;
+
+ case audioMasterEndEdit:
+ // end of automation session (when mouse up), parameter index in <index>
+ return 0;
+
+ case audioMasterOpenFileSelector:
+ // open a fileselector window with VstFileSelect* in <ptr>
+ return 0;
+
+ default:
+ break;
+ }
+ return 0;
+ }
+
+
+//---------------------------------------------------------
+// FstPlugin
+//---------------------------------------------------------
+
+FstPlugin::FstPlugin()
+ {
+ _fst = 0;
+ }
+
+//---------------------------------------------------------
+// ~FstPlugin
+//---------------------------------------------------------
+
+FstPlugin::~FstPlugin()
+ {
+ if (_fst) {
+ destroyEditor();
+ fst_close(_fst);
+ _fst = 0;
+ }
+ }
+
+//---------------------------------------------------------
+// instantiate
+//---------------------------------------------------------
+
+void FstPlugin::instantiate(FSTHandle* fstHandle, void* p)
+ {
+ _fst = fst_instantiate(fstHandle, vstHostCallback, p);
+ if (_fst == 0) {
+ printf("FstPlugin::instantiate:: cannot instantiate plugin\n");
+ return;
+ }
+ AEffect* plugin = _fst->plugin;
+ version = plugin->dispatcher (plugin, effGetVstVersion, 0, 0, 0, 0.0f);
+ }
+
+//---------------------------------------------------------
+// numInputs
+//---------------------------------------------------------
+
+int FstPlugin::numInputs() const
+ {
+ return _fst->plugin->numInputs;
+ }
+
+//---------------------------------------------------------
+// numOutputs
+//---------------------------------------------------------
+
+int FstPlugin::numOutputs() const
+ {
+ return _fst->plugin->numOutputs;
+ }
+
+//---------------------------------------------------------
+// numParameter
+//---------------------------------------------------------
+
+int FstPlugin::numParameter() const
+ {
+ return _fst->plugin->numParams;
+ }
+
+//---------------------------------------------------------
+// setSampleRate
+//---------------------------------------------------------
+
+void FstPlugin::setSampleRate(float sr)
+ {
+ AEffect* plugin = _fst->plugin;
+ plugin->dispatcher(plugin, effSetSampleRate, 0, 0, 0, sr);
+ }
+
+//---------------------------------------------------------
+// setBlockSize
+//---------------------------------------------------------
+
+void FstPlugin::setBlockSize(int bs)
+ {
+ AEffect* plugin = _fst->plugin;
+ plugin->dispatcher(plugin, effSetBlockSize, 0, bs, 0, 0.0f);
+ }
+
+//---------------------------------------------------------
+// mainsChanged
+//---------------------------------------------------------
+
+void FstPlugin::mainsChanged(bool on)
+ {
+ AEffect* plugin = _fst->plugin;
+ plugin->dispatcher(plugin, effMainsChanged, 0, on, 0, 0.0f);
+ }
+
+//---------------------------------------------------------
+// setProgram
+//---------------------------------------------------------
+
+void FstPlugin::setProgram(int p)
+ {
+ AEffect* plugin = _fst->plugin;
+ plugin->dispatcher(plugin, effSetProgram, 0, p, 0, 0.0f);
+ }
+
+//---------------------------------------------------------
+// hasGui
+//---------------------------------------------------------
+
+bool FstPlugin::hasGui() const
+ {
+ return _fst->plugin->flags & effFlagsHasEditor;
+ }
+
+//---------------------------------------------------------
+// canReplacing
+//---------------------------------------------------------
+
+bool FstPlugin::canReplacing()
+ {
+ return _fst->plugin->flags & effFlagsCanReplacing;
+ }
+
+//---------------------------------------------------------
+// runEditor
+//---------------------------------------------------------
+
+bool FstPlugin::runEditor()
+ {
+ return fst_run_editor(_fst);
+ }
+
+//---------------------------------------------------------
+// destroyEditor
+//---------------------------------------------------------
+
+void FstPlugin::destroyEditor()
+ {
+ fst_destroy_editor(_fst);
+ }
+
+//---------------------------------------------------------
+// getVstVersion
+//---------------------------------------------------------
+
+int FstPlugin::getVstVersion()
+ {
+ return version;
+ }
+
+//---------------------------------------------------------
+// setParameter
+//---------------------------------------------------------
+
+void FstPlugin::setParameter(int idx, float value)
+ {
+ AEffect* plugin = _fst->plugin;
+ plugin->setParameter(plugin, idx, value);
+ }
+
+//---------------------------------------------------------
+// getParameter
+//---------------------------------------------------------
+
+float FstPlugin::getParameter(int idx)
+ {
+ AEffect* plugin = _fst->plugin;
+ return plugin->getParameter(plugin, idx);
+ }
+
+//---------------------------------------------------------
+// processReplacing
+//---------------------------------------------------------
+
+void FstPlugin::processReplacing(float** ins, float** outs, int n)
+ {
+ AEffect* plugin = _fst->plugin;
+ plugin->processReplacing(plugin, ins, outs, n);
+ }
+
+//---------------------------------------------------------
+// process
+//---------------------------------------------------------
+
+void FstPlugin::process(float** ins, float** outs, int n)
+ {
+ AEffect* plugin = _fst->plugin;
+ plugin->process(plugin, ins, outs, n);
+ }
+
+//---------------------------------------------------------
+// putEvent
+//---------------------------------------------------------
+
+void FstPlugin::putEvent(const MidiEvent& ev)
+ {
+ AEffect* plugin = _fst->plugin;
+ static struct VstEvents events;
+ static struct VstMidiEvent event;
+ events.numEvents = 1;
+ events.reserved = 0;
+ events.events[0] = (VstEvent*)(&event);
+
+ event.type = kVstMidiType;
+ event.byteSize = 24;
+ event.deltaFrames = 0;
+ event.flags = 0;
+ event.detune = 0;
+ event.noteLength = 0;
+ event.noteOffset = 0;
+ event.reserved1 = 0;
+ event.reserved2 = 0;
+ event.noteOffVelocity = 0;
+ switch (ev.type()) {
+ case ME_PITCHBEND:
+ {
+ int a = ev.dataA() + 8192;
+ int b = a >> 7;
+ event.midiData[0] = (ev.type() | ev.channel()) & 0xff;
+ event.midiData[1] = a & 0x7f;
+ event.midiData[2] = b & 0x7f;
+ event.midiData[3] = 0;
+ }
+ break;
+
+ case ME_CONTROLLER:
+ case ME_NOTEON:
+ default:
+ event.midiData[0] = (ev.type() | ev.channel()) & 0xff;
+ event.midiData[1] = ev.dataA() & 0xff;
+ event.midiData[2] = ev.dataB() & 0xff;
+ event.midiData[3] = 0;
+ break;
+ }
+ plugin->dispatcher(plugin, effProcessEvents, 0, 0, &events, 0.0f);
+ }
+
+//---------------------------------------------------------
+// getParameterName
+//---------------------------------------------------------
+
+const char* FstPlugin::getParameterName(int idx) const
+ {
+ static char dsp[8];
+ dsp[0] = 0;
+ AEffect* effect = _fst->plugin;
+ effect->dispatcher(effect, effGetParamName, idx, 0, &dsp, 0.0f);
+ return dsp;
+ }
+
+//---------------------------------------------------------
+// getParameterLabel
+//---------------------------------------------------------
+
+const char* FstPlugin::getParameterLabel(int idx) const
+ {
+ static char dsp[8];
+ dsp[0] = 0;
+ AEffect* effect = _fst->plugin;
+ effect->dispatcher(effect, effGetParamLabel, idx, 0, &dsp, 0.0f);
+ return dsp;
+ }
+
+//---------------------------------------------------------
+// getParameterDisplay
+//---------------------------------------------------------
+
+const char* FstPlugin::getParameterDisplay(int idx, float val) const
+ {
+ static char dsp[8];
+ dsp[0] = 0;
+ AEffect* effect = _fst->plugin;
+ effect->dispatcher(effect, effGetParamDisplay, idx, 0, &dsp, val);
+ return dsp;
+ }
+
+//---------------------------------------------------------
+// scanVstDir
+//---------------------------------------------------------
+
+static void scanVstDir(const QString& s)
+ {
+ if (debugMsg)
+ printf("scan vst plugin dir <%s>\n", s.toLatin1().data());
+ QDir pluginDir(s, QString("*.dll"), QDir::Unsorted, QDir::Files);
+ if (pluginDir.exists()) {
+ const QFileInfoList list = pluginDir.entryInfoList();
+ for (int i = 0; i < list.size(); ++i) {
+ QFileInfo fi = list.at(i);
+ char* path = strdup(fi.filePath().toLatin1().data());
+ FSTInfo* info = fst_get_info(path);
+ if (info) {
+ //
+ // simple hack:
+ // plugins with no inputs are treated
+ // as software synthesizer
+ //
+ // if (info->wantEvents && info->numOutputs) {
+ if (info->numInputs == 0 && info->numOutputs) {
+ if (debugMsg)
+ printf(" add vsti synti <%s>\n", fi.fileName().toLatin1().data());
+ synthis.push_back(new VstSynth(&fi));
+ fst_free_info(info);
+ }
+ else if (info->numInputs && info->numOutputs) {
+ if (debugMsg)
+ printf(" add vst plugin <%s>\n", fi.fileName().toLatin1().data());
+ plugins.push_back(new VstPlugin(&fi, info));
+ }
+ }
+ free(path);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// fstSignalHandler
+//---------------------------------------------------------
+
+static void fstSignalHandler(int sig, siginfo_t* /*info*/, void* /*context*/)
+ {
+ fst_error("fst signal handler %d, thread = 0x%x", sig, pthread_self ());
+ //if (sig == SIGSEGV || sig == SIGABRT) {
+ char*p = 0;
+ *p = 0;
+// }
+ fatalError("fst signal");
+ }
+
+//---------------------------------------------------------
+// initVST
+//---------------------------------------------------------
+
+void initVST()
+ {
+ jfstReserveMem(1000000);
+
+ if (fst_init(fstSignalHandler)) {
+ printf("initVST failed\n");
+ return;
+ }
+ char* vstPath = getenv("VST_PATH");
+ if (vstPath == 0)
+ vstPath = "/usr/lib/vst:/usr/local/lib/vst";
+
+ char* p = vstPath;
+ while (*p != '\0') {
+ char* pe = p;
+ while (*pe != ':' && *pe != '\0')
+ pe++;
+
+ int n = pe - p;
+ if (n) {
+ char* buffer = new char[n + 1];
+ strncpy(buffer, p, n);
+ buffer[n] = '\0';
+ scanVstDir(QString(buffer));
+ delete[] buffer;
+ }
+ p = pe;
+ if (*p == ':')
+ p++;
+ }
+ }
+
+//---------------------------------------------------------
+// guiVisible
+//---------------------------------------------------------
+
+bool VstSynthIF::guiVisible() const
+ {
+ return _guiVisible;
+ }
+
+//---------------------------------------------------------
+// showGui
+//---------------------------------------------------------
+
+void VstSynthIF::showGui(bool v)
+ {
+ if (v == guiVisible())
+ return;
+ if (v)
+ _fst->runEditor();
+ else
+ _fst->destroyEditor();
+ _guiVisible = v;
+ }
+
+//---------------------------------------------------------
+// receiveEvent
+//---------------------------------------------------------
+
+MidiEvent VstSynthIF::receiveEvent()
+ {
+ return MidiEvent();
+ }
+
+//---------------------------------------------------------
+// hasGui
+//---------------------------------------------------------
+
+bool VstSynthIF::hasGui() const
+ {
+ return _fst->hasGui();
+ }
+
+//---------------------------------------------------------
+// incInstances
+//---------------------------------------------------------
+
+void VstSynth::incInstances(int val)
+ {
+ _instances += val;
+ if (_instances == 0 && fstHandle) {
+ fst_unload(fstHandle);
+ fstHandle = 0;
+ }
+ }
+
+//---------------------------------------------------------
+// init
+//---------------------------------------------------------
+
+bool VstSynthIF::init(FSTHandle* h)
+ {
+ _fst = new FstPlugin();
+ _fst->instantiate(h, 0);
+ _fst->setSampleRate(AL::sampleRate);
+ _fst->setBlockSize(segmentSize);
+ _fst->mainsChanged(true);
+ _fst->setProgram(0);
+ return true;
+ }
+
+//---------------------------------------------------------
+// channels
+//---------------------------------------------------------
+
+int VstSynthIF::channels() const
+ {
+ return _fst->numOutputs();
+ }
+
+//---------------------------------------------------------
+// createSIF
+//---------------------------------------------------------
+
+SynthIF* VstSynth::createSIF(SynthI* s)
+ {
+ VstSynthIF* sif = new VstSynthIF(s);
+ ++_instances;
+ const char* path = info.filePath().toLatin1().data();
+
+ if (fstHandle == 0) {
+ fstHandle = fst_load(path);
+ if (fstHandle == 0) {
+ printf("SynthIF:: cannot load vst plugin %s\n", path);
+ return 0;
+ }
+ }
+ sif->init(fstHandle);
+ return sif;
+ }
+
+//---------------------------------------------------------
+// deactivate3
+//---------------------------------------------------------
+
+void VstSynthIF::deactivate3()
+ {
+ if (_fst) {
+ delete _fst;
+ _fst = 0;
+ }
+ }
+
+//---------------------------------------------------------
+// ~VstSynthIF
+//---------------------------------------------------------
+
+VstSynthIF::~VstSynthIF()
+ {
+ deactivate3();
+ }
+
+//---------------------------------------------------------
+// setParameter
+//---------------------------------------------------------
+
+void VstSynthIF::setParameter(int idx, float value)
+ {
+ _fst->setParameter(idx, value);
+ }
+
+//---------------------------------------------------------
+// write
+//---------------------------------------------------------
+
+void VstSynthIF::write(Xml& xml) const
+ {
+ //---------------------------------------------
+ // dump current state of synth
+ //---------------------------------------------
+
+ int params = _fst->numParameter();
+ for (int i = 0; i < params; ++i) {
+ float f = _fst->getParameter(i);
+ xml.tag("param", f);
+ }
+ }
+
+//---------------------------------------------------------
+// getData
+//---------------------------------------------------------
+
+void VstSynthIF::getData(MidiEventList* el, unsigned pos, int ports, unsigned n, float** buffer)
+ {
+ unsigned int endPos = pos + n;
+ iMidiEvent i = el->begin();
+ for (; i != el->end(); ++i) {
+ if (i->time() >= endPos)
+ break;
+ putEvent(*i);
+ }
+ el->erase(el->begin(), i);
+
+ int outputs = _fst->numOutputs();
+ if (ports < outputs) {
+ float* ob[outputs];
+ float fp[n * (outputs-ports)]; // dummy output buffer
+ for (int i = 0; i < outputs; ++i) {
+ if (i < ports)
+ ob[i] = buffer[i];
+ else
+ ob[i] = fp + n * (i-ports);
+ }
+ if (_fst->canReplacing())
+ _fst->processReplacing(0, ob, n);
+ else {
+ for (int i = 0; i < outputs; ++i)
+ memset(ob[i], 0, n * sizeof(float));
+ _fst->process(0, ob, n);
+ }
+ }
+ else {
+ if (_fst->canReplacing())
+ _fst->processReplacing(0, buffer, n);
+ else {
+ for (int i = 0; i < outputs; ++i)
+ memset(buffer[i], 0, n * sizeof(float));
+ _fst->process(0, buffer, n);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// putEvent
+//---------------------------------------------------------
+
+bool VstSynthIF::putEvent(const MidiEvent& ev)
+ {
+ if (midiOutputTrace)
+ ev.dump();
+ _fst->putEvent(ev);
+ return false;
+ }
+
+//---------------------------------------------------------
+// VstPlugin
+//---------------------------------------------------------
+
+VstPlugin::VstPlugin(const QFileInfo* fi, FSTInfo* i)
+ : Plugin(fi)
+ {
+ info = i;
+ fstHandle = 0;
+ }
+
+//---------------------------------------------------------
+// VstPlugin
+//---------------------------------------------------------
+
+VstPlugin::~VstPlugin()
+ {
+ fst_free_info(info);
+ }
+
+//---------------------------------------------------------
+// createPIF
+//---------------------------------------------------------
+
+PluginIF* VstPlugin::createPIF(PluginI* pi)
+ {
+ VstPluginIF* pif = new VstPluginIF(pi);
+ ++_instances;
+ const char* path = fi.filePath().toLatin1().data();
+
+ if (fstHandle == 0) {
+ fstHandle = fst_load(path);
+ if (fstHandle == 0) {
+ printf("SynthIF:: cannot load vst plugin %s\n", path);
+ return 0;
+ }
+ }
+ pif->init(fstHandle);
+ return pif;
+ }
+
+//---------------------------------------------------------
+// parameter
+//---------------------------------------------------------
+
+int VstPlugin::parameter() const
+ {
+ return info->numParams;
+ }
+
+//---------------------------------------------------------
+// inports
+//---------------------------------------------------------
+
+int VstPlugin::inports() const
+ {
+ return info->numInputs;
+ }
+
+//---------------------------------------------------------
+// outports
+//---------------------------------------------------------
+
+int VstPlugin::outports() const
+ {
+ return info->numOutputs;
+ }
+
+//---------------------------------------------------------
+// id
+//---------------------------------------------------------
+
+unsigned long VstPlugin::id() const
+ {
+ return info->UniqueID;
+ }
+
+//---------------------------------------------------------
+// VstPluginIF
+//---------------------------------------------------------
+
+VstPluginIF::VstPluginIF(PluginI* pi)
+ : PluginIF(pi)
+ {
+ _fst = 0;
+ _guiVisible = false;
+ }
+
+VstPluginIF::~VstPluginIF()
+ {
+ if (_fst == 0)
+ return;
+ delete _fst;
+ }
+
+//---------------------------------------------------------
+// init
+//---------------------------------------------------------
+
+bool VstPluginIF::init(FSTHandle* h)
+ {
+ _fst = new FstPlugin();
+ _fst->instantiate(h, this);
+ _fst->setSampleRate(AL::sampleRate);
+ _fst->setBlockSize(segmentSize);
+ _fst->mainsChanged(true);
+ _fst->setProgram(0);
+ return true;
+ }
+
+//---------------------------------------------------------
+// hasGui
+//---------------------------------------------------------
+
+bool VstPluginIF::hasGui() const
+ {
+ return _fst->hasGui();
+ }
+
+//---------------------------------------------------------
+// showGui
+//---------------------------------------------------------
+
+void VstPluginIF::showGui(bool v)
+ {
+ if (v == guiVisible())
+ return;
+ if (v)
+ _fst->runEditor();
+ else
+ _fst->destroyEditor();
+ _guiVisible = v;
+ }
+
+//---------------------------------------------------------
+// getParameterName
+//---------------------------------------------------------
+
+const char* VstPluginIF::getParameterName(int idx) const
+ {
+ return _fst->getParameterName(idx);
+ }
+
+//---------------------------------------------------------
+// getParameterLabel
+//---------------------------------------------------------
+
+const char* VstPluginIF::getParameterLabel(int idx) const
+ {
+ return _fst->getParameterLabel(idx);
+ }
+
+//---------------------------------------------------------
+// getParameterDisplay
+//---------------------------------------------------------
+
+const char* VstPluginIF::getParameterDisplay(int idx, float val) const
+ {
+ return _fst->getParameterDisplay(idx, val);
+ }
+
+//---------------------------------------------------------
+// apply
+//---------------------------------------------------------
+
+void VstPluginIF::apply(unsigned nframes, float** src, float** dst)
+ {
+ if (_fst->canReplacing())
+ _fst->processReplacing(src, dst, nframes);
+ else {
+ int n = _fst->numOutputs();
+
+ for (int i = 0; i < n; ++i)
+ memset(dst[i], 0, sizeof(float) * nframes);
+ _fst->process(src, dst, nframes);
+ }
+ }
+
+//---------------------------------------------------------
+// setParam
+//---------------------------------------------------------
+
+void VstPluginIF::setParam(int i, double val)
+ {
+ _fst->setParameter(i, val);
+ }
+
+//---------------------------------------------------------
+// param
+//---------------------------------------------------------
+
+float VstPluginIF::param(int i) const
+ {
+ return _fst->getParameter(i);
+ }
+
+#else
+void initVST() {}
+#endif
+