From 6e5b0f8490848c2761e5f57db0e3ddd9b78275d6 Mon Sep 17 00:00:00 2001 From: Anton Kalmykov Date: Sun, 3 May 2015 01:03:02 +0300 Subject: [PATCH 1/9] Add support of the VST shell plugins --- src/host/host.cpp | 6 ++++++ src/plugin/plugin.cpp | 10 ++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/host/host.cpp b/src/host/host.cpp index e17aeab..aef2ece 100644 --- a/src/host/host.cpp +++ b/src/host/host.cpp @@ -315,6 +315,10 @@ bool Host::handleDispatch(DataFrame* frame) case effEndSetProgram: case effStopProcess: case effGetTailSize: +// 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 +429,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; @@ -549,6 +554,7 @@ 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; diff --git a/src/plugin/plugin.cpp b/src/plugin/plugin.cpp index 042d847..c636a02 100644 --- a/src/plugin/plugin.cpp +++ b/src/plugin/plugin.cpp @@ -197,6 +197,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 +227,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 +270,10 @@ intptr_t Plugin::dispatch(DataPort* port, i32 opcode, i32 index, intptr_t value, case effGetNumMidiOutputChannels: case effSetPanLaw: case effGetTailSize: +// case __effConnectInputDeprecated: +// case __effConnectOutputDeprecated: +// case __effKeysRequiredDeprecated: +// case __effIdentifyDeprecated: port->sendRequest(); port->waitResponse(); return frame->value; @@ -398,7 +403,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(); From 8e8abc6ccb47d0b4f651ffe706142439c87ffcde Mon Sep 17 00:00:00 2001 From: Anton Kalmykov Date: Sun, 3 May 2015 15:07:14 +0300 Subject: [PATCH 2/9] Add bridging of the initial plugin delay --- src/common/protocol.h | 1 + src/host/host.cpp | 2 ++ src/plugin/plugin.cpp | 2 ++ 3 files changed, 5 insertions(+) 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 aef2ece..414b621 100644 --- a/src/host/host.cpp +++ b/src/host/host.cpp @@ -134,6 +134,7 @@ 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; @@ -555,6 +556,7 @@ intptr_t Host::audioMaster(i32 opcode, i32 index, intptr_t value, void* ptr, flo case audioMasterGetCurrentProcessLevel: case audioMasterGetAutomationState: case audioMasterCurrentId: +// case audioMasterUpdateDisplay: callbackPort_.sendRequest(); callbackPort_.waitResponse(); return frame->value; diff --git a/src/plugin/plugin.cpp b/src/plugin/plugin.cpp index c636a02..a139c63 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); } From e41cdbdaf423730eaeccc3d05565c6930d3ea7cd Mon Sep 17 00:00:00 2001 From: Anton Kalmykov Date: Sun, 3 May 2015 15:09:12 +0300 Subject: [PATCH 3/9] Enable handling of the audioMasterUpdateDisplay event --- src/host/host.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/host/host.cpp b/src/host/host.cpp index 414b621..4cf6a09 100644 --- a/src/host/host.cpp +++ b/src/host/host.cpp @@ -556,15 +556,15 @@ intptr_t Host::audioMaster(i32 opcode, i32 index, intptr_t value, void* ptr, flo case audioMasterGetCurrentProcessLevel: case audioMasterGetAutomationState: case audioMasterCurrentId: -// case audioMasterUpdateDisplay: + case audioMasterUpdateDisplay: callbackPort_.sendRequest(); callbackPort_.waitResponse(); return frame->value; // FIXME Passing the audioMasterUpdateDisplay request to the plugin endpoint leads to // crash with some plugins. - case audioMasterUpdateDisplay: - return 1; +// case audioMasterUpdateDisplay: +// return 1; case audioMasterIdle: case __audioMasterNeedIdleDeprecated: From de605376f3cb7e0747b55f00eadc000ef929f933 Mon Sep 17 00:00:00 2001 From: Anton Kalmykov Date: Sun, 3 May 2015 15:10:29 +0300 Subject: [PATCH 4/9] Add handlers for the some deprecated events (Tracktion uses them) --- src/host/host.cpp | 8 ++++---- src/plugin/plugin.cpp | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/host/host.cpp b/src/host/host.cpp index 4cf6a09..01ce67c 100644 --- a/src/host/host.cpp +++ b/src/host/host.cpp @@ -316,10 +316,10 @@ bool Host::handleDispatch(DataFrame* frame) case effEndSetProgram: case effStopProcess: case effGetTailSize: -// case __effConnectInputDeprecated: -// case __effConnectOutputDeprecated: -// case __effKeysRequiredDeprecated: -// case __effIdentifyDeprecated: + case __effConnectInputDeprecated: + case __effConnectOutputDeprecated: + case __effKeysRequiredDeprecated: + case __effIdentifyDeprecated: frame->value = effect_->dispatcher(effect_, frame->opcode, frame->index, frame->value, nullptr, frame->opt); break; diff --git a/src/plugin/plugin.cpp b/src/plugin/plugin.cpp index a139c63..fa93fea 100644 --- a/src/plugin/plugin.cpp +++ b/src/plugin/plugin.cpp @@ -272,10 +272,10 @@ intptr_t Plugin::dispatch(DataPort* port, i32 opcode, i32 index, intptr_t value, case effGetNumMidiOutputChannels: case effSetPanLaw: case effGetTailSize: -// case __effConnectInputDeprecated: -// case __effConnectOutputDeprecated: -// case __effKeysRequiredDeprecated: -// case __effIdentifyDeprecated: + case __effConnectInputDeprecated: + case __effConnectOutputDeprecated: + case __effKeysRequiredDeprecated: + case __effIdentifyDeprecated: port->sendRequest(); port->waitResponse(); return frame->value; From ca480e2ea7e9254761807af2d2aa7a130594286e Mon Sep 17 00:00:00 2001 From: Anton Kalmykov Date: Mon, 11 May 2015 12:55:43 +0300 Subject: [PATCH 5/9] Add handlers for several unhandled events --- src/host/host.cpp | 14 +++++++++++++- src/plugin/plugin.cpp | 19 +++++++++++++++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/host/host.cpp b/src/host/host.cpp index 01ce67c..27049d7 100644 --- a/src/host/host.cpp +++ b/src/host/host.cpp @@ -316,6 +316,7 @@ bool Host::handleDispatch(DataFrame* frame) case effEndSetProgram: case effStopProcess: case effGetTailSize: + case effSetEditKnobMode: case __effConnectInputDeprecated: case __effConnectOutputDeprecated: case __effKeysRequiredDeprecated: @@ -470,6 +471,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]); } @@ -562,7 +574,7 @@ intptr_t Host::audioMaster(i32 opcode, i32 index, intptr_t value, void* ptr, flo 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 fa93fea..113d53f 100644 --- a/src/plugin/plugin.cpp +++ b/src/plugin/plugin.cpp @@ -272,6 +272,7 @@ 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: @@ -331,7 +332,7 @@ intptr_t Plugin::dispatch(DataPort* port, i32 opcode, i32 index, intptr_t value, XSync(display, false); // FIXME without this delay, the VST window sometimes stays black. - usleep(100000); +// usleep(100000); Window child = frame->value; XReparentWindow(display, child, parent, 0, 0); @@ -344,7 +345,7 @@ intptr_t Plugin::dispatch(DataPort* port, i32 opcode, i32 index, intptr_t value, port->waitResponse(); // FIXME without this delay, the VST window sometimes stays black. - usleep(100000); +// usleep(100000); XMapWindow(display, child); XSync(display, false); @@ -587,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]); From c564f4f020d9af2947e4e10fdec1796de24ff033 Mon Sep 17 00:00:00 2001 From: Anton Kalmykov Date: Mon, 11 May 2015 12:57:05 +0300 Subject: [PATCH 6/9] Disable handling of the audioMasterUpdateDisplay event u-he TripleCheese hangs in the Renoise tracker --- src/host/host.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/host/host.cpp b/src/host/host.cpp index 27049d7..ffb9d28 100644 --- a/src/host/host.cpp +++ b/src/host/host.cpp @@ -568,15 +568,14 @@ intptr_t Host::audioMaster(i32 opcode, i32 index, intptr_t value, void* ptr, flo case audioMasterGetCurrentProcessLevel: case audioMasterGetAutomationState: case audioMasterCurrentId: - case audioMasterUpdateDisplay: callbackPort_.sendRequest(); callbackPort_.waitResponse(); return frame->value; // FIXME Passing the audioMasterUpdateDisplay request to the plugin endpoint leads to // crash (or lock in Renoise) with some plugins (u-he TripleCheese). -// case audioMasterUpdateDisplay: -// return 1; + case audioMasterUpdateDisplay: + return 1; case audioMasterIdle: case __audioMasterNeedIdleDeprecated: From ebfe00e1863c5538e8c854379cdf0cda1942a7a8 Mon Sep 17 00:00:00 2001 From: Anton Kalmykov Date: Mon, 11 May 2015 12:58:11 +0300 Subject: [PATCH 7/9] Update compatibility list --- README.md | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) 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 From 26524ea6c77ff9bd1bf64f7332748b5c850ffbaf Mon Sep 17 00:00:00 2001 From: Anton Kalmykov Date: Fri, 15 May 2015 21:04:37 +0300 Subject: [PATCH 8/9] Workaround for Waves plugins to show the GUI --- src/host/host.cpp | 9 ++++++++- src/plugin/plugin.cpp | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/host/host.cpp b/src/host/host.cpp index ffb9d28..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(); @@ -138,6 +138,13 @@ bool Host::initialize(const char* fileName, int portId) 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; diff --git a/src/plugin/plugin.cpp b/src/plugin/plugin.cpp index 113d53f..c247352 100644 --- a/src/plugin/plugin.cpp +++ b/src/plugin/plugin.cpp @@ -332,7 +332,7 @@ intptr_t Plugin::dispatch(DataPort* port, i32 opcode, i32 index, intptr_t value, XSync(display, false); // FIXME without this delay, the VST window sometimes stays black. -// usleep(100000); + usleep(100000); Window child = frame->value; XReparentWindow(display, child, parent, 0, 0); @@ -345,7 +345,7 @@ intptr_t Plugin::dispatch(DataPort* port, i32 opcode, i32 index, intptr_t value, port->waitResponse(); // FIXME without this delay, the VST window sometimes stays black. -// usleep(100000); + usleep(100000); XMapWindow(display, child); XSync(display, false); From 254a902bdf2043c02aacd33230d3cd6e23db5718 Mon Sep 17 00:00:00 2001 From: Anton Kalmykov Date: Fri, 15 May 2015 21:25:13 +0300 Subject: [PATCH 9/9] Increase the minor version number --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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