mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-07 20:10:13 +02:00
Add CLAP audio thread callback sockets
The initialization here is a bit funky and happens in lockstep to ensure both sides are synchronized.
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <future>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include <clap/ext/audio-ports.h>
|
||||
@@ -201,6 +202,13 @@ class clap_plugin_proxy {
|
||||
*/
|
||||
ClapHostExtensions host_extensions_;
|
||||
|
||||
/**
|
||||
* A handler for receiving audio thread callbacks. Set when initializing the
|
||||
* plugin. This is needed to minimize blocking during those callbacks, as
|
||||
* certain CLAP extensions allow callbacks on the audio thread.
|
||||
*/
|
||||
std::jthread audio_thread_handler_;
|
||||
|
||||
private:
|
||||
ClapPluginBridge& bridge_;
|
||||
size_t instance_id_;
|
||||
|
||||
@@ -251,8 +251,48 @@ void ClapPluginBridge::register_plugin_proxy(
|
||||
plugin_proxies_.emplace(instance_id, std::move(plugin_proxy));
|
||||
|
||||
// For optimization reaons we use dedicated sockets for functions that will
|
||||
// be run in the audio processing loop
|
||||
sockets_.add_audio_thread_and_connect(instance_id);
|
||||
// be run in the audio processing loop.
|
||||
// Every plugin instance gets its own audio thread along with sockets for
|
||||
// host->plugin control messages and plugin->host callbacks
|
||||
std::promise<void> socket_listening_latch;
|
||||
plugin_proxies_.at(instance_id)
|
||||
->audio_thread_handler_ = std::jthread([&, instance_id]() {
|
||||
set_realtime_priority(true);
|
||||
|
||||
// XXX: Like with VST2 worker threads, when using plugin groups the
|
||||
// thread names from different plugins will clash. Not a huge
|
||||
// deal probably, since duplicate thread names are still more
|
||||
// useful than no thread names.
|
||||
const std::string thread_name = "audio-" + std::to_string(instance_id);
|
||||
pthread_setname_np(pthread_self(), thread_name.c_str());
|
||||
|
||||
// Certain CLAP extensions allow audio thread callbacks, so we need
|
||||
// a dedicated per-instance socket for that
|
||||
sockets_.add_audio_thread_and_listen_callback(
|
||||
instance_id, logger_, socket_listening_latch,
|
||||
overload{
|
||||
[&](const WantsConfiguration&) -> WantsConfiguration::Response {
|
||||
// FIXME: Without starting the variant with
|
||||
// `WantsConfiguration` you enter template deduction
|
||||
// hell. I haven't been able to figure out why.
|
||||
return {};
|
||||
},
|
||||
[&](const clap::ext::tail::host::Changed& request)
|
||||
-> clap::ext::tail::host::Changed::Response {
|
||||
// FIXME:
|
||||
// const auto& [instance, _] =
|
||||
// get_instance(request.instance_id);
|
||||
|
||||
// return instance.plugin->start_processing(
|
||||
// instance.plugin.get());
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
// Wait for the new socket to be listening on before continuing. Otherwise
|
||||
// the native plugin may try to connect to it before our thread is up and
|
||||
// running.
|
||||
socket_listening_latch.get_future().wait();
|
||||
}
|
||||
|
||||
void ClapPluginBridge::unregister_plugin_proxy(size_t instance_id) {
|
||||
|
||||
Reference in New Issue
Block a user