From 726b664d87b55a4efa959dedd219f8bacca9017c Mon Sep 17 00:00:00 2001 From: David Schornsheim <6382400+Schroedingers-Cat@users.noreply.github.com> Date: Mon, 6 May 2024 14:03:57 +0200 Subject: [PATCH 1/5] Add base implementation of configurable audio ports extension --- include/clap/helpers/plugin.hh | 30 +++++++++++ include/clap/helpers/plugin.hxx | 88 +++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) diff --git a/include/clap/helpers/plugin.hh b/include/clap/helpers/plugin.hh index 6e71e16..b646f1d 100644 --- a/include/clap/helpers/plugin.hh +++ b/include/clap/helpers/plugin.hh @@ -150,6 +150,22 @@ namespace clap { namespace helpers { return false; } + //--------------------------------------// + // clap_plugin_configurable_audio_ports // + //--------------------------------------// + virtual bool implementsConfigurableAudioPorts() const noexcept { return false; } + virtual bool configurableAudioPortsCanApplyConfiguration(const clap_audio_port_configuration_request *requests, + uint32_t request_count) const noexcept { + return false; + } + virtual bool configurableAudioPortsApplyConfiguration(const clap_audio_port_configuration_request *requests, + uint32_t request_count) noexcept { + return false; + } + void ensureClapAudioPortConfigurationRequestIsValid( + const clap_audio_port_configuration_request *requests, + uint32_t request_count); + //--------------------// // clap_plugin_params // //--------------------// @@ -315,6 +331,11 @@ namespace clap { namespace helpers { void ensureAudioThread(const char *method) const noexcept; void ensureParamThread(const char *method) const noexcept; + //////////////////// + // General Checks // + //////////////////// + void ensureIsInactive(const char *methodName) const noexcept; + /////////////// // Utilities // /////////////// @@ -427,6 +448,14 @@ namespace clap { namespace helpers { bool is_active, uint32_t sample_size) noexcept; + // clap_plugin_configurable_audio_ports + static bool clapConfigurableAudioPortsCanApplyConfiguration(const clap_plugin_t *plugin, + const clap_audio_port_configuration_request *requests, + uint32_t request_count) noexcept; + static bool clapConfigurableAudioPortsApplyActivation(const clap_plugin_t *plugin, + const clap_audio_port_configuration_request *requests, + uint32_t request_count) noexcept; + // clap_plugin_params static uint32_t clapParamsCount(const clap_plugin *plugin) noexcept; static bool clapParamsInfo(const clap_plugin *plugin, @@ -552,6 +581,7 @@ namespace clap { namespace helpers { static const clap_plugin_audio_ports _pluginAudioPorts; static const clap_plugin_audio_ports_config _pluginAudioPortsConfig; static const clap_plugin_audio_ports_activation _pluginAudioPortsActivation; + static const clap_plugin_configurable_audio_ports _pluginConfigurableAudioPorts; static const clap_plugin_gui _pluginGui; static const clap_plugin_latency _pluginLatency; static const clap_plugin_note_name _pluginNoteName; diff --git a/include/clap/helpers/plugin.hxx b/include/clap/helpers/plugin.hxx index be29ec5..42f1b50 100644 --- a/include/clap/helpers/plugin.hxx +++ b/include/clap/helpers/plugin.hxx @@ -61,6 +61,13 @@ namespace clap { namespace helpers { clapAudioPortsActivationSetActive, }; + template + const clap_plugin_configurable_audio_ports Plugin::_pluginConfigurableAudioPorts = { + clapConfigurableAudioPortsCanApplyConfiguration, + clapConfigurableAudioPortsApplyActivation, + }; + + template const clap_plugin_params Plugin::_pluginParams = { clapParamsCount, @@ -472,6 +479,8 @@ namespace clap { namespace helpers { return &_pluginAudioPortsActivation; if (!strcmp(id, CLAP_EXT_AUDIO_PORTS_CONFIG) && self.implementsAudioPortsConfig()) return &_pluginAudioPortsConfig; + if (!strcmp(id, CLAP_EXT_CONFIGURABLE_AUDIO_PORTS) && self.implementsConfigurableAudioPorts()) + return &_pluginConfigurableAudioPorts; if (!strcmp(id, CLAP_EXT_PARAMS) && self.implementsParams()) return &_pluginParams; if ((!strcmp(id, CLAP_EXT_PARAM_INDICATION) || @@ -791,6 +800,69 @@ namespace clap { namespace helpers { return self.paramsCount(); } + //--------------------------------------// + // clap_plugin_configurable_audio_ports // + //--------------------------------------// + + template + bool Plugin::clapConfigurableAudioPortsCanApplyConfiguration( + const clap_plugin_t *plugin, + const clap_audio_port_configuration_request *requests, + uint32_t request_count) noexcept { + auto &self = from(plugin); + auto methodName = "clap_plugin_configurable_audio_ports.can_apply_configuration"; + self.ensureMainThread(methodName); + self.ensureIsInactive(methodName); + self.ensureClapAudioPortConfigurationRequestIsValid(requests, request_count); + + return self.configurableAudioPortsCanApplyConfiguration(requests, request_count); + } + + template + bool Plugin::clapConfigurableAudioPortsApplyActivation( + const clap_plugin_t *plugin, + const clap_audio_port_configuration_request *requests, + uint32_t request_count) noexcept { + auto &self = from(plugin); + auto methodName = "clap_plugin_configurable_audio_ports.apply_configuration"; + self.ensureMainThread(methodName); + self.ensureIsInactive(methodName); + self.ensureClapAudioPortConfigurationRequestIsValid(requests, request_count); + + if (l >= CheckingLevel::Minimal && + !self.configurableAudioPortsCanApplyConfiguration(requests, request_count)) { + self.hostMisbehaving( + "Host requested a configuration that the plugin did not accept. Check with " + "clap_plugin_configurable_audio_ports.can_apply_configuration before applying a " + "configuration!"); + } + + return self.configurableAudioPortsApplyConfiguration(requests, request_count); + } + + template + void Plugin::ensureClapAudioPortConfigurationRequestIsValid( + const clap_audio_port_configuration_request *requests, + uint32_t request_count) { + if (l == CheckingLevel::None) + return; + + for (int i = 0; i < request_count; ++i) { + if (!requests[i].port_type) + continue; + + if (strcmp(requests[i].port_type, CLAP_PORT_MONO) == 0 && requests[i].channel_count != 1) { + hostMisbehaving("Host requested a mono port type with a channel count other than one."); + } else if (strcmp(requests[i].port_type, CLAP_PORT_STEREO) == 0 && requests[i].channel_count != 2) { + hostMisbehaving("Host requested a stereo port type with a channel count other than two."); + } else if (strcmp(requests[i].port_type, CLAP_PORT_SURROUND) == 0 && requests[i].channel_count < 3) { + hostMisbehaving("Host requested a surround port type with insufficient channel count."); + } else if (strcmp(requests[i].port_type, CLAP_PORT_AMBISONIC) == 0 && requests[i].channel_count < 4) { + hostMisbehaving("Host requested an ambisonic port type with insufficient channel count."); + } + } + } + //--------------------// // clap_plugin_params // //--------------------// @@ -1793,6 +1865,22 @@ namespace clap { namespace helpers { hostMisbehaving(msg.str()); } + //////////////////// + // General Checks // + //////////////////// + template + void Plugin::ensureIsInactive(const char *methodName) const noexcept { + if (l == CheckingLevel::None) + return; + + if (!isActive()) + return; + + std::ostringstream msg; + msg << "it is illegal to call " << methodName << "() while the plugin is active!"; + hostMisbehaving(msg.str()); + } + /////////////// // Utilities // /////////////// From 3233704aab7b8912333276a602c439b7877df4f7 Mon Sep 17 00:00:00 2001 From: David Schornsheim <6382400+Schroedingers-Cat@users.noreply.github.com> Date: Mon, 17 Jun 2024 14:59:02 +0200 Subject: [PATCH 2/5] Remove ensureClapAudioPortConfigurationRequestIsValid --- include/clap/helpers/plugin.hh | 3 --- include/clap/helpers/plugin.hxx | 21 --------------------- 2 files changed, 24 deletions(-) diff --git a/include/clap/helpers/plugin.hh b/include/clap/helpers/plugin.hh index b646f1d..485fd3b 100644 --- a/include/clap/helpers/plugin.hh +++ b/include/clap/helpers/plugin.hh @@ -162,9 +162,6 @@ namespace clap { namespace helpers { uint32_t request_count) noexcept { return false; } - void ensureClapAudioPortConfigurationRequestIsValid( - const clap_audio_port_configuration_request *requests, - uint32_t request_count); //--------------------// // clap_plugin_params // diff --git a/include/clap/helpers/plugin.hxx b/include/clap/helpers/plugin.hxx index 42f1b50..5c40b96 100644 --- a/include/clap/helpers/plugin.hxx +++ b/include/clap/helpers/plugin.hxx @@ -813,7 +813,6 @@ namespace clap { namespace helpers { auto methodName = "clap_plugin_configurable_audio_ports.can_apply_configuration"; self.ensureMainThread(methodName); self.ensureIsInactive(methodName); - self.ensureClapAudioPortConfigurationRequestIsValid(requests, request_count); return self.configurableAudioPortsCanApplyConfiguration(requests, request_count); } @@ -827,8 +826,6 @@ namespace clap { namespace helpers { auto methodName = "clap_plugin_configurable_audio_ports.apply_configuration"; self.ensureMainThread(methodName); self.ensureIsInactive(methodName); - self.ensureClapAudioPortConfigurationRequestIsValid(requests, request_count); - if (l >= CheckingLevel::Minimal && !self.configurableAudioPortsCanApplyConfiguration(requests, request_count)) { self.hostMisbehaving( @@ -840,26 +837,8 @@ namespace clap { namespace helpers { return self.configurableAudioPortsApplyConfiguration(requests, request_count); } - template - void Plugin::ensureClapAudioPortConfigurationRequestIsValid( - const clap_audio_port_configuration_request *requests, - uint32_t request_count) { - if (l == CheckingLevel::None) - return; - for (int i = 0; i < request_count; ++i) { - if (!requests[i].port_type) - continue; - if (strcmp(requests[i].port_type, CLAP_PORT_MONO) == 0 && requests[i].channel_count != 1) { - hostMisbehaving("Host requested a mono port type with a channel count other than one."); - } else if (strcmp(requests[i].port_type, CLAP_PORT_STEREO) == 0 && requests[i].channel_count != 2) { - hostMisbehaving("Host requested a stereo port type with a channel count other than two."); - } else if (strcmp(requests[i].port_type, CLAP_PORT_SURROUND) == 0 && requests[i].channel_count < 3) { - hostMisbehaving("Host requested a surround port type with insufficient channel count."); - } else if (strcmp(requests[i].port_type, CLAP_PORT_AMBISONIC) == 0 && requests[i].channel_count < 4) { - hostMisbehaving("Host requested an ambisonic port type with insufficient channel count."); - } } } From 850707951f3ea0a029c593257f254558f5595a59 Mon Sep 17 00:00:00 2001 From: David Schornsheim <6382400+Schroedingers-Cat@users.noreply.github.com> Date: Mon, 17 Jun 2024 15:03:59 +0200 Subject: [PATCH 3/5] Use correct name --- include/clap/helpers/plugin.hh | 6 +++--- include/clap/helpers/plugin.hxx | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/clap/helpers/plugin.hh b/include/clap/helpers/plugin.hh index 485fd3b..0c2cb39 100644 --- a/include/clap/helpers/plugin.hh +++ b/include/clap/helpers/plugin.hh @@ -449,9 +449,9 @@ namespace clap { namespace helpers { static bool clapConfigurableAudioPortsCanApplyConfiguration(const clap_plugin_t *plugin, const clap_audio_port_configuration_request *requests, uint32_t request_count) noexcept; - static bool clapConfigurableAudioPortsApplyActivation(const clap_plugin_t *plugin, - const clap_audio_port_configuration_request *requests, - uint32_t request_count) noexcept; + static bool clapConfigurableAudioPortsApplyConfiguration(const clap_plugin_t *plugin, + const clap_audio_port_configuration_request *requests, + uint32_t request_count) noexcept; // clap_plugin_params static uint32_t clapParamsCount(const clap_plugin *plugin) noexcept; diff --git a/include/clap/helpers/plugin.hxx b/include/clap/helpers/plugin.hxx index 5c40b96..8e29db9 100644 --- a/include/clap/helpers/plugin.hxx +++ b/include/clap/helpers/plugin.hxx @@ -64,7 +64,7 @@ namespace clap { namespace helpers { template const clap_plugin_configurable_audio_ports Plugin::_pluginConfigurableAudioPorts = { clapConfigurableAudioPortsCanApplyConfiguration, - clapConfigurableAudioPortsApplyActivation, + clapConfigurableAudioPortsApplyConfiguration, }; @@ -818,7 +818,7 @@ namespace clap { namespace helpers { } template - bool Plugin::clapConfigurableAudioPortsApplyActivation( + bool Plugin::clapConfigurableAudioPortsApplyConfiguration( const clap_plugin_t *plugin, const clap_audio_port_configuration_request *requests, uint32_t request_count) noexcept { From fe1d73c31b6677744dfd166b8ec9e84d2e6863ba Mon Sep 17 00:00:00 2001 From: David Schornsheim <6382400+Schroedingers-Cat@users.noreply.github.com> Date: Mon, 17 Jun 2024 15:04:39 +0200 Subject: [PATCH 4/5] Add ensureIsActive --- include/clap/helpers/plugin.hh | 1 + include/clap/helpers/plugin.hxx | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/include/clap/helpers/plugin.hh b/include/clap/helpers/plugin.hh index 0c2cb39..22be257 100644 --- a/include/clap/helpers/plugin.hh +++ b/include/clap/helpers/plugin.hh @@ -332,6 +332,7 @@ namespace clap { namespace helpers { // General Checks // //////////////////// void ensureIsInactive(const char *methodName) const noexcept; + void ensureIsActive(const char *methodName) const noexcept; /////////////// // Utilities // diff --git a/include/clap/helpers/plugin.hxx b/include/clap/helpers/plugin.hxx index 8e29db9..33a15ab 100644 --- a/include/clap/helpers/plugin.hxx +++ b/include/clap/helpers/plugin.hxx @@ -1860,6 +1860,19 @@ namespace clap { namespace helpers { hostMisbehaving(msg.str()); } + template + void Plugin::ensureIsActive(const char *methodName) const noexcept { + if (l == CheckingLevel::None) + return; + + if (isActive()) + return; + + std::ostringstream msg; + msg << "it is illegal to call " << methodName << "() while the plugin is not active!"; + hostMisbehaving(msg.str()); + } + /////////////// // Utilities // /////////////// From cccc104dc69502072b9fcf5528ae1fbed3bffb55 Mon Sep 17 00:00:00 2001 From: David Schornsheim <6382400+Schroedingers-Cat@users.noreply.github.com> Date: Mon, 17 Jun 2024 15:14:06 +0200 Subject: [PATCH 5/5] Rewrite applyConfiguration check --- include/clap/helpers/plugin.hxx | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/include/clap/helpers/plugin.hxx b/include/clap/helpers/plugin.hxx index 33a15ab..c9b4f56 100644 --- a/include/clap/helpers/plugin.hxx +++ b/include/clap/helpers/plugin.hxx @@ -826,20 +826,24 @@ namespace clap { namespace helpers { auto methodName = "clap_plugin_configurable_audio_ports.apply_configuration"; self.ensureMainThread(methodName); self.ensureIsInactive(methodName); - if (l >= CheckingLevel::Minimal && - !self.configurableAudioPortsCanApplyConfiguration(requests, request_count)) { - self.hostMisbehaving( - "Host requested a configuration that the plugin did not accept. Check with " - "clap_plugin_configurable_audio_ports.can_apply_configuration before applying a " - "configuration!"); - } - - return self.configurableAudioPortsApplyConfiguration(requests, request_count); - } + bool canApplyConfiguration; + if (l >= CheckingLevel::Minimal) { + canApplyConfiguration = + self.configurableAudioPortsCanApplyConfiguration(requests, request_count); + } + bool applyConfigurationSuccess = + self.configurableAudioPortsApplyConfiguration(requests, request_count); + if (l >= CheckingLevel::Minimal && canApplyConfiguration != applyConfigurationSuccess) { + self._host.pluginMisbehaving( + "Plugin's functions clap_plugin_configurable_audio_ports.can_apply_configuration and " + "clap_plugin_configurable_audio_ports.apply_configuration returned different values " + "for the same configuration."); } + + return applyConfigurationSuccess; } //--------------------//