mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-08 04:20:13 +02:00
ac17539ef3
Not really needed (since the only other thing happening in the IO context is processing stdio from the Wine process) and it was causing some impossible to debug malloc failures in Boost.Asio.
152 lines
5.6 KiB
C++
152 lines
5.6 KiB
C++
// yabridge: a Wine VST bridge
|
|
// Copyright (C) 2020 Robbert van der Helm
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
#pragma once
|
|
|
|
#include <optional>
|
|
#include <ostream>
|
|
|
|
#include "serialization.h"
|
|
|
|
/**
|
|
* Super basic logging facility meant for debugging malfunctioning VST
|
|
* plugins. This is also used to redirect the output of the Wine process
|
|
* because DAWs like Bitwig hide this from you, making it hard to debug
|
|
* crashing plugins.
|
|
*
|
|
* @note This does not do any synchronisation. While this should technically
|
|
* be causing problems in concurrent use, writing strings to fstreams from
|
|
* multiple threads at the same time doesn't seem to produce corrupted text if
|
|
* you're writing an entire string at once even though the messages may be
|
|
* slightly out of order.
|
|
*/
|
|
class Logger {
|
|
public:
|
|
enum class Verbosity : int {
|
|
/**
|
|
* Only output basic information such as the VST plugin that's being
|
|
* loaded and Wine's output. Doesn't add timestamps to reduce overhead.
|
|
* To quiet down Wine you could optionally also set the `WINEDEBUG`
|
|
* environment variable.
|
|
*/
|
|
basic = 0,
|
|
/**
|
|
* Also print information about callbacks and functions being called by
|
|
* the plugin and the host. This excludes the `effEditIdle()` and
|
|
* `audioMasterGetTime()` events and the event with opcode 52 since
|
|
* those events are typically sent tens of times per second. Every
|
|
* message is prefixed with a timestamp.
|
|
*/
|
|
most_events = 1,
|
|
/**
|
|
* The same as the above but without filtering out any events. This is
|
|
* very chatty but it can be crucial for debugging plugin-specific
|
|
* problems.
|
|
*/
|
|
all_events = 2,
|
|
};
|
|
|
|
/**
|
|
* Initialize the logger with the following verbosity level.
|
|
*
|
|
* @param stream The `std::ostream` instance to use. Typically either a file
|
|
* stream or STDERR.
|
|
* @param verbosity_level The verbosity of the logging, see the
|
|
* `Logger::Verbosity` constants above for a description of the verbosity
|
|
* levels.
|
|
* @param prefix An optional prefix for the logger. Useful for differentiate
|
|
* messages coming from the Wine VST host.
|
|
*/
|
|
Logger(std::shared_ptr<std::ostream> stream,
|
|
Verbosity verbosity_level,
|
|
std::string prefix = "");
|
|
|
|
/**
|
|
* Create a logger instance based on the set environment variables. See the
|
|
* constants in `logging.cpp` for more information.
|
|
*
|
|
* @param prefix A message to prepend for every log message, useful to
|
|
* differentiate between the Wine process and the Linux VST plugin.
|
|
*/
|
|
static Logger create_from_environment(std::string prefix = "");
|
|
|
|
/**
|
|
* Write a message to the log, prefixing it with a timestamp and this
|
|
* logger's prefix string.
|
|
*
|
|
* @param message The message to write.
|
|
*/
|
|
void log(const std::string& message);
|
|
|
|
// The following functions are for logging specific events, they are only
|
|
// enabled for verbosity levels higher than 1 (i.e. `Verbosity::events`)
|
|
void log_get_parameter(int index);
|
|
void log_get_parameter_response(float vlaue);
|
|
void log_set_parameter(int index, float value);
|
|
void log_set_parameter_response();
|
|
// If `is_dispatch` is `true`, then use opcode names from the plugin's
|
|
// dispatch function. Otherwise use names for the host callback function
|
|
// opcodes.
|
|
void log_event(bool is_dispatch,
|
|
int opcode,
|
|
int index,
|
|
intptr_t value,
|
|
const EventPayload& payload,
|
|
float option,
|
|
const std::optional<EventPayload>& value_payload);
|
|
void log_event_response(
|
|
bool is_dispatch,
|
|
int opcode,
|
|
intptr_t return_value,
|
|
const EventResultPayload& payload,
|
|
const std::optional<EventResultPayload>& value_payload);
|
|
|
|
private:
|
|
/**
|
|
* Determine whether an event should be filtered based on the current
|
|
* verbosity level.
|
|
*/
|
|
bool should_filter_event(bool is_dispatch, int opcode) const;
|
|
|
|
/**
|
|
* The output stream to write the log messages to. Typically either STDERR
|
|
* or a file stream.
|
|
*/
|
|
std::shared_ptr<std::ostream> stream;
|
|
/**
|
|
* The verbosity level of this logger instance. Based on this certain
|
|
* messages may or may not be shown.
|
|
*/
|
|
Verbosity verbosity;
|
|
/**
|
|
* A prefix that gets prepended before every message.
|
|
*/
|
|
std::string prefix;
|
|
};
|
|
|
|
/**
|
|
* Convert an event opcode to a human readable string for debugging purposes.
|
|
* See `src/include/vestige/aeffectx.h` for a complete list of these opcodes.
|
|
*
|
|
* @param is_dispatch Whether to use opcodes for the `dispatch` function. Will
|
|
* use the names from the host callback function if set to false.
|
|
* @param opcode The opcode of the event.
|
|
*
|
|
* @return Either the name from `aeffectx.h`, or a nullopt if it was not listed
|
|
* there.
|
|
*/
|
|
std::optional<std::string> opcode_to_string(bool is_dispatch, int opcode);
|