diff --git a/meson.build b/meson.build index 5e5dfe60..670ac30a 100644 --- a/meson.build +++ b/meson.build @@ -25,20 +25,12 @@ msgpack_dep = dependency('msgpack') include_dir = include_directories('src/include') -common_src = [] - -linux_plugin_src = [ - 'src/plugin/bridge.cpp', - 'src/plugin/plugin.cpp', -] - -wine_host_src = [ - 'src/wine-host/vst-host.cpp', -] - shared_library( 'yabridge', - linux_plugin_src + common_src, + [ + 'src/plugin/bridge.cpp', + 'src/plugin/plugin.cpp', + ], native : true, include_directories : include_dir, dependencies : [boost_dep, msgpack_dep], @@ -47,7 +39,9 @@ shared_library( executable( 'yabridge-host', - wine_host_src + common_src, + [ + 'src/wine-host/vst-host.cpp', + ], native : false, include_directories : include_dir, dependencies : [], diff --git a/src/common/communication.h b/src/common/communication.h new file mode 100644 index 00000000..9f0a8639 --- /dev/null +++ b/src/common/communication.h @@ -0,0 +1,81 @@ +#pragma once + +#include +#include +#include + +/** + * An event as dispatched by the VST host. These events will get forwarded to + * the VST host process running under Wine. The fields here mirror those + * arguments sent to the `AEffect::dispatch` function. + */ +struct Event { + int32_t opcode; + int32_t parameter; + // TODO: This is an intptr_t, is this actually a poitner that should be + // dereferenced? + intptr_t value; + float option; + + MSGPACK_DEFINE(opcode, parameter, value, option) +}; + +/** + * AN instance of this should be sent back as a response to an incoming event. + */ +struct EventResult { + /** + * The result that should be returned from the dispatch function. + */ + intptr_t return_value; + /** + * If present, this should get written into the void pointer passed to the + * dispatch function. + */ + std::optional result; + + // TODO: Add missing return value fields; + + MSGPACK_DEFINE(return_value, result) +}; + +/** + * Serialize an object and write it to a stream. This function prefixes the + * output with the length of the serialized object in bytes since msgpack + * doesn't handle this on its own. + * + * @param stream An ostream that can be written to. + * @param object The object to write to the stream. + * + * @relates read_object + */ +template +inline void write_object(Stream& stream, const T& object) { + // TODO: Reuse buffers + msgpack::sbuffer buffer; + msgpack::pack(buffer, object); + + stream << buffer.size(); + stream << buffer.data(); + stream.flush(); +} + +/** + * Deserialize an object by reading it from a stream. This should be used + * together with `write_object`. This will block until the object is + available. + * + * @param stream The stream to read from. + * + * @relates write_object + */ +template +inline EventResult read_object(Stream& stream) { + size_t message_length; + stream >> message_length; + + // TODO: Reuse buffers + std::vector buffer(message_length); + stream.read(buffer.data(), message_length); + return msgpack::unpack(buffer.data(), message_length).get().convert(); +} diff --git a/src/common/events.h b/src/common/events.h deleted file mode 100644 index 06afb2aa..00000000 --- a/src/common/events.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include -#include -#include - -/** - * An event as dispatched by the VST host. These events will get forwarded to - * the VST host process running under Wine. The fields here mirror those - * arguments sent to the `AEffect::dispatch` function. - */ -struct Event { - int32_t opcode; - int32_t parameter; - // TODO: This is an intptr_t, is this actually a poitner that should be - // dereferenced? - intptr_t value; - float option; - - MSGPACK_DEFINE(opcode, parameter, value, option) -}; - -/** - * AN instance of this should be sent back as a response to an incoming event. - */ -struct EventResult { - /** - * The result that should be returned from the dispatch function. - */ - intptr_t return_value; - /** - * If present, this should get written into the void pointer passed to the - * dispatch function. - */ - std::optional result; - - // TODO: Add missing return value fields; - - MSGPACK_DEFINE(return_value, result) -}; diff --git a/src/plugin/bridge.cpp b/src/plugin/bridge.cpp index 10bf923b..4ff89e85 100644 --- a/src/plugin/bridge.cpp +++ b/src/plugin/bridge.cpp @@ -6,7 +6,7 @@ #include #include -#include "../common/events.h" +#include "../common/communication.h" // TODO: I should track down the VST2 SDK for clarification on some of the // implementation details, such as the use of intptr_t isntead of void* @@ -38,13 +38,10 @@ intptr_t Bridge::dispatch(AEffect* /*plugin*/, intptr_t value, void* result, float option) { - // TODO: Send to the Wine process Event event{opcode, parameter, value, option}; - msgpack::sbuffer buffer; - msgpack::pack(buffer, event); + write_object(vst_stdin, event); - // TODO: Read the response - EventResult response; + EventResult response = read_object(vst_stdout); if (response.result) { std::copy(response.result->begin(), response.result->end(), static_cast(result));