Write basic log messages

This commit is contained in:
Robbert van der Helm
2020-03-07 17:57:56 +01:00
parent 77b2d1b44a
commit 50172aefbb
5 changed files with 86 additions and 43 deletions
+4 -3
View File
@@ -34,8 +34,9 @@ Logger::Logger(std::ostream&& stream,
Logger Logger::create_from_environment(std::string prefix) { Logger Logger::create_from_environment(std::string prefix) {
auto env = boost::this_process::environment(); auto env = boost::this_process::environment();
std::string file_path = env.get(logging_file_environment_variable); std::string file_path = env[logging_file_environment_variable].to_string();
std::string verbosity = env.get(logging_verbosity_environment_variable); std::string verbosity =
env[logging_verbosity_environment_variable].to_string();
// Default to `Verbosity::basic` if the environment variable has not // Default to `Verbosity::basic` if the environment variable has not
// been set or if it is not an integer. // been set or if it is not an integer.
@@ -68,7 +69,7 @@ void Logger::log(const std::string& message) {
localtime_r(&timestamp, &tm); localtime_r(&timestamp, &tm);
std::ostringstream formatted_message; std::ostringstream formatted_message;
formatted_message << "[" << std::put_time(&tm, "%T") << "]"; formatted_message << std::put_time(&tm, "%T") << " ";
formatted_message << prefix; formatted_message << prefix;
formatted_message << message; formatted_message << message;
// Flushing a stringstream doesn't do anything, but we need to put a // Flushing a stringstream doesn't do anything, but we need to put a
+50 -28
View File
@@ -47,6 +47,7 @@ constexpr char alphanumeric_characters[] =
std::string create_logger_prefix(const fs::path& socket_path); std::string create_logger_prefix(const fs::path& socket_path);
fs::path find_vst_plugin(); fs::path find_vst_plugin();
fs::path find_wine_vst_host(); fs::path find_wine_vst_host();
std::optional<fs::path> find_wineprefix();
fs::path generate_endpoint_name(); fs::path generate_endpoint_name();
bp::environment set_wineprefix(); bp::environment set_wineprefix();
@@ -65,10 +66,10 @@ HostBridge& get_bridge_instance(const AEffect& plugin) {
return *static_cast<HostBridge*>(plugin.ptr3); return *static_cast<HostBridge*>(plugin.ptr3);
} }
// TODO: When adding debug information, print both the path to the VST host and
// the chosen wineprefix
HostBridge::HostBridge(audioMasterCallback host_callback) 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_endpoint(generate_endpoint_name().string()),
socket_acceptor(io_context, socket_endpoint), socket_acceptor(io_context, socket_endpoint),
host_vst_dispatch(io_context), host_vst_dispatch(io_context),
@@ -79,15 +80,20 @@ HostBridge::HostBridge(audioMasterCallback host_callback)
host_callback_function(host_callback), host_callback_function(host_callback),
logger(Logger::create_from_environment( logger(Logger::create_from_environment(
create_logger_prefix(socket_endpoint.path()))), 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 // The Wine VST host needs to know which plugin to load
// and which Unix domain socket to connect to // and which Unix domain socket to connect to
find_vst_plugin(), vst_plugin_path,
socket_endpoint.path(), socket_endpoint.path(),
bp::env = set_wineprefix()), bp::env = set_wineprefix()),
process_buffer(std::make_unique<AudioBuffers::buffer_type>()) { process_buffer(std::make_unique<AudioBuffers::buffer_type>()) {
// It's very important that these sockets are connected to in the same order logger.log("Initializing yabridge using '" + vst_host_path.string() + "'");
// in the Wine VST host logger.log("plugin: '" + vst_plugin_path.string() + "'");
logger.log("wineprefix: '" +
find_wineprefix().value_or("<default>").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(host_vst_dispatch);
socket_acceptor.accept(vst_host_callback); socket_acceptor.accept(vst_host_callback);
socket_acceptor.accept(host_vst_parameters); socket_acceptor.accept(host_vst_parameters);
@@ -201,6 +207,23 @@ float HostBridge::get_parameter(AEffect* /*plugin*/, int32_t index) {
return response.value.value(); 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 * Finds the Wine VST hsot (named `yabridge-host.exe`). For this we will search
* in two places: * 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 * Locate the wineprefix this file is located in, if it is inside of a wine
* identification. The socket path contains both the plugin's name and a unique * prefix.
* identifier.
* *
* @param socket_path The path to the socket endpoint in use. * @return Either the path to the wineprefix (containing the `drive_c?`
* * directory), or `std::nullopt` if it is not inside of a wine prefix.
* @return A prefix string for log messages.
*/ */
std::string create_logger_prefix(const fs::path& socket_path) { std::optional<fs::path> find_wineprefix() {
std::ostringstream prefix; // Try to locate the wineprefix this .so file is located in by finding the
prefix << "[" << socket_path.filename() << "] "; // 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() { bp::environment set_wineprefix() {
auto env(boost::this_process::environment()); auto env(boost::this_process::environment());
// Try to locate the wineprefix this .so file is located in by finding the const auto wineprefix_path = find_wineprefix();
// first parent directory that contains a directory named `dosdevices` if (wineprefix_path.has_value()) {
fs::path wineprefix_path = env["WINEPREFIX"] = wineprefix_path->string();
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();
} }
return env; return env;
+9
View File
@@ -69,6 +69,15 @@ class HostBridge {
void set_parameter(AEffect* plugin, int32_t index, float value); void set_parameter(AEffect* plugin, int32_t index, float value);
float get_parameter(AEffect* plugin, int32_t index); 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 * 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 * VST host during initialization and then passed as a pointer to the Linux
+22 -11
View File
@@ -16,9 +16,9 @@
#include "plugin-bridge.h" #include "plugin-bridge.h"
#include <filesystem> #include <boost/filesystem.hpp>
namespace fs = std::filesystem; namespace fs = boost::filesystem;
/** /**
* A function pointer to what should be the entry point of a VST plugin. * 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<AudioBuffers::buffer_type>()) { process_buffer(std::make_unique<AudioBuffers::buffer_type>()) {
// Got to love these C APIs // Got to love these C APIs
if (plugin_handle == nullptr) { if (plugin_handle == nullptr) {
throw std::runtime_error("Could not load a shared library at '" + std::string error =
plugin_dll_path + "'."); "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 // 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) { if (vst_entry_point == nullptr) {
throw std::runtime_error( std::string error = "Could not find a valid VST entry point for '" +
"Could not find a valid VST entry point for '" + plugin_dll_path + 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 // 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; current_bridge_isntance = this;
plugin = vst_entry_point(host_callback_proxy); plugin = vst_entry_point(host_callback_proxy);
if (plugin == nullptr) { if (plugin == nullptr) {
throw std::runtime_error("VST plugin at '" + plugin_dll_path + std::string error =
"' failed to initialize."); "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 // 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); write_object(host_vst_process_replacing, response, *process_buffer);
} }
}); });
logger.log("Finished initializing '" + plugin_dll_path + "'");
} }
void PluginBridge::wait() { 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::string create_logger_prefix(const fs::path& socket_path) {
std::ostringstream prefix; std::ostringstream prefix;
prefix << "[" << socket_path.filename() << "] "; prefix << "[" << socket_path.filename().replace_extension().string()
prefix << "[WINE] "; << "] ";
prefix << "[Wine] ";
return prefix.str(); return prefix.str();
} }
+1 -1
View File
@@ -38,7 +38,7 @@ int main(int argc, char* argv[]) {
// Block the main thread until the plugin shuts down // Block the main thread until the plugin shuts down
bridge.wait(); bridge.wait();
} catch (const std::runtime_error& error) { } 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; std::cerr << error.what() << std::endl;
return 1; return 1;