diff --git a/include/clap/helpers/plugin.hh b/include/clap/helpers/plugin.hh index 6e71e16..22be257 100644 --- a/include/clap/helpers/plugin.hh +++ b/include/clap/helpers/plugin.hh @@ -150,6 +150,19 @@ 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; + } + //--------------------// // clap_plugin_params // //--------------------// @@ -315,6 +328,12 @@ 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; + void ensureIsActive(const char *methodName) const noexcept; + /////////////// // Utilities // /////////////// @@ -427,6 +446,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 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; static bool clapParamsInfo(const clap_plugin *plugin, @@ -552,6 +579,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..c9b4f56 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, + clapConfigurableAudioPortsApplyConfiguration, + }; + + 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,52 @@ 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); + + return self.configurableAudioPortsCanApplyConfiguration(requests, request_count); + } + + template + bool Plugin::clapConfigurableAudioPortsApplyConfiguration( + 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); + + 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; + } + //--------------------// // clap_plugin_params // //--------------------// @@ -1793,6 +1848,35 @@ 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()); + } + + 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 // ///////////////