From 50172aefbb9c20892e46c066468313f430f34bd3 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Sat, 7 Mar 2020 17:57:56 +0100 Subject: [PATCH] Write basic log messages --- src/common/logging.cpp | 7 +-- src/plugin/host-bridge.cpp | 78 +++++++++++++++++++++------------ src/plugin/host-bridge.h | 9 ++++ src/wine-host/plugin-bridge.cpp | 33 +++++++++----- src/wine-host/vst-host.cpp | 2 +- 5 files changed, 86 insertions(+), 43 deletions(-) diff --git a/src/common/logging.cpp b/src/common/logging.cpp index f9e776c9..6ea3b98f 100644 --- a/src/common/logging.cpp +++ b/src/common/logging.cpp @@ -34,8 +34,9 @@ Logger::Logger(std::ostream&& stream, Logger Logger::create_from_environment(std::string prefix) { auto env = boost::this_process::environment(); - std::string file_path = env.get(logging_file_environment_variable); - std::string verbosity = env.get(logging_verbosity_environment_variable); + std::string file_path = env[logging_file_environment_variable].to_string(); + std::string verbosity = + env[logging_verbosity_environment_variable].to_string(); // Default to `Verbosity::basic` if the environment variable has not // been set or if it is not an integer. @@ -68,7 +69,7 @@ void Logger::log(const std::string& message) { localtime_r(×tamp, &tm); std::ostringstream formatted_message; - formatted_message << "[" << std::put_time(&tm, "%T") << "]"; + formatted_message << std::put_time(&tm, "%T") << " "; formatted_message << prefix; formatted_message << message; // Flushing a stringstream doesn't do anything, but we need to put a diff --git a/src/plugin/host-bridge.cpp b/src/plugin/host-bridge.cpp index 69cd1c5c..68dc88c9 100644 --- a/src/plugin/host-bridge.cpp +++ b/src/plugin/host-bridge.cpp @@ -47,6 +47,7 @@ constexpr char alphanumeric_characters[] = std::string create_logger_prefix(const fs::path& socket_path); fs::path find_vst_plugin(); fs::path find_wine_vst_host(); +std::optional find_wineprefix(); fs::path generate_endpoint_name(); bp::environment set_wineprefix(); @@ -65,10 +66,10 @@ HostBridge& get_bridge_instance(const AEffect& plugin) { return *static_cast(plugin.ptr3); } -// TODO: When adding debug information, print both the path to the VST host and -// the chosen wineprefix HostBridge::HostBridge(audioMasterCallback host_callback) - : io_context(), + : vst_host_path(find_wine_vst_host()), + vst_plugin_path(find_vst_plugin()), + io_context(), socket_endpoint(generate_endpoint_name().string()), socket_acceptor(io_context, socket_endpoint), host_vst_dispatch(io_context), @@ -79,15 +80,20 @@ HostBridge::HostBridge(audioMasterCallback host_callback) host_callback_function(host_callback), logger(Logger::create_from_environment( create_logger_prefix(socket_endpoint.path()))), - vst_host(find_wine_vst_host(), + vst_host(vst_host_path, // The Wine VST host needs to know which plugin to load // and which Unix domain socket to connect to - find_vst_plugin(), + vst_plugin_path, socket_endpoint.path(), bp::env = set_wineprefix()), process_buffer(std::make_unique()) { - // It's very important that these sockets are connected to in the same order - // in the Wine VST host + logger.log("Initializing yabridge using '" + vst_host_path.string() + "'"); + logger.log("plugin: '" + vst_plugin_path.string() + "'"); + logger.log("wineprefix: '" + + find_wineprefix().value_or("").string() + "'"); + + // It's very important that these sockets are connected to in the same + // order in the Wine VST host socket_acceptor.accept(host_vst_dispatch); socket_acceptor.accept(vst_host_callback); socket_acceptor.accept(host_vst_parameters); @@ -201,6 +207,23 @@ float HostBridge::get_parameter(AEffect* /*plugin*/, int32_t index) { return response.value.value(); } +/** + * Create a logger prefix based on the unique socket path for easy + * identification. The socket path contains both the plugin's name and a unique + * identifier. + * + * @param socket_path The path to the socket endpoint in use. + * + * @return A prefix string for log messages. + */ +std::string create_logger_prefix(const fs::path& socket_path) { + std::ostringstream prefix; + prefix << "[" << socket_path.filename().replace_extension().string() + << "] "; + + return prefix.str(); +} + /** * Finds the Wine VST hsot (named `yabridge-host.exe`). For this we will search * in two places: @@ -234,19 +257,26 @@ fs::path find_wine_vst_host() { } /** - * Create a logger prefix based on the unique socket path for easy - * identification. The socket path contains both the plugin's name and a unique - * identifier. + * Locate the wineprefix this file is located in, if it is inside of a wine + * prefix. * - * @param socket_path The path to the socket endpoint in use. - * - * @return A prefix string for log messages. + * @return Either the path to the wineprefix (containing the `drive_c?` + * directory), or `std::nullopt` if it is not inside of a wine prefix. */ -std::string create_logger_prefix(const fs::path& socket_path) { - std::ostringstream prefix; - prefix << "[" << socket_path.filename() << "] "; +std::optional find_wineprefix() { + // Try to locate the wineprefix this .so file is located in by finding the + // first parent directory that contains a directory named `dosdevices` + fs::path wineprefix_path = + boost::dll::this_line_location().remove_filename(); + while (wineprefix_path != "") { + if (fs::is_directory(wineprefix_path / "dosdevices")) { + return wineprefix_path; + } - return prefix.str(); + wineprefix_path = wineprefix_path.parent_path(); + } + + return std::nullopt; } /** @@ -320,17 +350,9 @@ fs::path generate_endpoint_name() { bp::environment set_wineprefix() { auto env(boost::this_process::environment()); - // Try to locate the wineprefix this .so file is located in by finding the - // first parent directory that contains a directory named `dosdevices` - fs::path wineprefix_path = - boost::dll::this_line_location().remove_filename(); - while (wineprefix_path != "") { - if (fs::is_directory(wineprefix_path / "dosdevices")) { - env["WINEPREFIX"] = wineprefix_path.string(); - break; - } - - wineprefix_path = wineprefix_path.parent_path(); + const auto wineprefix_path = find_wineprefix(); + if (wineprefix_path.has_value()) { + env["WINEPREFIX"] = wineprefix_path->string(); } return env; diff --git a/src/plugin/host-bridge.h b/src/plugin/host-bridge.h index ebe665e4..08648df7 100644 --- a/src/plugin/host-bridge.h +++ b/src/plugin/host-bridge.h @@ -69,6 +69,15 @@ class HostBridge { void set_parameter(AEffect* plugin, int32_t index, float value); float get_parameter(AEffect* plugin, int32_t index); + /** + * The path to `yabridge-host.exe`. + */ + const boost::filesystem::path vst_host_path; + /** + * The path to the .dll being loaded in the Wine VST host. + */ + const boost::filesystem::path vst_plugin_path; + /** * This AEffect struct will be populated using the data passed by the Wine * VST host during initialization and then passed as a pointer to the Linux diff --git a/src/wine-host/plugin-bridge.cpp b/src/wine-host/plugin-bridge.cpp index 416b5570..4f3f08b4 100644 --- a/src/wine-host/plugin-bridge.cpp +++ b/src/wine-host/plugin-bridge.cpp @@ -16,9 +16,9 @@ #include "plugin-bridge.h" -#include +#include -namespace fs = std::filesystem; +namespace fs = boost::filesystem; /** * A function pointer to what should be the entry point of a VST plugin. @@ -69,8 +69,11 @@ PluginBridge::PluginBridge(std::string plugin_dll_path, process_buffer(std::make_unique()) { // Got to love these C APIs if (plugin_handle == nullptr) { - throw std::runtime_error("Could not load a shared library at '" + - plugin_dll_path + "'."); + std::string error = + "Could not load a shared library at '" + plugin_dll_path + "'."; + + logger.log("ERROR: " + error); + throw std::runtime_error(error); } // VST plugin entry point functions should be called `VSTPluginMain`, but @@ -86,9 +89,11 @@ PluginBridge::PluginBridge(std::string plugin_dll_path, } } if (vst_entry_point == nullptr) { - throw std::runtime_error( - "Could not find a valid VST entry point for '" + plugin_dll_path + - "'."); + std::string error = "Could not find a valid VST entry point for '" + + plugin_dll_path + "'."; + + logger.log("ERROR: " + error); + throw std::runtime_error(error); } // It's very important that these sockets are accepted to in the same order @@ -106,8 +111,11 @@ PluginBridge::PluginBridge(std::string plugin_dll_path, current_bridge_isntance = this; plugin = vst_entry_point(host_callback_proxy); if (plugin == nullptr) { - throw std::runtime_error("VST plugin at '" + plugin_dll_path + - "' failed to initialize."); + std::string error = + "VST plugin at '" + plugin_dll_path + "' failed to initialize."; + + logger.log("ERROR: " + error); + throw std::runtime_error(error); } // Send the plugin's information to the Linux VST plugin @@ -182,6 +190,8 @@ PluginBridge::PluginBridge(std::string plugin_dll_path, write_object(host_vst_process_replacing, response, *process_buffer); } }); + + logger.log("Finished initializing '" + plugin_dll_path + "'"); } void PluginBridge::wait() { @@ -210,8 +220,9 @@ intptr_t PluginBridge::host_callback(AEffect* /*plugin*/, */ std::string create_logger_prefix(const fs::path& socket_path) { std::ostringstream prefix; - prefix << "[" << socket_path.filename() << "] "; - prefix << "[WINE] "; + prefix << "[" << socket_path.filename().replace_extension().string() + << "] "; + prefix << "[Wine] "; return prefix.str(); } diff --git a/src/wine-host/vst-host.cpp b/src/wine-host/vst-host.cpp index 83787c28..83f2649e 100644 --- a/src/wine-host/vst-host.cpp +++ b/src/wine-host/vst-host.cpp @@ -38,7 +38,7 @@ int main(int argc, char* argv[]) { // Block the main thread until the plugin shuts down bridge.wait(); } catch (const std::runtime_error& error) { - std::cerr << "Error while initializing plugin:" << std::endl; + std::cerr << "Error while initializing Wine VST host:" << std::endl; std::cerr << error.what() << std::endl; return 1;