diff --git a/CMakeLists.txt b/CMakeLists.txt index c3bd5e2..94d7765 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ project(${PROJECT_NAME}) # Project version set(VERSION_MAJOR 1) -set(VERSION_MINOR 1) +set(VERSION_MINOR 2) set(VERSION_PATCH 1) # Set plugin shared library base name diff --git a/README.md b/README.md index 8a3bf14..454403a 100644 --- a/README.md +++ b/README.md @@ -77,9 +77,13 @@ The following list is not complete. It contains only plugins, that have been tes ------------:|:----------:|:-------| AlgoMusic CZynthia | yes | Aly James LAB OB-Xtreme | yes | + Analogic Delay by interrruptor | yes | + Bionic Delay by interrruptor | yes | Blue Cat Audio Oscilloscope Multi | no | doesn't work with wine + Cableguys Kickstart | no | doesn't work with wine + Cableguys Volume Shaper | no | doesn't work with wine Credland Audio BigKick | no | doesn't work with wine - FabFilter Total bundle | yes | haven't tested them all + FabFilter plugins | yes | haven't tested them all Green Oak Software Crystal | yes | Image-Line Harmless | yes | Image-Line Sytrus | yes | @@ -94,7 +98,7 @@ The following list is not complete. It contains only plugins, that have been tes Magnus Choir | yes | Martin Lüders pg8x | yes | Meesha Damatriks | yes | - Odo Synths Double Six | partly | GUI doesn't show, but presets are available and functional + Odo Synths Double Six | partly | GUI issues Peavey Revalver Mark III.V | yes | ReFX Nexus2 | yes | ReFX Vanguard | yes | @@ -104,6 +108,7 @@ The following list is not complete. It contains only plugins, that have been tes Sonic Cat LFX-1310 | yes | Sonic Charge Cyclone | yes | Smartelectronix s(M)exoscope | yes | + Spectrasonics Omnisphere | yes | SQ8L by Siegfried Kullmann | yes | SuperWave P8 | yes | Synapse Audio DUNE 2 | yes | @@ -111,15 +116,7 @@ The following list is not complete. It contains only plugins, that have been tes Tone2 FireBird | yes | Tone2 Nemesis | yes | Tone2 Saurus | yes | - u-he A.C.E. | yes | Linux version is also available - u-he Bazille | yes | Linux version is also available - u-he Diva | yes | Linux version is also available - u-he Hive | yes | Linux version is also available - u-he Presswerk | yes | Linux version is also available - u-he Satin | yes | Linux version is also available - u-he Uhbik | yes | Linux version is also available - u-he Zebra2 | yes | Linux version is also available + u-he plugins | yes | Linux version is also available Variety of Sound plugins | yes | - Voxengo SPAN | yes | - Voxengo SPAN Pro | mostly | inter plugin routing doesn't work (architecture issue) + Voxengo plugins | mostly | inter plugin routing doesn't work (architecture issue) Xfer Serum | no | the GUI doesn't appear (wine issue), but audio works diff --git a/src/common/protocol.h b/src/common/protocol.h index 55505d2..03f22b6 100644 --- a/src/common/protocol.h +++ b/src/common/protocol.h @@ -39,6 +39,7 @@ struct PluginInfo { i32 paramCount; i32 inputCount; i32 outputCount; + i32 initialDelay; i32 uniqueId; i32 version; } __attribute__((packed)); diff --git a/src/host/host.cpp b/src/host/host.cpp index e17aeab..d69273e 100644 --- a/src/host/host.cpp +++ b/src/host/host.cpp @@ -113,7 +113,7 @@ bool Host::initialize(const char* fileName, int portId) TRACE("Initializing VST plugin..."); effect_ = vstMainProc(audioMasterProc); - if(!effect_) { + if(!effect_ || effect_->magic != kEffectMagic) { ERROR("Unable to initialize VST plugin"); controlPort_.disconnect(); callbackPort_.disconnect(); @@ -134,9 +134,17 @@ bool Host::initialize(const char* fileName, int portId) info->paramCount = effect_->numParams; info->inputCount = effect_->numInputs; info->outputCount = effect_->numOutputs; + info->initialDelay = effect_->initialDelay; info->uniqueId = effect_->uniqueID; info->version = effect_->version; + // Workaround for plugins from Waves + char vendorName[kVstMaxVendorStrLen]; + if(effect_->dispatcher(effect_, effGetVendorString, 0, 0, &vendorName, 0.0f)) { + if(strncmp(vendorName, "Waves", kVstMaxVendorStrLen) == 0) + info->flags |= effFlagsHasEditor; + } + controlPort_.sendResponse(); isInitialized_ = true; @@ -315,6 +323,11 @@ bool Host::handleDispatch(DataFrame* frame) case effEndSetProgram: case effStopProcess: case effGetTailSize: + case effSetEditKnobMode: + case __effConnectInputDeprecated: + case __effConnectOutputDeprecated: + case __effKeysRequiredDeprecated: + case __effIdentifyDeprecated: frame->value = effect_->dispatcher(effect_, frame->opcode, frame->index, frame->value, nullptr, frame->opt); break; @@ -425,6 +438,7 @@ bool Host::handleDispatch(DataFrame* frame) case effBeginLoadBank: case effBeginLoadProgram: case effGetEffectName: + case effShellGetNextPlugin: frame->value = effect_->dispatcher(effect_, frame->opcode, frame->index, frame->value, frame->data, frame->opt); break; @@ -464,6 +478,17 @@ bool Host::handleDispatch(DataFrame* frame) chunk_.clear(); break; } + case effSetSpeakerArrangement: { + u8* data = frame->data; + + intptr_t value = reinterpret_cast(data); + void* ptr = data + sizeof(VstSpeakerArrangement); + + frame->value = effect_->dispatcher(effect_, frame->opcode, frame->index, value, + ptr, frame->opt); + + break; } + default: ERROR("Unhandled dispatch event: %s", kDispatchEvents[frame->opcode]); } @@ -549,12 +574,13 @@ intptr_t Host::audioMaster(i32 opcode, i32 index, intptr_t value, void* ptr, flo case audioMasterGetOutputLatency: case audioMasterGetCurrentProcessLevel: case audioMasterGetAutomationState: + case audioMasterCurrentId: callbackPort_.sendRequest(); callbackPort_.waitResponse(); return frame->value; // FIXME Passing the audioMasterUpdateDisplay request to the plugin endpoint leads to - // crash with some plugins. + // crash (or lock in Renoise) with some plugins (u-he TripleCheese). case audioMasterUpdateDisplay: return 1; diff --git a/src/plugin/plugin.cpp b/src/plugin/plugin.cpp index 042d847..c247352 100644 --- a/src/plugin/plugin.cpp +++ b/src/plugin/plugin.cpp @@ -110,6 +110,7 @@ Plugin::Plugin(const std::string& vstPath, const std::string& hostPath, effect_->numParams = info->paramCount; effect_->numInputs = info->inputCount; effect_->numOutputs = info->outputCount; + effect_->initialDelay = info->initialDelay; effect_->uniqueID = info->uniqueId; effect_->version = info->version; @@ -119,6 +120,7 @@ Plugin::Plugin(const std::string& vstPath, const std::string& hostPath, DEBUG(" param count: %d", effect_->numParams); DEBUG(" input count: %d", effect_->numInputs); DEBUG(" output count: %d", effect_->numOutputs); + DEBUG(" initial delay: %d", effect_->initialDelay); DEBUG(" unique ID: 0x%08X", effect_->uniqueID); DEBUG(" version: %d", effect_->version); } @@ -197,6 +199,7 @@ intptr_t Plugin::handleAudioMaster() case audioMasterGetOutputLatency: case audioMasterGetCurrentProcessLevel: case audioMasterGetAutomationState: + case audioMasterCurrentId: return masterProc_(effect_, frame->opcode, frame->index, frame->value, nullptr, frame->opt); @@ -226,7 +229,7 @@ intptr_t Plugin::handleAudioMaster() return masterProc_(effect_, frame->opcode, 0, 0, e, 0.0f); } } - ERROR("Unhandled audio master event: %s", kAudioMasterEvents[frame->opcode]); + ERROR("Unhandled audio master event: %s %d", kAudioMasterEvents[frame->opcode], frame->opcode); return 0; } @@ -269,6 +272,11 @@ intptr_t Plugin::dispatch(DataPort* port, i32 opcode, i32 index, intptr_t value, case effGetNumMidiOutputChannels: case effSetPanLaw: case effGetTailSize: + case effSetEditKnobMode: + case __effConnectInputDeprecated: + case __effConnectOutputDeprecated: + case __effKeysRequiredDeprecated: + case __effIdentifyDeprecated: port->sendRequest(); port->waitResponse(); return frame->value; @@ -398,7 +406,8 @@ intptr_t Plugin::dispatch(DataPort* port, i32 opcode, i32 index, intptr_t value, return frame->value; } case effGetVendorString: - case effGetProductString: { + case effGetProductString: + case effShellGetNextPlugin: { port->sendRequest(); port->waitResponse(); @@ -579,6 +588,20 @@ intptr_t Plugin::dispatch(DataPort* port, i32 opcode, i32 index, intptr_t value, port->sendRequest(); port->waitResponse(); return frame->value; + + case effSetSpeakerArrangement: { + void* pluginInput = reinterpret_cast(value); + void* pluginOutput = ptr; + + u8* data = frame->data; + std::memcpy(data, pluginInput, sizeof(VstSpeakerArrangement)); + + data += sizeof(VstSpeakerArrangement); + std::memcpy(data, pluginOutput, sizeof(VstSpeakerArrangement)); + + port->sendRequest(); + port->waitResponse(); + return frame->value; } } ERROR("Unhandled dispatch event: %s", kDispatchEvents[opcode]);