From 620ba5b7567042d4e1c9b626a11e130fa4688970 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Thu, 5 Mar 2020 19:03:48 +0100 Subject: [PATCH] Define a buffer size for each type --- src/common/communication.h | 62 ++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/src/common/communication.h b/src/common/communication.h index 51ecc318..b6d7fb8a 100644 --- a/src/common/communication.h +++ b/src/common/communication.h @@ -49,23 +49,23 @@ constexpr size_t max_buffer_size = 16384; constexpr size_t max_string_length = 128; /** - * The buffer size in bytes used for all buffers for sending and recieving - * messages. - * - * TODO: This should probably depend on the type. 512 bytes is way too much for - * events, and probably not enough for sending audio. + * A simple constant sized buffer for smaller types that can be allocated on the + * stack. */ -constexpr size_t buffer_size = 512; - -// Types used for serialization and deserialization with bitsery. template -using Buffer = std::array; +using ArrayBuffer = std::array; -template -using OutputAdapter = bitsery::OutputBufferAdapter>; +/** + * A dynamically sized buffer, useful for larger types without known sizes. In + * other words, audio buffers. + */ +using VectorBuffer = std::vector; -template -using InputAdapter = bitsery::InputBufferAdapter>; +template +using OutputAdapter = bitsery::OutputBufferAdapter; + +template +using InputAdapter = bitsery::InputBufferAdapter; /** * An event as dispatched by the VST host. These events will get forwarded to @@ -73,6 +73,8 @@ using InputAdapter = bitsery::InputBufferAdapter>; * arguments sent to the `AEffect::dispatch` function. */ struct Event { + using buffer_type = ArrayBuffer; + int32_t opcode; int32_t index; // TODO: This is an intptr_t, if we want to support 32 bit Wine plugins all @@ -106,6 +108,8 @@ struct Event { * AN instance of this should be sent back as a response to an incoming event. */ struct EventResult { + using buffer_type = ArrayBuffer; + /** * The result that should be returned from the dispatch function. */ @@ -129,6 +133,8 @@ struct EventResult { * whether `value` contains a value or not. */ struct Parameter { + using buffer_type = ArrayBuffer<16>; + int32_t index; std::optional value; @@ -146,6 +152,8 @@ struct Parameter { * from the Wine VST host. */ struct ParameterResult { + using buffer_type = ArrayBuffer<16>; + std::optional value; template @@ -160,6 +168,8 @@ struct ParameterResult { * processing. The number of samples is encoded in each audio buffer's length. */ struct AudioBuffer { + using buffer_type = VectorBuffer; + /** * An audio buffer for each of the plugin's audio channels. The number of * samples is equal to `buffers[0].size()`. @@ -196,6 +206,18 @@ void serialize(S& s, AEffect& plugin) { s.container1b(plugin.unknown1); } +// I don't want to editor 'include/vestige/aeffect.h`. That's why this type +// trait and the above serialization function are here.` +template +struct buffer_type { + using type = typename T::buffer_type; +}; + +template <> +struct buffer_type { + using type = ArrayBuffer<128>; +}; + /** * Serialize an object using bitsery and write it to a socket. * @@ -206,9 +228,9 @@ void serialize(S& s, AEffect& plugin) { */ template inline void write_object(Socket& socket, const T& object) { - Buffer buffer; - auto length = - bitsery::quickSerialization>(buffer, object); + typename buffer_type::type buffer; + auto length = bitsery::quickSerialization< + OutputAdapter::type>>(buffer, object); socket.send(boost::asio::buffer(buffer, length)); } @@ -228,12 +250,12 @@ inline void write_object(Socket& socket, const T& object) { */ template inline T read_object(Socket& socket, T object = T()) { - Buffer buffer; + typename buffer_type::type buffer; auto message_length = socket.receive(boost::asio::buffer(buffer)); - auto [_, success] = - bitsery::quickDeserialization>( - {buffer.begin(), message_length}, object); + auto [_, success] = bitsery::quickDeserialization< + InputAdapter::type>>( + {buffer.begin(), message_length}, object); if (!success) { throw std::runtime_error("Deserialization failure in call:" +