From a172b0ad06934a2b12496e5a966c8665127b47c8 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Mon, 22 Aug 2022 19:59:23 +0200 Subject: [PATCH] Add minimal boilerplate for a CLAP plugin --- meson.build | 35 ++++++++++++++++++++++- meson_options.txt | 7 +++++ src/plugin/clap-plugin.cpp | 57 ++++++++++++++++++++++++++++++++++++++ src/plugin/meson.build | 22 +++++++++++++++ 4 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 src/plugin/clap-plugin.cpp diff --git a/meson.build b/meson.build index bfab6361..e7ba7dc1 100644 --- a/meson.build +++ b/meson.build @@ -22,6 +22,7 @@ project( is_64bit_system = build_machine.cpu_family() not in ['x86', 'arm'] with_32bit_libraries = (not is_64bit_system) or get_option('build.cpp_args').contains('-m32') with_bitbridge = get_option('bitbridge') +with_clap = get_option('clap') with_system_asio = get_option('system-asio') with_winedbg = get_option('winedbg') with_vst3 = get_option('vst3') @@ -40,6 +41,7 @@ with_vst3 = get_option('vst3') # These variables are used to generate a `config.h` file. The library names will # be prefixed with `lib` and suffixed with `.so`, and the host names will be # suffixed with `.exe`. +clap_plugin_name = 'yabridge-clap' vst2_plugin_name = 'yabridge-vst2' vst3_plugin_name = 'yabridge-vst3' host_name_64bit = 'yabridge-host' @@ -101,6 +103,10 @@ if with_bitbridge compiler_options += '-DWITH_BITBRIDGE' endif +if with_clap + compiler_options += '-DWITH_CLAP' +endif + # This provides an easy way to start the Wine VST host using winedbg since it # can be quite a pain to set up if with_winedbg @@ -239,6 +245,10 @@ wine_shell32_dep = declare_dependency(link_args : '-lshell32') wine_threads_dep = declare_dependency(link_args : '-lpthread') wine_uuid_dep = declare_dependency(link_args : '-luuid') +if with_clap + clap_dep = dependency('clap', version : '>=1.1.1') +endif + # We need to build the VST3 SDK dependencies in tree because Meson won't let us # build both native, 32-bit cross compiled and 64-bit cross compiled # dependencies from a (CMake) subproject @@ -293,9 +303,32 @@ shared_library( override_options : ['b_lto=true'], ) +if with_clap + # This is the CLAP equivalent of `libyabridge-vst2.so`. The Wine host + # applications can handle VST2, VST3, and CLAP plugins. + shared_library( + clap_plugin_name, + clap_plugin_sources, + native : true, + include_directories : include_dir, + dependencies : clap_plugin_deps, + cpp_args : compiler_options, + ) + # TODO: Chainloader + # shared_library( + # 'yabridge-chainloader-clap', + # clap_chainloader_sources, + # native : true, + # dependencies : chainloader_deps, + # cpp_args : compiler_options + chainloader_compiler_options, + # # See above + # override_options : ['b_lto=true'], + # ) +endif + if with_vst3 # This is the VST3 equivalent of `libyabridge-vst2.so`. The Wine host - # applications can handle both VST2 and VST3 plugins. + # applications can handle both VST2, VST3 and CLAP plugins. shared_library( vst3_plugin_name, vst3_plugin_sources, diff --git a/meson_options.txt b/meson_options.txt index 69c5dfce..2dde560f 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -5,6 +5,13 @@ option( description : 'Build a 32-bit host application for hosting 32-bit plugins. See the readme for full instructions on how to use this.' ) +option( + 'clap', + type : 'boolean', + value : true, + description : 'Whether to build the CLAP version of yabridge.' +) + option( 'system-asio', type : 'boolean', diff --git a/src/plugin/clap-plugin.cpp b/src/plugin/clap-plugin.cpp new file mode 100644 index 00000000..77ba86cf --- /dev/null +++ b/src/plugin/clap-plugin.cpp @@ -0,0 +1,57 @@ +// yabridge: a Wine plugin bridge +// Copyright (C) 2020-2022 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 . + +#include + +#include + +/** + * The number of active instances. Incremented when `clap_entry_init()` is + * called, decremented when `clap_entry_exit()` is called. We'll initialize the + * bridge when this is first incremented from 0, and we'll free the bridge again + * when a `clap_entry_exit()` call causes this to return back to 0. + */ +std::atomic_size_t active_instances = 0; + +bool clap_entry_init(const char* plugin_path) { + // This function can be called multiple times, so we should make sure to + // only initialize the bridge on the first call + if (active_instances.fetch_add(1, std::memory_order_seq_cst) == 0) { + // TODO: Increase reference count, init factory if it was zero + } + + return true; +} + +void clap_entry_deinit() { + // We'll free the bridge when this exits brings the reference count back to + // zero + if (active_instances.fetch_sub(1, std::memory_order_seq_cst) == 1) { + // TODO: Destroy the bridge instance + } +} + +const void* clap_entry_get_factory(const char* factory_id) { + // TODO: Do the thing + // TODO: Assertion +} + +CLAP_EXPORT const clap_plugin_entry_t clap_entry = { + .clap_version = CLAP_VERSION_INIT, + .init = clap_entry_init, + .deinit = clap_entry_deinit, + .get_factory = clap_entry_get_factory, +}; diff --git a/src/plugin/meson.build b/src/plugin/meson.build index 96782c55..100d6553 100644 --- a/src/plugin/meson.build +++ b/src/plugin/meson.build @@ -14,6 +14,22 @@ vst2_plugin_deps = [ tomlplusplus_dep, ] +if with_clap + clap_plugin_deps = [ + configuration_dep, + + asio_dep, + bitsery_dep, + clap_dep, + dl_dep, + function2_dep, + ghc_filesystem_dep, + rt_dep, + threads_dep, + tomlplusplus_dep, + ] +endif + if with_vst3 vst3_plugin_deps = [ configuration_dep, @@ -50,6 +66,12 @@ vst2_plugin_sources = files( 'vst2-plugin.cpp', ) +if with_clap + clap_plugin_sources = files( + 'clap-plugin.cpp', + ) +endif + if with_vst3 vst3_plugin_sources = files( '../common/communication/common.cpp',