mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-10 04:30:12 +02:00
Properly handle effGet{Input,Output}Properties
Apparently the plugin needs the actual contents of the struct for this to work.
This commit is contained in:
+8
-1
@@ -135,6 +135,7 @@ intptr_t send_event(boost::asio::local::stream_protocol::socket& socket,
|
|||||||
const std::optional<EventPayload> payload =
|
const std::optional<EventPayload> payload =
|
||||||
data_converter.read(opcode, index, value, data);
|
data_converter.read(opcode, index, value, data);
|
||||||
if (!payload.has_value()) {
|
if (!payload.has_value()) {
|
||||||
|
// A 1 usually means that the event was processed succesfully
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,7 +218,8 @@ void passthrough_event(boost::asio::local::stream_protocol::socket& socket,
|
|||||||
return &events.as_c_events();
|
return &events.as_c_events();
|
||||||
},
|
},
|
||||||
[&](WantsChunkBuffer&) -> void* { return string_buffer.data(); },
|
[&](WantsChunkBuffer&) -> void* { return string_buffer.data(); },
|
||||||
[&](const WantsVstRect&) -> void* { return string_buffer.data(); },
|
[&](VstIOProperties& props) -> void* { return &props; },
|
||||||
|
[&](WantsVstRect&) -> void* { return string_buffer.data(); },
|
||||||
[&](const WantsVstTimeInfo&) -> void* { return nullptr; },
|
[&](const WantsVstTimeInfo&) -> void* { return nullptr; },
|
||||||
[&](WantsString&) -> void* { return string_buffer.data(); }},
|
[&](WantsString&) -> void* { return string_buffer.data(); }},
|
||||||
event.payload);
|
event.payload);
|
||||||
@@ -265,6 +267,11 @@ void passthrough_event(boost::asio::local::stream_protocol::socket& socket,
|
|||||||
return std::string(*static_cast<char**>(data),
|
return std::string(*static_cast<char**>(data),
|
||||||
return_value);
|
return_value);
|
||||||
},
|
},
|
||||||
|
[&](VstIOProperties& props) -> EventResposnePayload {
|
||||||
|
// The plugin has written a pointer to a VstRect struct
|
||||||
|
// into the data poitner
|
||||||
|
return props;
|
||||||
|
},
|
||||||
[&](WantsVstRect&) -> EventResposnePayload {
|
[&](WantsVstRect&) -> EventResposnePayload {
|
||||||
// The plugin has written a pointer to a VstRect struct
|
// The plugin has written a pointer to a VstRect struct
|
||||||
// into the data poitner
|
// into the data poitner
|
||||||
|
|||||||
@@ -177,6 +177,7 @@ void Logger::log_event(bool is_dispatch,
|
|||||||
[&](const WantsChunkBuffer&) {
|
[&](const WantsChunkBuffer&) {
|
||||||
message << "<writable_buffer>";
|
message << "<writable_buffer>";
|
||||||
},
|
},
|
||||||
|
[&](const VstIOProperties&) { message << "<io_properties>"; },
|
||||||
[&](const WantsVstRect&) { message << "<writable_buffer>"; },
|
[&](const WantsVstRect&) { message << "<writable_buffer>"; },
|
||||||
[&](const WantsVstTimeInfo&) { message << "<nullptr>"; },
|
[&](const WantsVstTimeInfo&) { message << "<nullptr>"; },
|
||||||
[&](const WantsString&) { message << "<writable_string>"; }},
|
[&](const WantsString&) { message << "<writable_string>"; }},
|
||||||
@@ -202,21 +203,23 @@ void Logger::log_event_response(bool is_dispatch,
|
|||||||
message << return_value;
|
message << return_value;
|
||||||
|
|
||||||
std::visit(
|
std::visit(
|
||||||
overload{[&](const std::monostate&) {},
|
overload{
|
||||||
|
[&](const std::monostate&) {},
|
||||||
[&](const std::string& s) {
|
[&](const std::string& s) {
|
||||||
if (s.size() < 32) {
|
if (s.size() < 32) {
|
||||||
message << ", \"" << s << "\"";
|
message << ", \"" << s << "\"";
|
||||||
} else {
|
} else {
|
||||||
// Long strings contain binary data that we
|
// Long strings contain binary data that we probably
|
||||||
// probably don't want to print
|
// don't want to print
|
||||||
message << ", <" << s.size() << " bytes>";
|
message << ", <" << s.size() << " bytes>";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[&](const AEffect&) { message << ", <AEffect_object>"; },
|
[&](const AEffect&) { message << ", <AEffect_object>"; },
|
||||||
|
[&](const VstIOProperties&) { message << ", <io_properties>"; },
|
||||||
[&](const VstRect& rect) {
|
[&](const VstRect& rect) {
|
||||||
message << ", {l: " << rect.left << ", t: " << rect.top
|
message << ", {l: " << rect.left << ", t: " << rect.top
|
||||||
<< ", r: " << rect.right
|
<< ", r: " << rect.right << ", b: " << rect.bottom
|
||||||
<< ", b: " << rect.bottom << "}";
|
<< "}";
|
||||||
},
|
},
|
||||||
[&](const VstTimeInfo&) { message << ", <time_info>"; }},
|
[&](const VstTimeInfo&) { message << ", <time_info>"; }},
|
||||||
payload);
|
payload);
|
||||||
|
|||||||
@@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
|
#include "vst24.h"
|
||||||
|
|
||||||
// These constants are limits used by bitsery
|
// These constants are limits used by bitsery
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -83,6 +85,11 @@ void serialize(S& s, AEffect& plugin) {
|
|||||||
s.value4b(plugin.version);
|
s.value4b(plugin.version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename S>
|
||||||
|
void serialize(S& s, VstIOProperties& props) {
|
||||||
|
s.container1b(props.data);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename S>
|
template <typename S>
|
||||||
void serialize(S& s, VstRect& rect) {
|
void serialize(S& s, VstRect& rect) {
|
||||||
s.value2b(rect.top);
|
s.value2b(rect.top);
|
||||||
@@ -212,6 +219,7 @@ using EventPayload = std::variant<std::nullptr_t,
|
|||||||
AEffect,
|
AEffect,
|
||||||
DynamicVstEvents,
|
DynamicVstEvents,
|
||||||
WantsChunkBuffer,
|
WantsChunkBuffer,
|
||||||
|
VstIOProperties,
|
||||||
WantsVstRect,
|
WantsVstRect,
|
||||||
WantsVstTimeInfo,
|
WantsVstTimeInfo,
|
||||||
WantsString>;
|
WantsString>;
|
||||||
@@ -233,6 +241,7 @@ void serialize(S& s, EventPayload& payload) {
|
|||||||
events.events, max_midi_events,
|
events.events, max_midi_events,
|
||||||
[](S& s, VstEvent& event) { s.container1b(event.dump); });
|
[](S& s, VstEvent& event) { s.container1b(event.dump); });
|
||||||
},
|
},
|
||||||
|
[](S& s, VstIOProperties& props) { s.object(props); },
|
||||||
[](S&, WantsChunkBuffer&) {}, [](S&, WantsVstRect&) {},
|
[](S&, WantsChunkBuffer&) {}, [](S&, WantsVstRect&) {},
|
||||||
[](S&, WantsVstTimeInfo&) {}, [](S&, WantsString&) {}});
|
[](S&, WantsVstTimeInfo&) {}, [](S&, WantsString&) {}});
|
||||||
}
|
}
|
||||||
@@ -289,8 +298,12 @@ struct Event {
|
|||||||
* `audioMasterIOChanged`.
|
* `audioMasterIOChanged`.
|
||||||
* - An X11 window pointer for the editor window.
|
* - An X11 window pointer for the editor window.
|
||||||
*/
|
*/
|
||||||
using EventResposnePayload =
|
using EventResposnePayload = std::variant<std::monostate,
|
||||||
std::variant<std::monostate, std::string, AEffect, VstRect, VstTimeInfo>;
|
std::string,
|
||||||
|
AEffect,
|
||||||
|
VstIOProperties,
|
||||||
|
VstRect,
|
||||||
|
VstTimeInfo>;
|
||||||
|
|
||||||
template <typename S>
|
template <typename S>
|
||||||
void serialize(S& s, EventResposnePayload& payload) {
|
void serialize(S& s, EventResposnePayload& payload) {
|
||||||
@@ -304,6 +317,7 @@ void serialize(S& s, EventResposnePayload& payload) {
|
|||||||
s.text1b(string, binary_buffer_size);
|
s.text1b(string, binary_buffer_size);
|
||||||
},
|
},
|
||||||
[](S& s, AEffect& effect) { s.object(effect); },
|
[](S& s, AEffect& effect) { s.object(effect); },
|
||||||
|
[](S& s, VstIOProperties& props) { s.object(props); },
|
||||||
[](S& s, VstRect& rect) { s.object(rect); },
|
[](S& s, VstRect& rect) { s.object(rect); },
|
||||||
[](S& s, VstTimeInfo& time_info) { s.object(time_info); }});
|
[](S& s, VstTimeInfo& time_info) { s.object(time_info); }});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -206,6 +206,13 @@ class DispatchDataConverter : DefaultDataConverter {
|
|||||||
case effProcessEvents:
|
case effProcessEvents:
|
||||||
return DynamicVstEvents(*static_cast<const VstEvents*>(data));
|
return DynamicVstEvents(*static_cast<const VstEvents*>(data));
|
||||||
break;
|
break;
|
||||||
|
case effGetInputProperties:
|
||||||
|
case effGetOutputProperties:
|
||||||
|
// In this case we can't simply pass an empty marker struct
|
||||||
|
// because the host can have already populated this field with
|
||||||
|
// data (or at least Bitwig does this)
|
||||||
|
return *static_cast<const VstIOProperties*>(data);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return DefaultDataConverter::read(opcode, index, value, data);
|
return DefaultDataConverter::read(opcode, index, value, data);
|
||||||
break;
|
break;
|
||||||
@@ -232,11 +239,21 @@ class DispatchDataConverter : DefaultDataConverter {
|
|||||||
// `HostBridge` and write a pointer to that struct to the data
|
// `HostBridge` and write a pointer to that struct to the data
|
||||||
// pointer
|
// pointer
|
||||||
|
|
||||||
std::string buffer = std::get<std::string>(response.payload);
|
const auto buffer = std::get<std::string>(response.payload);
|
||||||
chunk.assign(buffer.begin(), buffer.end());
|
chunk.assign(buffer.begin(), buffer.end());
|
||||||
|
|
||||||
*static_cast<void**>(data) = chunk.data();
|
*static_cast<void**>(data) = chunk.data();
|
||||||
} break;
|
} break;
|
||||||
|
case effGetInputProperties:
|
||||||
|
case effGetOutputProperties: {
|
||||||
|
// These opcodes pass the plugin some empty struct through the
|
||||||
|
// data parameter that the plugin then fills with flags and
|
||||||
|
// other data to describe an input or output channel.
|
||||||
|
const auto properties =
|
||||||
|
std::get<VstIOProperties>(response.payload);
|
||||||
|
|
||||||
|
*static_cast<VstIOProperties*>(data) = properties;
|
||||||
|
} break;
|
||||||
default:
|
default:
|
||||||
DefaultDataConverter::write(opcode, data, response);
|
DefaultDataConverter::write(opcode, data, response);
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user