From 7fcf5abaf2f1e6e95640f8a9c4a53c73a0bffbb2 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Mon, 9 Mar 2020 23:53:36 +0100 Subject: [PATCH] Handle `effGetChunk` correctly --- src/common/communication.h | 3 ++- src/plugin/host-bridge.cpp | 30 ++++++++++++++++++++++++++++-- src/plugin/host-bridge.h | 8 ++++++++ 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/common/communication.h b/src/common/communication.h index ed94d7d0..5ca4813e 100644 --- a/src/common/communication.h +++ b/src/common/communication.h @@ -114,7 +114,8 @@ inline T read_object(Socket& socket) { * (`audioMaster()`). The `dispatch()` function will require some more specific * structs. */ -struct DefaultDataConverter { +class DefaultDataConverter { + public: EventPayload read(const int /*opcode*/, const void* data) { if (data == nullptr) { return nullptr; diff --git a/src/plugin/host-bridge.cpp b/src/plugin/host-bridge.cpp index c8eed339..9464f23f 100644 --- a/src/plugin/host-bridge.cpp +++ b/src/plugin/host-bridge.cpp @@ -137,12 +137,18 @@ HostBridge::HostBridge(audioMasterCallback host_callback) plugin = read_object(vst_host_aeffect, plugin); } -struct DispatchDataConverter : DefaultDataConverter { +class DispatchDataConverter : DefaultDataConverter { + public: + DispatchDataConverter(std::vector& chunk_data) + : chunk(chunk_data) {} + EventPayload read(const int opcode, const void* data) { // There are some events that need specific structs that we can't simply // serialize as a string because they might contain null bytes // TODO: More of these structs switch (opcode) { + case effGetChunk: + return WantsBinaryBuffer(); case effProcessEvents: return DynamicVstEvents(*static_cast(data)); break; @@ -151,6 +157,26 @@ struct DispatchDataConverter : DefaultDataConverter { break; } } + + void write(const int opcode, void* data, const EventResult& response) { + switch (opcode) { + case effGetChunk: + // Write the chunk data to some publically accessible place in + // `HostBridge` and write a pointer to that struct to the data + // pointer + assert(response.data.has_value()); + chunk.assign(response.data->begin(), response.data->end()); + + *static_cast(data) = chunk.data(); + break; + default: + DefaultDataConverter::write(opcode, data, response); + break; + } + } + + private: + std::vector& chunk; }; /** @@ -183,7 +209,7 @@ intptr_t HostBridge::dispatch(AEffect* /*plugin*/, } // TODO: Maybe reuse buffers here when dealing with chunk data - DispatchDataConverter converter; + DispatchDataConverter converter(chunk_data); return send_event(host_vst_dispatch, converter, opcode, index, value, data, option, std::pair(logger, true)); } diff --git a/src/plugin/host-bridge.h b/src/plugin/host-bridge.h index 0ecc7b17..80e1a9a4 100644 --- a/src/plugin/host-bridge.h +++ b/src/plugin/host-bridge.h @@ -87,6 +87,14 @@ class HostBridge { */ AEffect plugin; + /** + * The VST hsot can query a plugin for arbitrary binary data such as + * presets. It will expect the plugin to write back a pointer that points to + * that data. This vector is where we store the chunk data for the last + * `effGetChunk` event. + */ + std::vector chunk_data; + private: /** * Write output from an async pipe to the log on a line by line basis.