mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-06-20 02:13:56 +02:00
Rename PluginBridge to Vst2PluginBridge
This commit is contained in:
@@ -14,8 +14,6 @@ highly compatible, while also staying easy to debug and maintain.
|
|||||||
This branch is still very far removed from being in a usable state. Below is an
|
This branch is still very far removed from being in a usable state. Below is an
|
||||||
imcomplete list of things that still have to be done before this can be used:
|
imcomplete list of things that still have to be done before this can be used:
|
||||||
|
|
||||||
- Rename `PluginBridge` to `Vst2PluginBridge` and explain that the names are
|
|
||||||
chosen this way to be easily greppable.
|
|
||||||
- Actually start implementing VST3 support.
|
- Actually start implementing VST3 support.
|
||||||
- Update the GitHub Actions workflows.
|
- Update the GitHub Actions workflows.
|
||||||
- Update yabridgectl to handle buth VST2 and VST3 plugins.
|
- Update yabridgectl to handle buth VST2 and VST3 plugins.
|
||||||
|
|||||||
@@ -881,7 +881,7 @@ class Sockets {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a unique base directory that can be used as a prefix for all Unix
|
* Generate a unique base directory that can be used as a prefix for all Unix
|
||||||
* domain socket endpoints used in `PluginBridge`/`Vst2Bridge`. This will
|
* domain socket endpoints used in `Vst2PluginBridge`/`Vst2Bridge`. This will
|
||||||
* usually return `/run/user/<uid>/yabridge-<plugin_name>-<random_id>/`.
|
* usually return `/run/user/<uid>/yabridge-<plugin_name>-<random_id>/`.
|
||||||
*
|
*
|
||||||
* Sockets for group hosts are handled separately. See
|
* Sockets for group hosts are handled separately. See
|
||||||
|
|||||||
@@ -458,7 +458,7 @@ struct Event {
|
|||||||
* - A (short) string.
|
* - A (short) string.
|
||||||
* - Some binary blob stored as a byte vector. During `effGetChunk` this will
|
* - Some binary blob stored as a byte vector. During `effGetChunk` this will
|
||||||
* contain some chunk data that should be written to
|
* contain some chunk data that should be written to
|
||||||
* `PluginBridge::chunk_data`.
|
* `Vst2PluginBridge::chunk_data`.
|
||||||
* - 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.
|
||||||
|
|||||||
+29
-27
@@ -41,11 +41,11 @@ float get_parameter_proxy(AEffect*, int);
|
|||||||
* is sadly needed as a workaround to avoid using globals since we need free
|
* is sadly needed as a workaround to avoid using globals since we need free
|
||||||
* function pointers to interface with the VST C API.
|
* function pointers to interface with the VST C API.
|
||||||
*/
|
*/
|
||||||
PluginBridge& get_bridge_instance(const AEffect& plugin) {
|
Vst2PluginBridge& get_bridge_instance(const AEffect& plugin) {
|
||||||
return *static_cast<PluginBridge*>(plugin.ptr3);
|
return *static_cast<Vst2PluginBridge*>(plugin.ptr3);
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginBridge::PluginBridge(audioMasterCallback host_callback)
|
Vst2PluginBridge::Vst2PluginBridge(audioMasterCallback host_callback)
|
||||||
: config(load_config_for(get_this_file_location())),
|
: config(load_config_for(get_this_file_location())),
|
||||||
vst_plugin_path(find_vst_plugin()),
|
vst_plugin_path(find_vst_plugin()),
|
||||||
// All the fields should be zero initialized because
|
// All the fields should be zero initialized because
|
||||||
@@ -297,8 +297,8 @@ class DispatchDataConverter : DefaultDataConverter {
|
|||||||
} break;
|
} break;
|
||||||
case effGetChunk: {
|
case effGetChunk: {
|
||||||
// Write the chunk data to some publically accessible place in
|
// Write the chunk data to some publically accessible place in
|
||||||
// `PluginBridge` and write a pointer to that struct to the data
|
// `Vst2PluginBridge` and write a pointer to that struct to the
|
||||||
// pointer
|
// data pointer
|
||||||
const auto buffer =
|
const auto buffer =
|
||||||
std::get<ChunkData>(response.payload).buffer;
|
std::get<ChunkData>(response.payload).buffer;
|
||||||
chunk.assign(buffer.begin(), buffer.end());
|
chunk.assign(buffer.begin(), buffer.end());
|
||||||
@@ -391,12 +391,12 @@ class DispatchDataConverter : DefaultDataConverter {
|
|||||||
VstRect& rect;
|
VstRect& rect;
|
||||||
};
|
};
|
||||||
|
|
||||||
intptr_t PluginBridge::dispatch(AEffect* /*plugin*/,
|
intptr_t Vst2PluginBridge::dispatch(AEffect* /*plugin*/,
|
||||||
int opcode,
|
int opcode,
|
||||||
int index,
|
int index,
|
||||||
intptr_t value,
|
intptr_t value,
|
||||||
void* data,
|
void* data,
|
||||||
float option) {
|
float option) {
|
||||||
// HACK: Ardour 5.X has a bug in its VST implementation where it calls the
|
// HACK: Ardour 5.X has a bug in its VST implementation where it calls the
|
||||||
// plugin's dispatcher before the plugin has even finished
|
// plugin's dispatcher before the plugin has even finished
|
||||||
// initializing. This has been fixed back in 2018, but there has not
|
// initializing. This has been fixed back in 2018, but there has not
|
||||||
@@ -483,7 +483,7 @@ intptr_t PluginBridge::dispatch(AEffect* /*plugin*/,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, bool replacing>
|
template <typename T, bool replacing>
|
||||||
void PluginBridge::do_process(T** inputs, T** outputs, int sample_frames) {
|
void Vst2PluginBridge::do_process(T** inputs, T** outputs, int sample_frames) {
|
||||||
// The inputs and outputs arrays should be `[num_inputs][sample_frames]` and
|
// The inputs and outputs arrays should be `[num_inputs][sample_frames]` and
|
||||||
// `[num_outputs][sample_frames]` floats large respectfully.
|
// `[num_outputs][sample_frames]` floats large respectfully.
|
||||||
std::vector<std::vector<T>> input_buffers(plugin.numInputs,
|
std::vector<std::vector<T>> input_buffers(plugin.numInputs,
|
||||||
@@ -541,10 +541,10 @@ void PluginBridge::do_process(T** inputs, T** outputs, int sample_frames) {
|
|||||||
incoming_midi_events.clear();
|
incoming_midi_events.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PluginBridge::process(AEffect* /*plugin*/,
|
void Vst2PluginBridge::process(AEffect* /*plugin*/,
|
||||||
float** inputs,
|
float** inputs,
|
||||||
float** outputs,
|
float** outputs,
|
||||||
int sample_frames) {
|
int sample_frames) {
|
||||||
// Technically either `Vst2PluginBridge::process()` or
|
// Technically either `Vst2PluginBridge::process()` or
|
||||||
// `Vst2PluginBridge::process_replacing()` could actually call the other
|
// `Vst2PluginBridge::process_replacing()` could actually call the other
|
||||||
// function on the plugin depending on what the plugin supports.
|
// function on the plugin depending on what the plugin supports.
|
||||||
@@ -553,25 +553,25 @@ void PluginBridge::process(AEffect* /*plugin*/,
|
|||||||
logger.log_trace(" process() :: end");
|
logger.log_trace(" process() :: end");
|
||||||
}
|
}
|
||||||
|
|
||||||
void PluginBridge::process_replacing(AEffect* /*plugin*/,
|
void Vst2PluginBridge::process_replacing(AEffect* /*plugin*/,
|
||||||
float** inputs,
|
float** inputs,
|
||||||
float** outputs,
|
float** outputs,
|
||||||
int sample_frames) {
|
int sample_frames) {
|
||||||
logger.log_trace(">> processReplacing() :: start");
|
logger.log_trace(">> processReplacing() :: start");
|
||||||
do_process<float, true>(inputs, outputs, sample_frames);
|
do_process<float, true>(inputs, outputs, sample_frames);
|
||||||
logger.log_trace(" processReplacing() :: end");
|
logger.log_trace(" processReplacing() :: end");
|
||||||
}
|
}
|
||||||
|
|
||||||
void PluginBridge::process_double_replacing(AEffect* /*plugin*/,
|
void Vst2PluginBridge::process_double_replacing(AEffect* /*plugin*/,
|
||||||
double** inputs,
|
double** inputs,
|
||||||
double** outputs,
|
double** outputs,
|
||||||
int sample_frames) {
|
int sample_frames) {
|
||||||
logger.log_trace(">> processDoubleReplacing() :: start");
|
logger.log_trace(">> processDoubleReplacing() :: start");
|
||||||
do_process<double, true>(inputs, outputs, sample_frames);
|
do_process<double, true>(inputs, outputs, sample_frames);
|
||||||
logger.log_trace(" processDoubleReplacing() :: end");
|
logger.log_trace(" processDoubleReplacing() :: end");
|
||||||
}
|
}
|
||||||
|
|
||||||
float PluginBridge::get_parameter(AEffect* /*plugin*/, int index) {
|
float Vst2PluginBridge::get_parameter(AEffect* /*plugin*/, int index) {
|
||||||
logger.log_get_parameter(index);
|
logger.log_get_parameter(index);
|
||||||
|
|
||||||
const Parameter request{index, std::nullopt};
|
const Parameter request{index, std::nullopt};
|
||||||
@@ -592,7 +592,9 @@ float PluginBridge::get_parameter(AEffect* /*plugin*/, int index) {
|
|||||||
return *response.value;
|
return *response.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PluginBridge::set_parameter(AEffect* /*plugin*/, int index, float value) {
|
void Vst2PluginBridge::set_parameter(AEffect* /*plugin*/,
|
||||||
|
int index,
|
||||||
|
float value) {
|
||||||
logger.log_set_parameter(index, value);
|
logger.log_set_parameter(index, value);
|
||||||
|
|
||||||
const Parameter request{index, value};
|
const Parameter request{index, value};
|
||||||
@@ -612,7 +614,7 @@ void PluginBridge::set_parameter(AEffect* /*plugin*/, int index, float value) {
|
|||||||
assert(!response.value);
|
assert(!response.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PluginBridge::log_init_message() {
|
void Vst2PluginBridge::log_init_message() {
|
||||||
std::stringstream init_msg;
|
std::stringstream init_msg;
|
||||||
|
|
||||||
init_msg << "Initializing yabridge version " << yabridge_git_version
|
init_msg << "Initializing yabridge version " << yabridge_git_version
|
||||||
|
|||||||
@@ -29,11 +29,15 @@
|
|||||||
#include "../host-process.h"
|
#include "../host-process.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This handles the communication between the Linux native VST plugin and the
|
* This handles the communication between the Linux native VST2 plugin and the
|
||||||
* Wine VST host. The functions below should be used as callback functions in an
|
* Wine VST host. The functions below should be used as callback functions in an
|
||||||
* `AEffect` object.
|
* `AEffect` object.
|
||||||
|
*
|
||||||
|
* The naming scheme of all of these 'bridge' classes is `<type>{,Plugin}Bridge`
|
||||||
|
* for greppability reasons. The `Plugin` infix is added on the native plugin
|
||||||
|
* side.
|
||||||
*/
|
*/
|
||||||
class PluginBridge {
|
class Vst2PluginBridge {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Initializes the Wine VST bridge. This sets up the sockets for event
|
* Initializes the Wine VST bridge. This sets up the sockets for event
|
||||||
@@ -45,7 +49,7 @@ class PluginBridge {
|
|||||||
* @throw std::runtime_error Thrown when the VST host could not be found, or
|
* @throw std::runtime_error Thrown when the VST host could not be found, or
|
||||||
* if it could not locate and load a VST .dll file.
|
* if it could not locate and load a VST .dll file.
|
||||||
*/
|
*/
|
||||||
PluginBridge(audioMasterCallback host_callback);
|
Vst2PluginBridge(audioMasterCallback host_callback);
|
||||||
|
|
||||||
// The four below functions are the handlers from the VST2 API. They are
|
// The four below functions are the handlers from the VST2 API. They are
|
||||||
// called through proxy functions in `plugin.cpp`.
|
// called through proxy functions in `plugin.cpp`.
|
||||||
@@ -83,10 +87,10 @@ class PluginBridge {
|
|||||||
float** outputs,
|
float** outputs,
|
||||||
int sample_frames);
|
int sample_frames);
|
||||||
/**
|
/**
|
||||||
* The same as `PluginBridge::process_replacing`, but for double precision
|
* The same as `Vst2PluginBridge::process_replacing`, but for double
|
||||||
* audio. Support for this on both the plugin and host side is pretty rare,
|
* precision audio. Support for this on both the plugin and host side is
|
||||||
* but REAPER supports it. This reuses the same infrastructure as
|
* pretty rare, but REAPER supports it. This reuses the same infrastructure
|
||||||
* `process_replacing` is using since the host will only call one or the
|
* as `process_replacing` is using since the host will only call one or the
|
||||||
* other.
|
* other.
|
||||||
*/
|
*/
|
||||||
void process_double_replacing(AEffect* plugin,
|
void process_double_replacing(AEffect* plugin,
|
||||||
@@ -108,8 +112,8 @@ class PluginBridge {
|
|||||||
* values in `outputs`. No host will use this last behaviour anymore, but
|
* values in `outputs`. No host will use this last behaviour anymore, but
|
||||||
* it's part of the VST2.4 spec so we have to support it.
|
* it's part of the VST2.4 spec so we have to support it.
|
||||||
*
|
*
|
||||||
* @see PluginBridge::process_replacing
|
* @see Vst2PluginBridge::process_replacing
|
||||||
* @see PluginBridge::process_double_replacing
|
* @see Vst2PluginBridge::process_double_replacing
|
||||||
*/
|
*/
|
||||||
template <typename T, bool replacing>
|
template <typename T, bool replacing>
|
||||||
void do_process(T** inputs, T** outputs, int sample_frames);
|
void do_process(T** inputs, T** outputs, int sample_frames);
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ extern "C" VST_EXPORT AEffect* VSTPluginMain(
|
|||||||
// This is the only place where we have to use manual memory management.
|
// This is the only place where we have to use manual memory management.
|
||||||
// The bridge's destructor is called when the `effClose` opcode is
|
// The bridge's destructor is called when the `effClose` opcode is
|
||||||
// received.
|
// received.
|
||||||
PluginBridge* bridge = new PluginBridge(host_callback);
|
Vst2PluginBridge* bridge = new Vst2PluginBridge(host_callback);
|
||||||
|
|
||||||
return &bridge->plugin;
|
return &bridge->plugin;
|
||||||
} catch (const std::exception& error) {
|
} catch (const std::exception& error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user