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:
Robbert van der Helm
2020-04-14 15:59:23 +02:00
parent a2ba001e2f
commit eed4677ed3
6 changed files with 38 additions and 15 deletions
-2
View File
@@ -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
View File
@@ -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));
+3
View File
@@ -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,
+3 -1
View File
@@ -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())) !=
+19 -8
View File
@@ -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,
+4 -2
View File
@@ -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:
/** /**