Add a more distinct wrapper around chunk data

This commit is contained in:
Robbert van der Helm
2020-12-07 02:41:37 +01:00
parent 7f7da50282
commit 84d00b568b
4 changed files with 47 additions and 37 deletions
+27 -25
View File
@@ -931,8 +931,8 @@ EventResult passthrough_event(AEffect* plugin, F callback, Event& event) {
[&](const std::string& s) -> void* { [&](const std::string& s) -> void* {
return const_cast<char*>(s.c_str()); return const_cast<char*>(s.c_str());
}, },
[&](const std::vector<uint8_t>& buffer) -> void* { [&](const ChunkData& chunk) -> void* {
return const_cast<uint8_t*>(buffer.data()); return const_cast<uint8_t*>(chunk.buffer.data());
}, },
[&](native_size_t& window_handle) -> void* { [&](native_size_t& window_handle) -> void* {
// This is the X11 window handle that the editor should reparent // This is the X11 window handle that the editor should reparent
@@ -982,32 +982,26 @@ EventResult passthrough_event(AEffect* plugin, F callback, Event& event) {
auto write_payload_fn = overload{ auto write_payload_fn = overload{
[&](auto) -> EventResultPayload { return nullptr; }, [&](auto) -> EventResultPayload { return nullptr; },
[&](const AEffect& updated_plugin) -> EventResultPayload { [&](const AEffect& updated_plugin) -> EventResultPayload {
// This is a bit of a special case! Instead of writing some // This is a bit of a special case! Instead of writing some return
// return value, we will update values on the native VST // value, we will update values on the native VST plugin's `AEffect`
// plugin's `AEffect` object. This is triggered by the // object. This is triggered by the `audioMasterIOChanged` callback
// `audioMasterIOChanged` callback from the hosted VST plugin. // from the hosted VST plugin.
update_aeffect(*plugin, updated_plugin); update_aeffect(*plugin, updated_plugin);
return nullptr; return nullptr;
}, },
[&](DynamicSpeakerArrangement& speaker_arrangement) [&](DynamicSpeakerArrangement& speaker_arrangement)
-> EventResultPayload { return speaker_arrangement; }, -> EventResultPayload { return speaker_arrangement; },
[&](WantsChunkBuffer&) -> EventResultPayload {
// In this case the plugin will have written its data stored in
// an array to which a pointer is stored in `data`, with the
// return value from the event determines how much data the
// plugin has written
const uint8_t* chunk_data = *static_cast<uint8_t**>(data);
return std::vector<uint8_t>(chunk_data, chunk_data + return_value);
},
[&](VstIOProperties& props) -> EventResultPayload { return props; },
[&](VstMidiKeyName& key_name) -> EventResultPayload {
return key_name;
},
[&](VstParameterProperties& props) -> EventResultPayload {
return props;
},
[&](WantsAEffectUpdate&) -> EventResultPayload { return *plugin; }, [&](WantsAEffectUpdate&) -> EventResultPayload { return *plugin; },
[&](WantsChunkBuffer&) -> EventResultPayload {
// In this case the plugin will have written its data stored in an
// array to which a pointer is stored in `data`, with the return
// value from the event determines how much data the plugin has
// written
const uint8_t* chunk_data = *static_cast<uint8_t**>(data);
return ChunkData{
std::vector<uint8_t>(chunk_data, chunk_data + return_value)};
},
[&](WantsVstRect&) -> EventResultPayload { [&](WantsVstRect&) -> EventResultPayload {
// The plugin should have written a pointer to a VstRect struct into // The plugin should have written a pointer to a VstRect struct into
// the data pointer. I haven't seen this fail yet, but since some // the data pointer. I haven't seen this fail yet, but since some
@@ -1021,10 +1015,11 @@ EventResult passthrough_event(AEffect* plugin, F callback, Event& event) {
return *editor_rect; return *editor_rect;
}, },
[&](WantsVstTimeInfo&) -> EventResultPayload { [&](WantsVstTimeInfo&) -> EventResultPayload {
// Not sure why the VST API has twenty different ways of returning // Not sure why the VST API has twenty different ways of
// structs, but in this case the value returned from the callback // returning structs, but in this case the value returned from
// function is actually a pointer to a `VstTimeInfo` struct! It can // the callback function is actually a pointer to a
// also be a null pointer if the host doesn't support this. // `VstTimeInfo` struct! It can also be a null pointer if the
// host doesn't support this.
const auto time_info = const auto time_info =
reinterpret_cast<const VstTimeInfo*>(return_value); reinterpret_cast<const VstTimeInfo*>(return_value);
if (!time_info) { if (!time_info) {
@@ -1035,6 +1030,13 @@ EventResult passthrough_event(AEffect* plugin, F callback, Event& event) {
}, },
[&](WantsString&) -> EventResultPayload { [&](WantsString&) -> EventResultPayload {
return std::string(static_cast<char*>(data)); return std::string(static_cast<char*>(data));
},
[&](VstIOProperties& props) -> EventResultPayload { return props; },
[&](VstMidiKeyName& key_name) -> EventResultPayload {
return key_name;
},
[&](VstParameterProperties& props) -> EventResultPayload {
return props;
}}; }};
// As mentioned about, the `effSetSpeakerArrangement` and // As mentioned about, the `effSetSpeakerArrangement` and
+4 -4
View File
@@ -198,8 +198,8 @@ void Logger::log_event(bool is_dispatch,
message << "<" << s.size() << " bytes>"; message << "<" << s.size() << " bytes>";
} }
}, },
[&](const std::vector<uint8_t>& buffer) { [&](const ChunkData& chunk) {
message << "<" << buffer.size() << " byte chunk>"; message << "<" << chunk.buffer.size() << " byte chunk>";
}, },
[&](const native_size_t& window_id) { [&](const native_size_t& window_id) {
message << "<window " << window_id << ">"; message << "<window " << window_id << ">";
@@ -277,8 +277,8 @@ void Logger::log_event_response(
message << ", <" << s.size() << " bytes>"; message << ", <" << s.size() << " bytes>";
} }
}, },
[&](const std::vector<uint8_t>& buffer) { [&](const ChunkData& chunk) {
message << ", <" << buffer.size() << " byte chunk>"; message << ", <" << chunk.buffer.size() << " byte chunk>";
}, },
[&](const AEffect&) { message << ", <AEffect_object>"; }, [&](const AEffect&) { message << ", <AEffect_object>"; },
[&](const DynamicSpeakerArrangement& speaker_arrangement) { [&](const DynamicSpeakerArrangement& speaker_arrangement) {
+13 -6
View File
@@ -172,6 +172,13 @@ void serialize(S& s, VstTimeInfo& time_info) {
s.value4b(time_info.flags); s.value4b(time_info.flags);
} }
/**
* Wrapper for chunk data.
*/
struct ChunkData {
std::vector<uint8_t> buffer;
};
/** /**
* A wrapper around `VstEvents` that stores the data in a vector instead of a * A wrapper around `VstEvents` that stores the data in a vector instead of a
* C-style array. Needed until bitsery supports C-style arrays * C-style array. Needed until bitsery supports C-style arrays
@@ -361,9 +368,9 @@ struct WantsString {};
*/ */
using EventPayload = std::variant<std::nullptr_t, using EventPayload = std::variant<std::nullptr_t,
std::string, std::string,
std::vector<uint8_t>,
native_size_t, native_size_t,
AEffect, AEffect,
ChunkData,
DynamicVstEvents, DynamicVstEvents,
DynamicSpeakerArrangement, DynamicSpeakerArrangement,
WantsAEffectUpdate, WantsAEffectUpdate,
@@ -383,8 +390,8 @@ void serialize(S& s, EventPayload& payload) {
[](S& s, std::string& string) { [](S& s, std::string& string) {
s.text1b(string, max_string_length); s.text1b(string, max_string_length);
}, },
[](S& s, std::vector<uint8_t>& buffer) { [](S& s, ChunkData& chunk) {
s.container1b(buffer, binary_buffer_size); s.container1b(chunk.buffer, binary_buffer_size);
}, },
[](S& s, native_size_t& window_handle) { [](S& s, native_size_t& window_handle) {
s.value8b(window_handle); s.value8b(window_handle);
@@ -460,8 +467,8 @@ struct Event {
*/ */
using EventResultPayload = std::variant<std::nullptr_t, using EventResultPayload = std::variant<std::nullptr_t,
std::string, std::string,
std::vector<uint8_t>,
AEffect, AEffect,
ChunkData,
DynamicSpeakerArrangement, DynamicSpeakerArrangement,
VstIOProperties, VstIOProperties,
VstMidiKeyName, VstMidiKeyName,
@@ -477,8 +484,8 @@ void serialize(S& s, EventResultPayload& payload) {
[](S& s, std::string& string) { [](S& s, std::string& string) {
s.text1b(string, max_string_length); s.text1b(string, max_string_length);
}, },
[](S& s, std::vector<uint8_t>& buffer) { [](S& s, ChunkData& chunk) {
s.container1b(buffer, binary_buffer_size); s.container1b(chunk.buffer, binary_buffer_size);
}, },
[](S& s, AEffect& effect) { s.object(effect); }, [](S& s, AEffect& effect) { s.object(effect); },
[&](DynamicSpeakerArrangement& speaker_arrangement) -> void* { [&](DynamicSpeakerArrangement& speaker_arrangement) -> void* {
+3 -2
View File
@@ -203,7 +203,8 @@ class DispatchDataConverter : DefaultDataConverter {
// When the host passes a chunk it will use the value parameter // When the host passes a chunk it will use the value parameter
// to tell us its length // to tell us its length
return std::vector<uint8_t>(chunk_data, chunk_data + value); return ChunkData{
std::vector<uint8_t>(chunk_data, chunk_data + value)};
} break; } break;
case effProcessEvents: case effProcessEvents:
return DynamicVstEvents(*static_cast<const VstEvents*>(data)); return DynamicVstEvents(*static_cast<const VstEvents*>(data));
@@ -299,7 +300,7 @@ class DispatchDataConverter : DefaultDataConverter {
// `PluginBridge` and write a pointer to that struct to the data // `PluginBridge` and write a pointer to that struct to the data
// pointer // pointer
const auto buffer = const auto buffer =
std::get<std::vector<uint8_t>>(response.payload); std::get<ChunkData>(response.payload).buffer;
chunk.assign(buffer.begin(), buffer.end()); chunk.assign(buffer.begin(), buffer.end());
*static_cast<uint8_t**>(data) = chunk.data(); *static_cast<uint8_t**>(data) = chunk.data();