mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-06 19:40:10 +02:00
Fix VstTimeinfo responses and allow null responses
The host is allowed to return a null pointer if it doesn't support the query.
This commit is contained in:
@@ -7,8 +7,6 @@ Yet Another way to use Windows VST2 plugins in Linux VST hosts.
|
|||||||
There are a few things that should be done before releasing this, including:
|
There are a few things that should be done before releasing this, including:
|
||||||
|
|
||||||
- Fix implementation bugs:
|
- Fix implementation bugs:
|
||||||
- `VstTimeInfo` doesn't get passed to the plugin correctly in
|
|
||||||
`audioMasterGetTime`.
|
|
||||||
- Polish GUIs even further. There are some todos left in
|
- Polish GUIs even further. There are some todos left in
|
||||||
`src/wine-host/editor.{h,cpp}`.
|
`src/wine-host/editor.{h,cpp}`.
|
||||||
- There are likely some minor issues left.
|
- There are likely some minor issues left.
|
||||||
|
|||||||
+9
-2
@@ -285,8 +285,15 @@ void passthrough_event(boost::asio::local::stream_protocol::socket& socket,
|
|||||||
// Not sure why the VST API has twenty different ways of
|
// Not sure why the VST API has twenty different ways of
|
||||||
// returning structs, but in this case the value returned
|
// returning structs, but in this case the value returned
|
||||||
// from the callback function is actually a pointer to a
|
// from the callback function is actually a pointer to a
|
||||||
// `VstTimeInfo` struct!
|
// `VstTimeInfo` struct! It can also be a null pointer if
|
||||||
return *reinterpret_cast<const VstTimeInfo*>(return_value);
|
// the host doesn't support this.
|
||||||
|
const auto time_info =
|
||||||
|
reinterpret_cast<const VstTimeInfo*>(return_value);
|
||||||
|
if (time_info == nullptr) {
|
||||||
|
return std::monostate{};
|
||||||
|
} else {
|
||||||
|
return *time_info;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
[&](WantsString&) -> EventResposnePayload {
|
[&](WantsString&) -> EventResposnePayload {
|
||||||
return std::string(static_cast<char*>(data));
|
return std::string(static_cast<char*>(data));
|
||||||
|
|||||||
@@ -295,6 +295,9 @@ struct Event {
|
|||||||
* - A specific struct in response to an event such as `audioMasterGetTime` or
|
* - A specific struct in response to an event such as `audioMasterGetTime` or
|
||||||
* `audioMasterIOChanged`.
|
* `audioMasterIOChanged`.
|
||||||
* - An X11 window pointer for the editor window.
|
* - An X11 window pointer for the editor window.
|
||||||
|
*
|
||||||
|
* TODO: Replace `std::monostate` with `std::nullptr_t` as it's more expressive
|
||||||
|
* in what it actually represents.
|
||||||
*/
|
*/
|
||||||
using EventResposnePayload = std::variant<std::monostate,
|
using EventResposnePayload = std::variant<std::monostate,
|
||||||
std::string,
|
std::string,
|
||||||
|
|||||||
@@ -130,7 +130,9 @@ void Editor::handle_events() {
|
|||||||
|
|
||||||
// Handle X11 events
|
// Handle X11 events
|
||||||
// TODO: Check if we should forward other events mostly to prevent
|
// TODO: Check if we should forward other events mostly to prevent
|
||||||
// unnecessary GUI processing in the background
|
// unnecessary GUI processing in the background. Since
|
||||||
|
// `effEditIdle` should only be called when the plugin's editor is
|
||||||
|
// open this should not cause any different in CPU though.
|
||||||
// TODO: Check whether drag and drop works out of the box
|
// TODO: Check whether drag and drop works out of the box
|
||||||
xcb_generic_event_t* generic_event;
|
xcb_generic_event_t* generic_event;
|
||||||
while ((generic_event = xcb_poll_for_event(x11_connection.get())) !=
|
while ((generic_event = xcb_poll_for_event(x11_connection.get())) !=
|
||||||
|
|||||||
@@ -272,7 +272,7 @@ class HostCallbackDataConverter : DefaultDataConverter {
|
|||||||
public:
|
public:
|
||||||
HostCallbackDataConverter(AEffect* plugin,
|
HostCallbackDataConverter(AEffect* plugin,
|
||||||
Editor& editor,
|
Editor& editor,
|
||||||
VstTimeInfo& time_info)
|
std::optional<VstTimeInfo>& time_info)
|
||||||
: plugin(plugin), editor(editor), time_info(time_info) {}
|
: plugin(plugin), editor(editor), time_info(time_info) {}
|
||||||
|
|
||||||
std::optional<EventPayload> read(const int opcode,
|
std::optional<EventPayload> read(const int opcode,
|
||||||
@@ -314,8 +314,15 @@ class HostCallbackDataConverter : DefaultDataConverter {
|
|||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case audioMasterGetTime:
|
case audioMasterGetTime:
|
||||||
// Write the returned `VstTimeInfo` struct into a field and make
|
// Write the returned `VstTimeInfo` struct into a field and make
|
||||||
// the function return a poitner to it in the function below
|
// the function return a poitner to it in the function below.
|
||||||
time_info = std::get<VstTimeInfo>(response.payload);
|
// Depending on whether the host supported the requested time
|
||||||
|
// information this operations returns either a null pointer or
|
||||||
|
// a pointer to a `VstTimeInfo` object.
|
||||||
|
if (std::holds_alternative<std::monostate>(response.payload)) {
|
||||||
|
time_info = std::nullopt;
|
||||||
|
} else {
|
||||||
|
time_info = std::get<VstTimeInfo>(response.payload);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DefaultDataConverter::write(opcode, data, response);
|
DefaultDataConverter::write(opcode, data, response);
|
||||||
@@ -325,12 +332,16 @@ class HostCallbackDataConverter : DefaultDataConverter {
|
|||||||
|
|
||||||
intptr_t return_value(const int opcode, const intptr_t original) {
|
intptr_t return_value(const int opcode, const intptr_t original) {
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case audioMasterGetTime:
|
case audioMasterGetTime: {
|
||||||
// Return a pointer to the `VstTimeInfo` object written in the
|
// Return a pointer to the `VstTimeInfo` object written in the
|
||||||
// function above
|
// function above
|
||||||
// TODO: This is incorrect!
|
VstTimeInfo* time_info_pointer = nullptr;
|
||||||
return reinterpret_cast<intptr_t>(&time);
|
if (time_info.has_value()) {
|
||||||
break;
|
time_info_pointer = &time_info.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
return reinterpret_cast<intptr_t>(time_info_pointer);
|
||||||
|
} break;
|
||||||
default:
|
default:
|
||||||
return DefaultDataConverter::return_value(opcode, original);
|
return DefaultDataConverter::return_value(opcode, original);
|
||||||
break;
|
break;
|
||||||
@@ -341,7 +352,7 @@ class HostCallbackDataConverter : DefaultDataConverter {
|
|||||||
AEffect* plugin;
|
AEffect* plugin;
|
||||||
// TODO: Clean up
|
// TODO: Clean up
|
||||||
Editor& editor;
|
Editor& editor;
|
||||||
VstTimeInfo& time_info;
|
std::optional<VstTimeInfo>& time_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
intptr_t PluginBridge::host_callback(AEffect* effect,
|
intptr_t PluginBridge::host_callback(AEffect* effect,
|
||||||
|
|||||||
@@ -67,9 +67,11 @@ class PluginBridge {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* With the `audioMasterGetTime` host callback the plugin expects the return
|
* With the `audioMasterGetTime` host callback the plugin expects the return
|
||||||
* value from the calblack to be a pointer to a VstTimeInfo struct.
|
* value from the calblack to be a pointer to a VstTimeInfo struct. If the
|
||||||
|
* host did not support a certain time info query, than we'll store the
|
||||||
|
* returned null pointer as a nullopt.
|
||||||
*/
|
*/
|
||||||
VstTimeInfo time_info;
|
std::optional<VstTimeInfo> time_info;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user