diff --git a/README.md b/README.md index 58caede0..1a75af73 100644 --- a/README.md +++ b/README.md @@ -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: - Fix implementation bugs: - - `VstTimeInfo` doesn't get passed to the plugin correctly in - `audioMasterGetTime`. - Polish GUIs even further. There are some todos left in `src/wine-host/editor.{h,cpp}`. - There are likely some minor issues left. diff --git a/src/common/events.h b/src/common/events.h index f51a72cc..ec968cc1 100644 --- a/src/common/events.h +++ b/src/common/events.h @@ -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 // returning structs, but in this case the value returned // from the callback function is actually a pointer to a - // `VstTimeInfo` struct! - return *reinterpret_cast(return_value); + // `VstTimeInfo` struct! It can also be a null pointer if + // the host doesn't support this. + const auto time_info = + reinterpret_cast(return_value); + if (time_info == nullptr) { + return std::monostate{}; + } else { + return *time_info; + } }, [&](WantsString&) -> EventResposnePayload { return std::string(static_cast(data)); diff --git a/src/common/serialization.h b/src/common/serialization.h index cc473385..e4d05d39 100644 --- a/src/common/serialization.h +++ b/src/common/serialization.h @@ -295,6 +295,9 @@ struct Event { * - A specific struct in response to an event such as `audioMasterGetTime` or * `audioMasterIOChanged`. * - 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& time_info) : plugin(plugin), editor(editor), time_info(time_info) {} std::optional read(const int opcode, @@ -314,8 +314,15 @@ class HostCallbackDataConverter : DefaultDataConverter { switch (opcode) { case audioMasterGetTime: // Write the returned `VstTimeInfo` struct into a field and make - // the function return a poitner to it in the function below - time_info = std::get(response.payload); + // the function return a poitner to it in the function below. + // 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(response.payload)) { + time_info = std::nullopt; + } else { + time_info = std::get(response.payload); + } break; default: DefaultDataConverter::write(opcode, data, response); @@ -325,12 +332,16 @@ class HostCallbackDataConverter : DefaultDataConverter { intptr_t return_value(const int opcode, const intptr_t original) { switch (opcode) { - case audioMasterGetTime: + case audioMasterGetTime: { // Return a pointer to the `VstTimeInfo` object written in the // function above - // TODO: This is incorrect! - return reinterpret_cast(&time); - break; + VstTimeInfo* time_info_pointer = nullptr; + if (time_info.has_value()) { + time_info_pointer = &time_info.value(); + } + + return reinterpret_cast(time_info_pointer); + } break; default: return DefaultDataConverter::return_value(opcode, original); break; @@ -341,7 +352,7 @@ class HostCallbackDataConverter : DefaultDataConverter { AEffect* plugin; // TODO: Clean up Editor& editor; - VstTimeInfo& time_info; + std::optional& time_info; }; intptr_t PluginBridge::host_callback(AEffect* effect, diff --git a/src/wine-host/plugin-bridge.h b/src/wine-host/plugin-bridge.h index c174f646..61c40af7 100644 --- a/src/wine-host/plugin-bridge.h +++ b/src/wine-host/plugin-bridge.h @@ -67,9 +67,11 @@ class PluginBridge { /** * 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 time_info; private: /**