clap

CLAP Audio Plugin API
Log | Files | Refs | README | LICENSE

commit 94d1c6f8bbf6cd69fcdee46922c268bc493d120e
parent 64b4349e11667096298f916805674ec3ba39e19b
Author: Alexandre BIQUE <bique.alexandre@gmail.com>
Date:   Wed,  2 Jun 2021 00:30:32 +0200

More work


Diffstat:
Mexamples/plugins/gain/gain.cc | 70+++++++++++++++++++++++++++++++++++-----------------------------------
Mexamples/plugins/gain/gain.hh | 7++-----
Mexamples/plugins/plugin.cc | 81+++++++++++++++++++++++++++++++------------------------------------------------
Mexamples/plugins/plugin.hh | 75++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
4 files changed, 129 insertions(+), 104 deletions(-)

diff --git a/examples/plugins/gain/gain.cc b/examples/plugins/gain/gain.cc @@ -27,28 +27,29 @@ namespace clap { }; Gain::Gain(const clap_host *host) : Plugin(descriptor(), host) { - parameters_.addParameter({ - .info = { - .id = kParamIdGain, - .name = "gain", - .module = "/", - .is_per_note = false, - .is_per_channel = false, - .is_used = true, - .is_periodic = false, - .is_locked = false, - .is_automatable = true, - .is_hidden = false, - .is_bypass = false, - .type = CLAP_PARAM_FLOAT, - .min_value = { .d = -120 }, - .max_value = { .d = 20 }, - .default_value = { .d = 0 }, - .enum_entry_count = 0, - }, + parameters_.addParameter(Parameter{ + .info = + clap_param_info{ + .id = kParamIdGain, + .name = "gain", + .module = "/", + .is_per_note = false, + .is_per_channel = false, + .is_used = true, + .is_periodic = false, + .is_locked = false, + .is_automatable = true, + .is_hidden = false, + .is_bypass = false, + .type = CLAP_PARAM_FLOAT, + .min_value = {.d = -120}, + .max_value = {.d = 20}, + .default_value = {.d = 0}, + .enum_entry_count = 0, + }, .enumDefinition = {}, - .value = { .d = 0 }, - .modulation = { .d = 0 }, + .value = {.d = 0}, + .modulation = {.d = 0}, }); } @@ -60,7 +61,7 @@ namespace clap { void Gain::deactivate() { channelCount_ = 0; } clap_process_status Gain::process(const clap_process *process) { - float **in = process->audio_inputs[0].data32; + float **in = process->audio_inputs[0].data32; float **out = process->audio_outputs[0].data32; float k = 1; @@ -72,19 +73,18 @@ namespace clap { return CLAP_PROCESS_CONTINUE_IF_NOT_QUIET; } - void Gain::defineAudioPorts(std::vector<clap_audio_port_info> &inputPorts, - std::vector<clap_audio_port_info> &outputPorts) { - clap_audio_port_info info; - info.id = 0; - strncpy(info.name, "main", sizeof(info.name)); - info.is_main = true; - info.is_cv = false; - info.sample_size = 32; - info.in_place = true; - info.channel_count = channelCount_; - info.channel_map = CLAP_CHMAP_UNSPECIFIED; + bool Gain::audioPortsInfo(uint32_t index, bool is_input, clap_audio_port_info *info) { + assert(index == 0); - inputPorts.push_back(info); - outputPorts.push_back(info); + info->id = 0; + strncpy(info->name, "main", sizeof(info->name)); + info->is_main = true; + info->is_cv = false; + info->sample_size = 32; + info->in_place = true; + info->channel_count = channelCount_; + info->channel_map = CLAP_CHMAP_UNSPECIFIED; + + return true; } } // namespace clap \ No newline at end of file diff --git a/examples/plugins/gain/gain.hh b/examples/plugins/gain/gain.hh @@ -16,11 +16,8 @@ namespace clap { void deactivate() override; clap_process_status process(const clap_process *process) override; - void defineAudioPorts(std::vector<clap_audio_port_info> &inputPorts, - std::vector<clap_audio_port_info> &outputPorts) override; - bool shouldInvalidateAudioPortsDefinitionOnTrackChannelChange() const override { - return true; - } + uint32_t audioPortsCount(bool is_input) override { return 2; } + bool audioPortsInfo(uint32_t index, bool is_input, clap_audio_port_info *info) override; private: int channelCount_ = 0; diff --git a/examples/plugins/plugin.cc b/examples/plugins/plugin.cc @@ -3,6 +3,7 @@ #include <iostream> #include <sstream> #include <stdexcept> +#include <utility> #include "plugin.hh" @@ -39,7 +40,6 @@ namespace clap { self.initInterfaces(); self.ensureMainThread("clap_plugin.init"); self.initTrackInfo(); - self.defineAudioPorts(self.inputAudioPorts_, self.outputAudioPorts_); return self.init(); } @@ -97,9 +97,6 @@ namespace clap { return; } - if (self.scheduleAudioPortsUpdate_) - self.updateAudioPorts(); - self.deactivate(); } @@ -165,8 +162,10 @@ namespace clap { return &self.pluginRender_; if (!strcmp(id, CLAP_EXT_TRACK_INFO)) return &pluginTrackInfo_; - if (!strcmp(id, CLAP_EXT_AUDIO_PORTS)) + if (!strcmp(id, CLAP_EXT_AUDIO_PORTS) && self.implementsAudioPorts()) return &pluginAudioPorts_; + if (!strcmp(id, CLAP_EXT_PARAMS) && self.implementsParams()) + return &pluginParams_; return from(plugin).extension(id); } @@ -193,26 +192,9 @@ namespace clap { info.channel_map != self.trackInfo_.channel_map; self.trackInfo_ = info; self.hasTrackInfo_ = true; - - if (didChannelChange && self.canChangeAudioPorts() && - self.shouldInvalidateAudioPortsDefinitionOnTrackChannelChange()) - self.invalidateAudioPortsDefinition(); - self.trackInfoChanged(); } - void Plugin::invalidateAudioPortsDefinition() { - checkMainThread(); - - if (isActive()) { - scheduleAudioPortsUpdate_ = true; - hostAudioPorts_->rescan(host_, CLAP_AUDIO_PORTS_RESCAN_ALL); - return; - } - - updateAudioPorts(); - } - void Plugin::initTrackInfo() { checkMainThread(); @@ -227,7 +209,7 @@ namespace clap { auto &self = from(plugin); self.ensureMainThread("clap_plugin_audio_ports.count"); - return is_input ? self.inputAudioPorts_.size() : self.outputAudioPorts_.size(); + return self.audioPortsCount(is_input); } bool Plugin::clapAudioPortsInfo(const clap_plugin * plugin, @@ -245,40 +227,41 @@ namespace clap { return false; } - *info = is_input ? self.inputAudioPorts_[index] : self.outputAudioPorts_[index]; - return true; + return self.audioPortsInfo(index, is_input, info); } - void Plugin::updateAudioPorts() { - checkMainThread(); - assert(!isActive()); - - scheduleAudioPortsUpdate_ = false; - - // Get the new list of ports - std::vector<clap_audio_port_info> inputs; - std::vector<clap_audio_port_info> outputs; - defineAudioPorts(inputAudioPorts_, outputAudioPorts_); + uint32_t Plugin::clapAudioPortsConfigCount(const clap_plugin *plugin) { + auto &self = from(plugin); + self.ensureMainThread("clap_plugin_audio_ports.config_count"); + return self.audioPortsConfigCount(); + } - uint32_t flags = 0; + bool Plugin::clapAudioPortsGetConfig(const clap_plugin * plugin, + uint32_t index, + clap_audio_ports_config *config) { + auto &self = from(plugin); + self.ensureMainThread("clap_plugin_audio_ports.get_config"); - if (inputs.size() != inputAudioPorts_.size() || outputs.size() != outputAudioPorts_.size()) - flags = CLAP_AUDIO_PORTS_RESCAN_ALL; - else { - for (int i = 0; i < inputs.size() && !(flags & CLAP_AUDIO_PORTS_RESCAN_ALL); ++i) - flags |= compareAudioPortsInfo(inputs[i], inputAudioPorts_[i]); - for (int i = 0; i < outputs.size() && !(flags & CLAP_AUDIO_PORTS_RESCAN_ALL); ++i) - flags |= compareAudioPortsInfo(outputs[i], outputAudioPorts_[i]); + auto count = clapAudioPortsConfigCount(plugin); + if (index >= count) { + std::ostringstream msg; + msg << "called clap_plugin_audio_ports.get_config with an index out of bounds: " << index + << " >= " << count; + self.hostMisbehaving(msg.str()); + return false; } + return self.audioPortsGetConfig(index, config); + } - if (flags == 0) - return; + bool Plugin::clapAudioPortsSetConfig(const clap_plugin *plugin, clap_id config_id) { + auto &self = from(plugin); + self.ensureMainThread("clap_plugin_audio_ports.get_config"); - // compare the list of ports to the old one - inputAudioPorts_ = inputs; - outputAudioPorts_ = outputs; + if (self.isActive()) + self.hostMisbehaving( + "it is illegal to call clap_audio_ports.set_config if the plugin is active"); - hostAudioPorts_->rescan(host_, flags); + return self.audioPortsSetConfig(config_id); } ///////////// diff --git a/examples/plugins/plugin.hh b/examples/plugins/plugin.hh @@ -39,16 +39,23 @@ namespace clap { } virtual const void *extension(const char *id) { return nullptr; } - virtual void defineAudioPorts(std::vector<clap_audio_port_info> &inputPorts, - std::vector<clap_audio_port_info> &outputPorts) {} - virtual bool shouldInvalidateAudioPortsDefinitionOnTrackChannelChange() const { - return false; - } - // clap_plugin_track_info virtual void trackInfoChanged() {} + // clap_plugin_audio_ports + virtual bool implementsAudioPorts() const noexcept { return false; } + virtual uint32_t audioPortsCount(bool is_input) { return 0; } + virtual bool audioPortsInfo(uint32_t index, bool is_input, clap_audio_port_info *info) { + return false; + } + virtual uint32_t audioPortsConfigCount() { return 0; } + virtual bool audioPortsGetConfig(uint32_t index, clap_audio_ports_config *config) { + return false; + } + virtual bool audioPortsSetConfig(clap_id config_id) { return false; } + // clap_plugin_params + virtual bool implementsParams() const noexcept { return false; } virtual uint32_t paramsCount() const { return 0; } virtual bool paramsInfo(int32_t paramIndex, clap_param_info *info) const { return false; } virtual bool paramsEnumValue(clap_id paramId, int32_t valueIndex, clap_param_value *value) { @@ -58,9 +65,13 @@ namespace clap { virtual void paramsSetValue(clap_id paramId, clap_param_value value, clap_param_value modulation) {} virtual bool - paramsValueToText(clap_id paramId, clap_param_value value, char *display, uint32_t size) { return false; } + paramsValueToText(clap_id paramId, clap_param_value value, char *display, uint32_t size) { + return false; + } virtual bool - paramsTextToValue(clap_id param_id, const char *display, clap_param_value *value) { return false; } + paramsTextToValue(clap_id param_id, const char *display, clap_param_value *value) { + return false; + } ////////////////// // Invalidation // @@ -126,7 +137,6 @@ namespace clap { protected: clap_plugin_event_filter pluginEventFilter_; clap_plugin_latency pluginLatency_; - clap_plugin_params pluginParams_; clap_plugin_render pluginRender_; clap_plugin_note_name pluginNoteName_; clap_plugin_thread_pool pluginThreadPool_; @@ -185,11 +195,50 @@ namespace clap { uint32_t index, bool is_input, clap_audio_port_info *info); - void updateAudioPorts(); + static uint32_t clapAudioPortsConfigCount(const clap_plugin *plugin); + static bool clapAudioPortsGetConfig(const clap_plugin * plugin, + uint32_t index, + clap_audio_ports_config *config); + static bool clapAudioPortsSetConfig(const clap_plugin *plugin, clap_id config_id); + // clap_plugin_params + static uint32_t clapParamsCount(const clap_plugin *plugin); + static bool + clapParamsIinfo(const clap_plugin *plugin, int32_t param_index, clap_param_info *param_info); + static bool clapParamsEnumValue(const clap_plugin *plugin, + clap_id param_id, + int32_t value_index, + clap_param_value * value); + static bool + clapParamsValue(const clap_plugin *plugin, clap_id param_id, clap_param_value *value); + static bool clapParamsSetValue(const clap_plugin *plugin, + clap_id param_id, + clap_param_value value, + clap_param_value modulation); + static bool clapParamsValueToText(const clap_plugin *plugin, + clap_id param_id, + clap_param_value value, + char * display, + uint32_t size); + static bool clapParamsTextToValue(const clap_plugin *plugin, + clap_id param_id, + const char * display, + clap_param_value * value); + + // interfaces static const constexpr clap_plugin_track_info pluginTrackInfo_ = {clapTrackInfoChanged}; static const constexpr clap_plugin_audio_ports pluginAudioPorts_ = {clapAudioPortsCount, - clapAudioPortsInfo}; + clapAudioPortsInfo, + clapAudioPortsConfigCount, + clapAudioPortsGetConfig, + clapAudioPortsSetConfig}; + static const constexpr clap_plugin_params pluginParams_ = {clapParamsCount, + clapParamsIinfo, + clapParamsEnumValue, + clapParamsValue, + clapParamsSetValue, + clapParamsValueToText, + clapParamsTextToValue}; // state bool isActive_ = false; @@ -198,9 +247,5 @@ namespace clap { bool hasTrackInfo_ = false; clap_track_info trackInfo_; - - bool scheduleAudioPortsUpdate_ = false; - std::vector<clap_audio_port_info> inputAudioPorts_; - std::vector<clap_audio_port_info> outputAudioPorts_; }; } // namespace clap \ No newline at end of file