From aa586d40ee28ded9ff2302a25566ca602206d6d4 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Fri, 21 Oct 2022 17:17:50 +0200 Subject: [PATCH] Fully implement CLAP note name extension --- src/common/serialization/clap.h | 2 + src/common/serialization/clap/README.md | 2 +- src/common/serialization/clap/plugin.cpp | 4 +- src/common/serialization/clap/plugin.h | 4 +- .../bridges/clap-impls/plugin-proxy.cpp | 37 +++++++++++++++++++ src/plugin/bridges/clap-impls/plugin-proxy.h | 6 +++ src/wine-host/bridges/clap.cpp | 28 ++++++++++++++ src/wine-host/bridges/clap.h | 1 + 8 files changed, 81 insertions(+), 3 deletions(-) diff --git a/src/common/serialization/clap.h b/src/common/serialization/clap.h index 3d4e1f55..b2950ab8 100644 --- a/src/common/serialization/clap.h +++ b/src/common/serialization/clap.h @@ -79,6 +79,8 @@ using ClapMainThreadControlRequest = clap::ext::gui::plugin::Show, clap::ext::gui::plugin::Hide, clap::ext::latency::plugin::Get, + clap::ext::note_name::plugin::Count, + clap::ext::note_name::plugin::Get, clap::ext::note_ports::plugin::Count, clap::ext::note_ports::plugin::Get, clap::ext::params::plugin::Count, diff --git a/src/common/serialization/clap/README.md b/src/common/serialization/clap/README.md index 82e07ee7..6e6b59bb 100644 --- a/src/common/serialization/clap/README.md +++ b/src/common/serialization/clap/README.md @@ -23,7 +23,7 @@ Yabridge currently tracks CLAP 1.1.1. The implementation status for CLAP's core | `clap.gui` | :heavy_check_mark: Currently only does embedded GUIs | | `clap.latency` | :heavy_check_mark: | | `clap.log` | :heavy_check_mark: Always supported with or without bridging | -| `clap.note-name` | :x: Not supported yet | +| `clap.note-name` | :heavy_check_mark: | | `clap.note-ports` | :heavy_check_mark: | | `clap.params` | :heavy_check_mark: | | `clap.posix-fd-support` | :heavy_exclamation_mark: Not used by Windows plugins | diff --git a/src/common/serialization/clap/plugin.cpp b/src/common/serialization/clap/plugin.cpp index e565b720..dc22e5a4 100644 --- a/src/common/serialization/clap/plugin.cpp +++ b/src/common/serialization/clap/plugin.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -85,12 +86,13 @@ const clap_plugin_descriptor_t* Descriptor::get() const { return &clap_descriptor; } -std::array, 10> SupportedPluginExtensions::list() +std::array, 11> SupportedPluginExtensions::list() const noexcept { return {std::pair(supports_audio_ports, CLAP_EXT_AUDIO_PORTS), std::pair(supports_audio_ports_config, CLAP_EXT_AUDIO_PORTS_CONFIG), std::pair(supports_gui, CLAP_EXT_GUI), std::pair(supports_latency, CLAP_EXT_LATENCY), + std::pair(supports_note_name, CLAP_EXT_NOTE_NAME), std::pair(supports_note_ports, CLAP_EXT_NOTE_PORTS), std::pair(supports_params, CLAP_EXT_PARAMS), std::pair(supports_render, CLAP_EXT_RENDER), diff --git a/src/common/serialization/clap/plugin.h b/src/common/serialization/clap/plugin.h index 6392dcc3..2295ab15 100644 --- a/src/common/serialization/clap/plugin.h +++ b/src/common/serialization/clap/plugin.h @@ -119,6 +119,7 @@ struct SupportedPluginExtensions { bool supports_audio_ports_config = false; bool supports_gui = false; bool supports_latency = false; + bool supports_note_name = false; bool supports_note_ports = false; bool supports_params = false; bool supports_render = false; @@ -130,7 +131,7 @@ struct SupportedPluginExtensions { * Get a list of `` tuples for the supported * extensions. Used during logging. */ - std::array, 10> list() const noexcept; + std::array, 11> list() const noexcept; template void serialize(S& s) { @@ -138,6 +139,7 @@ struct SupportedPluginExtensions { s.value1b(supports_audio_ports_config); s.value1b(supports_gui); s.value1b(supports_latency); + s.value1b(supports_note_name); s.value1b(supports_note_ports); s.value1b(supports_params); s.value1b(supports_render); diff --git a/src/plugin/bridges/clap-impls/plugin-proxy.cpp b/src/plugin/bridges/clap-impls/plugin-proxy.cpp index 90228034..bbf1fa4b 100644 --- a/src/plugin/bridges/clap-impls/plugin-proxy.cpp +++ b/src/plugin/bridges/clap-impls/plugin-proxy.cpp @@ -111,6 +111,10 @@ clap_plugin_proxy::clap_plugin_proxy(ClapPluginBridge& bridge, ext_latency_vtable(clap_plugin_latency_t{ .get = ext_latency_get, }), + ext_note_name_vtable(clap_plugin_note_name_t{ + .count = ext_note_name_count, + .get = ext_note_name_get, + }), ext_note_ports_vtable(clap_plugin_note_ports_t{ .count = ext_note_ports_count, .get = ext_note_ports_get, @@ -322,6 +326,9 @@ clap_plugin_proxy::plugin_get_extension(const struct clap_plugin* plugin, } else if (self->supported_extensions_.supports_latency && strcmp(id, CLAP_EXT_LATENCY) == 0) { extension_ptr = &self->ext_latency_vtable; + } else if (self->supported_extensions_.supports_note_name && + strcmp(id, CLAP_EXT_NOTE_NAME) == 0) { + extension_ptr = &self->ext_note_name_vtable; } else if (self->supported_extensions_.supports_note_ports && strcmp(id, CLAP_EXT_NOTE_PORTS) == 0) { extension_ptr = &self->ext_note_ports_vtable; @@ -641,6 +648,36 @@ clap_plugin_proxy::ext_latency_get(const clap_plugin_t* plugin) { clap::ext::latency::plugin::Get{.instance_id = self->instance_id()}); } +uint32_t CLAP_ABI +clap_plugin_proxy::ext_note_name_count(const clap_plugin_t* plugin) { + assert(plugin && plugin->plugin_data); + auto self = static_cast(plugin->plugin_data); + + return self->bridge_.send_main_thread_message( + clap::ext::note_name::plugin::Count{.instance_id = + self->instance_id()}); +} + +bool CLAP_ABI +clap_plugin_proxy::ext_note_name_get(const clap_plugin_t* plugin, + uint32_t index, + clap_note_name_t* note_name) { + assert(plugin && plugin->plugin_data && note_name); + auto self = static_cast(plugin->plugin_data); + + const clap::ext::note_name::plugin::GetResponse response = + self->bridge_.send_main_thread_message( + clap::ext::note_name::plugin::Get{ + .instance_id = self->instance_id(), .index = index}); + if (response.result) { + response.result->reconstruct(*note_name); + + return true; + } else { + return false; + } +} + uint32_t CLAP_ABI clap_plugin_proxy::ext_note_ports_count(const clap_plugin_t* plugin, bool is_input) { diff --git a/src/plugin/bridges/clap-impls/plugin-proxy.h b/src/plugin/bridges/clap-impls/plugin-proxy.h index e7819120..b941c0df 100644 --- a/src/plugin/bridges/clap-impls/plugin-proxy.h +++ b/src/plugin/bridges/clap-impls/plugin-proxy.h @@ -246,6 +246,11 @@ class clap_plugin_proxy { static uint32_t CLAP_ABI ext_latency_get(const clap_plugin_t* plugin); + static uint32_t CLAP_ABI ext_note_name_count(const clap_plugin_t* plugin); + static bool CLAP_ABI ext_note_name_get(const clap_plugin_t* plugin, + uint32_t index, + clap_note_name_t* note_name); + static uint32_t CLAP_ABI ext_note_ports_count(const clap_plugin_t* plugin, bool is_input); static bool CLAP_ABI ext_note_ports_get(const clap_plugin_t* plugin, @@ -348,6 +353,7 @@ class clap_plugin_proxy { const clap_plugin_audio_ports_config_t ext_audio_ports_config_vtable; const clap_plugin_gui_t ext_gui_vtable; const clap_plugin_latency_t ext_latency_vtable; + const clap_plugin_note_name_t ext_note_name_vtable; const clap_plugin_note_ports_t ext_note_ports_vtable; const clap_plugin_params_t ext_params_vtable; const clap_plugin_render_t ext_render_vtable; diff --git a/src/wine-host/bridges/clap.cpp b/src/wine-host/bridges/clap.cpp index 7bd421da..d5f9033e 100644 --- a/src/wine-host/bridges/clap.cpp +++ b/src/wine-host/bridges/clap.cpp @@ -35,6 +35,8 @@ ClapPluginExtensions::ClapPluginExtensions(const clap_plugin& plugin) noexcept plugin.get_extension(&plugin, CLAP_EXT_GUI))), latency(static_cast( plugin.get_extension(&plugin, CLAP_EXT_LATENCY))), + note_name(static_cast( + plugin.get_extension(&plugin, CLAP_EXT_NOTE_NAME))), note_ports(static_cast( plugin.get_extension(&plugin, CLAP_EXT_NOTE_PORTS))), params(static_cast( @@ -57,6 +59,7 @@ clap::plugin::SupportedPluginExtensions ClapPluginExtensions::supported() .supports_audio_ports_config = audio_ports_config != nullptr, .supports_gui = gui != nullptr, .supports_latency = latency != nullptr, + .supports_note_name = note_name != nullptr, .supports_note_ports = note_ports != nullptr, .supports_params = params != nullptr, .supports_render = render != nullptr, @@ -660,6 +663,31 @@ void ClapBridge::run() { // to avoid the synchronisation costs in hot code paths return instance.extensions.latency->get(instance.plugin.get()); }, + [&](const clap::ext::note_name::plugin::Count& request) + -> clap::ext::note_name::plugin::Count::Response { + const auto& [instance, _] = get_instance(request.instance_id); + + // We'll ignore the main thread requirement for simple array + // lookups to avoid the synchronisation costs in hot code paths + return instance.extensions.note_name->count( + instance.plugin.get()); + }, + [&](const clap::ext::note_name::plugin::Get& request) + -> clap::ext::note_name::plugin::Get::Response { + const auto& [instance, _] = get_instance(request.instance_id); + + // We'll ignore the main thread requirement for simple array + // lookups to avoid the synchronisation costs in hot code paths + clap_note_name_t note_name{}; + if (instance.extensions.note_name->get( + instance.plugin.get(), request.index, ¬e_name)) { + return clap::ext::note_name::plugin::GetResponse{ + .result = note_name}; + } else { + return clap::ext::note_name::plugin::GetResponse{ + .result = std::nullopt}; + } + }, [&](const clap::ext::note_ports::plugin::Count& request) -> clap::ext::note_ports::plugin::Count::Response { const auto& [instance, _] = get_instance(request.instance_id); diff --git a/src/wine-host/bridges/clap.h b/src/wine-host/bridges/clap.h index cbc208c0..36382e2f 100644 --- a/src/wine-host/bridges/clap.h +++ b/src/wine-host/bridges/clap.h @@ -70,6 +70,7 @@ struct ClapPluginExtensions { const clap_plugin_audio_ports_config_t* audio_ports_config = nullptr; const clap_plugin_gui_t* gui = nullptr; const clap_plugin_latency_t* latency = nullptr; + const clap_plugin_note_name_t* note_name = nullptr; const clap_plugin_note_ports_t* note_ports = nullptr; const clap_plugin_params_t* params = nullptr; const clap_plugin_render_t* render = nullptr;