clap

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

commit 5c6c94f271aa8c88e313af7b96d0f17e07fdad89
parent 6efc21314a5abb32d7306b61d9da256c727cfff5
Author: Alexandre BIQUE <bique.alexandre@gmail.com>
Date:   Sun,  6 Jun 2021 21:47:26 +0200

More work

Diffstat:
Mexamples/.clang-format | 4++--
Mexamples/plugins/CMakeLists.txt | 2++
Aexamples/plugins/abstract-gui.hh | 25+++++++++++++++++++++++++
Mexamples/plugins/gain/gain.cc | 91+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Mexamples/plugins/gain/gain.hh | 23++++++++++++-----------
Aexamples/plugins/plugin-helper.cc | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aexamples/plugins/plugin-helper.hh | 102+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mexamples/plugins/plugin.cc | 333+++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
Mexamples/plugins/plugin.hh | 361++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Minclude/clap/ext/draft/key-name.h | 4++--
Minclude/clap/ext/draft/preset-load.h | 2+-
Minclude/clap/ext/render.h | 2+-
Minclude/clap/ext/state.h | 7+++++--
13 files changed, 704 insertions(+), 309 deletions(-)

diff --git a/examples/.clang-format b/examples/.clang-format @@ -3,8 +3,8 @@ Language: Cpp AccessModifierOffset: -3 AlignAfterOpenBracket: Align AlignConsecutiveMacros: true -AlignConsecutiveAssignments: true -AlignConsecutiveDeclarations: true +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false AlignEscapedNewlines: Right AlignOperands: true AlignTrailingComments: true diff --git a/examples/plugins/CMakeLists.txt b/examples/plugins/CMakeLists.txt @@ -5,6 +5,8 @@ add_library( parameters.hh plugin.cc plugin.hh + plugin-helper.cc + plugin-helper.hh gain/gain.hh gain/gain.cc) diff --git a/examples/plugins/abstract-gui.hh b/examples/plugins/abstract-gui.hh @@ -0,0 +1,24 @@ +#pragma once + +#include <clap/all.h> + +namespace clap { + + class AbstractGui { + public: + virtual ~AbstractGui(); + + virtual bool attach(void *nsView) noexcept = 0; + virtual bool attachWin32(clap_hwnd window) noexcept = 0; + virtual bool attachX11(const char *display_name, unsigned long window) noexcept = 0; + + virtual void size(int32_t *width, int32_t *height) noexcept = 0; + virtual void setScale(double scale) noexcept = 0; + + virtual bool show() noexcept = 0; + virtual bool hide() noexcept = 0; + + virtual void close() noexcept = 0; + }; + +} // namespace clap +\ No newline at end of file diff --git a/examples/plugins/gain/gain.cc b/examples/plugins/gain/gain.cc @@ -26,42 +26,70 @@ namespace clap { kParamIdGain = 0, }; - Gain::Gain(const clap_host *host) : Plugin(descriptor(), host) { - parameters_.addParameter(Parameter{ + Gain::Gain(const clap_host *host) : PluginHelper(descriptor(), host) { + parameters_.addParameter({ .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}, + { + .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}, }); } - bool Gain::activate(int sample_rate) { + bool Gain::init() noexcept { + if (!super::init()) + return false; + + defineAudioPorts(); + return true; + } + + void Gain::defineAudioPorts() noexcept { + assert(!isActive()); + channelCount_ = trackChannelCount(); + + 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; + + audioInputs_.clear(); + audioInputs_.push_back(info); + audioOutputs_.clear(); + audioOutputs_.push_back(info); + } + + bool Gain::activate(int sample_rate) noexcept { return true; } - void Gain::deactivate() { channelCount_ = 0; } + void Gain::deactivate() noexcept { channelCount_ = 0; } - clap_process_status Gain::process(const clap_process *process) { - float **in = process->audio_inputs[0].data32; + clap_process_status Gain::process(const clap_process *process) noexcept { + float **in = process->audio_inputs[0].data32; float **out = process->audio_outputs[0].data32; float k = 1; @@ -72,19 +100,4 @@ namespace clap { return CLAP_PROCESS_CONTINUE_IF_NOT_QUIET; } - - bool Gain::audioPortsInfo(uint32_t index, bool is_input, clap_audio_port_info *info) { - assert(index == 0); - - 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 @@ -2,26 +2,27 @@ #include <clap/all.h> -#include "../plugin.hh" +#include "../plugin-helper.hh" namespace clap { - class Gain final : public Plugin { + class Gain final : public PluginHelper { + private: + using super = PluginHelper; + public: Gain(const clap_host *host); static const clap_plugin_descriptor *descriptor(); protected: - bool activate(int sample_rate) override; - void deactivate() override; - clap_process_status process(const clap_process *process) override; - - uint32_t audioPortsCount(bool is_input) override { return 2; } - bool audioPortsInfo(uint32_t index, bool is_input, clap_audio_port_info *info) override; + // clap_plugin + bool init() noexcept override; + void defineAudioPorts() noexcept; + bool activate(int sample_rate) noexcept override; + void deactivate() noexcept override; + clap_process_status process(const clap_process *process) noexcept override; private: - int channelCount_ = 0; - - Parameters parameters_; + int channelCount_ = 1; }; } // namespace clap \ No newline at end of file diff --git a/examples/plugins/plugin-helper.cc b/examples/plugins/plugin-helper.cc @@ -0,0 +1,56 @@ +#include "plugin-helper.hh" + +namespace clap { + + PluginHelper::PluginHelper(const clap_plugin_descriptor *desc, const clap_host *host) + : Plugin(desc, host) {} + + bool PluginHelper::init() noexcept { + initTrackInfo(); + return true; + } + + void PluginHelper::initTrackInfo() noexcept { + checkMainThread(); + + assert(!hasTrackInfo_); + if (!canUseTrackInfo()) + return; + + hasTrackInfo_ = hostTrackInfo_->get(host_, &trackInfo_); + } + + void PluginHelper::trackInfoChanged() noexcept { + if (!hostTrackInfo_->get(host_, &trackInfo_)) { + hasTrackInfo_ = false; + hostMisbehaving( + "clap_host_track_info.get() failed after calling clap_plugin_track_info.changed()"); + return; + } + + hasTrackInfo_ = true; + } + + bool PluginHelper::implementsAudioPorts() const noexcept { return true; } + + uint32_t PluginHelper::audioPortsCount(bool is_input) const noexcept { + return is_input ? audioInputs_.size() : audioOutputs_.size(); + } + + bool PluginHelper::audioPortsInfo(uint32_t index, + bool is_input, + clap_audio_port_info *info) const noexcept { + *info = is_input ? audioInputs_[index] : audioOutputs_[index]; + return true; + } + + uint32_t PluginHelper::audioPortsConfigCount() const noexcept { return audioConfigs_.size(); } + + bool PluginHelper::audioPortsGetConfig(uint32_t index, + clap_audio_ports_config *config) const noexcept { + *config = audioConfigs_[index]; + return true; + } + + bool PluginHelper::audioPortsSetConfig(clap_id config_id) noexcept { return false; } +} // namespace clap +\ No newline at end of file diff --git a/examples/plugins/plugin-helper.hh b/examples/plugins/plugin-helper.hh @@ -0,0 +1,101 @@ +#pragma once + +#include "plugin.hh" + +namespace clap { + class PluginHelper : public Plugin { + public: + PluginHelper(const clap_plugin_descriptor *desc, const clap_host *host); + + protected: + // clap_plugin + bool init() noexcept override; + void initTrackInfo() noexcept; + + // clap_plugin_track_info + bool implementsTrackInfo() const noexcept override { return true; } + void trackInfoChanged() noexcept override; + + // clap_plugin_audio_ports + bool implementsAudioPorts() const noexcept override; + uint32_t audioPortsCount(bool is_input) const noexcept override; + bool audioPortsInfo(uint32_t index, + bool is_input, + clap_audio_port_info *info) const noexcept override; + uint32_t audioPortsConfigCount() const noexcept override; + bool audioPortsGetConfig(uint32_t index, + clap_audio_ports_config *config) const noexcept override; + bool audioPortsSetConfig(clap_id config_id) noexcept override; + + // clap_plugin_params + bool implementsParams() const noexcept override { return true; } + + uint32_t paramsCount() const noexcept override { return parameters_.count(); } + + bool paramsInfo(int32_t paramIndex, clap_param_info *info) const noexcept override { + *info = parameters_.getByIndex(paramIndex)->info; + return true; + } + + bool paramsEnumValue(clap_id paramId, + int32_t valueIndex, + clap_param_value *value) noexcept override { + value->i = parameters_.getById(paramId)->enumDefinition.entries[valueIndex].value; + return true; + } + + virtual bool paramsValue(clap_id paramId, clap_param_value *value) noexcept override { + *value = parameters_.getById(paramId)->value; + return true; + } + + virtual bool paramsSetValue(clap_id paramId, + clap_param_value value, + clap_param_value modulation) noexcept override { + auto p = parameters_.getById(paramId); + p->value = value; + p->modulation = modulation; + return false; + } + + virtual bool paramsValueToText(clap_id paramId, + clap_param_value value, + char *display, + uint32_t size) noexcept override { + // TODO + return false; + } + + virtual bool paramsTextToValue(clap_id param_id, + const char *display, + clap_param_value *value) noexcept override { + // TODO + return false; + } + + ////////////////////// + // Cached Host Info // + ////////////////////// + bool hasTrackInfo() const noexcept { return hasTrackInfo_; } + const clap_track_info &trackInfo() const noexcept { + assert(hasTrackInfo_); + return trackInfo_; + } + uint32_t trackChannelCount() const noexcept { + return hasTrackInfo_ ? trackInfo_.channel_count : 2; + } + clap_chmap trackChannelMap() const noexcept { + return hasTrackInfo_ ? trackInfo_.channel_map : CLAP_CHMAP_STEREO; + } + + protected: + bool hasTrackInfo_ = false; + clap_track_info trackInfo_; + + std::vector<clap_audio_port_info> audioInputs_; + std::vector<clap_audio_port_info> audioOutputs_; + std::vector<clap_audio_ports_config> audioConfigs_; + + Parameters parameters_; + }; +} // namespace clap +\ No newline at end of file diff --git a/examples/plugins/plugin.cc b/examples/plugins/plugin.cc @@ -1,5 +1,6 @@ #include <cassert> #include <cstring> +#include <filesystem> #include <iostream> #include <sstream> #include <stdexcept> @@ -10,46 +11,47 @@ namespace clap { Plugin::Plugin(const clap_plugin_descriptor *desc, const clap_host *host) : host_(host) { - plugin_.plugin_data = this; - plugin_.desc = desc; - plugin_.init = Plugin::clapInit; - plugin_.destroy = Plugin::clapDestroy; - plugin_.extension = nullptr; - plugin_.process = nullptr; - plugin_.activate = nullptr; - plugin_.deactivate = nullptr; + plugin_.plugin_data = this; + plugin_.desc = desc; + plugin_.init = Plugin::clapInit; + plugin_.destroy = Plugin::clapDestroy; + plugin_.extension = nullptr; + plugin_.process = nullptr; + plugin_.activate = nullptr; + plugin_.deactivate = nullptr; plugin_.start_processing = nullptr; - plugin_.stop_processing = nullptr; + plugin_.stop_processing = nullptr; } ///////////////////// // CLAP Interfaces // ///////////////////// - // clap_plugin interface - bool Plugin::clapInit(const clap_plugin *plugin) { + //-------------// + // clap_plugin // + //-------------// + bool Plugin::clapInit(const clap_plugin *plugin) noexcept { auto &self = from(plugin); - self.plugin_.extension = Plugin::clapExtension; - self.plugin_.process = Plugin::clapProcess; - self.plugin_.activate = Plugin::clapActivate; - self.plugin_.deactivate = Plugin::clapDeactivate; + self.plugin_.extension = Plugin::clapExtension; + self.plugin_.process = Plugin::clapProcess; + self.plugin_.activate = Plugin::clapActivate; + self.plugin_.deactivate = Plugin::clapDeactivate; self.plugin_.start_processing = Plugin::clapStartProcessing; - self.plugin_.stop_processing = Plugin::clapStopProcessing; + self.plugin_.stop_processing = Plugin::clapStopProcessing; self.initInterfaces(); self.ensureMainThread("clap_plugin.init"); - self.initTrackInfo(); return self.init(); } - void Plugin::clapDestroy(const clap_plugin *plugin) { + void Plugin::clapDestroy(const clap_plugin *plugin) noexcept { auto &self = from(plugin); self.ensureMainThread("clap_plugin.destroy"); delete &from(plugin); } - bool Plugin::clapActivate(const clap_plugin *plugin, int sample_rate) { + bool Plugin::clapActivate(const clap_plugin *plugin, int sample_rate) noexcept { auto &self = from(plugin); self.ensureMainThread("clap_plugin.activate"); @@ -83,12 +85,12 @@ namespace clap { return false; } - self.isActive_ = true; + self.isActive_ = true; self.sampleRate_ = sample_rate; return true; } - void Plugin::clapDeactivate(const clap_plugin *plugin) { + void Plugin::clapDeactivate(const clap_plugin *plugin) noexcept { auto &self = from(plugin); self.ensureMainThread("clap_plugin.deactivate"); @@ -100,7 +102,7 @@ namespace clap { self.deactivate(); } - bool Plugin::clapStartProcessing(const clap_plugin *plugin) { + bool Plugin::clapStartProcessing(const clap_plugin *plugin) noexcept { auto &self = from(plugin); self.ensureAudioThread("clap_plugin.start_processing"); @@ -118,7 +120,7 @@ namespace clap { return self.isProcessing_; } - void Plugin::clapStopProcessing(const clap_plugin *plugin) { + void Plugin::clapStopProcessing(const clap_plugin *plugin) noexcept { auto &self = from(plugin); self.ensureAudioThread("clap_plugin.stop_processing"); @@ -136,7 +138,8 @@ namespace clap { self.isProcessing_ = false; } - clap_process_status Plugin::clapProcess(const clap_plugin *plugin, const clap_process *process) { + clap_process_status Plugin::clapProcess(const clap_plugin *plugin, + const clap_process *process) noexcept { auto &self = from(plugin); self.ensureAudioThread("clap_plugin.process"); @@ -154,68 +157,161 @@ namespace clap { return self.process(process); } - const void *Plugin::clapExtension(const clap_plugin *plugin, const char *id) { + const void *Plugin::clapExtension(const clap_plugin *plugin, const char *id) noexcept { auto &self = from(plugin); self.ensureMainThread("clap_plugin.extension"); - if (!strcmp(id, CLAP_EXT_RENDER)) - return &self.pluginRender_; - if (!strcmp(id, CLAP_EXT_TRACK_INFO)) + if (!strcmp(id, CLAP_EXT_STATE) && self.implementsState()) + return &pluginState_; + if (!strcmp(id, CLAP_EXT_PRESET_LOAD) && self.implementsPresetLoad()) + return &pluginPresetLoad_; + if (!strcmp(id, CLAP_EXT_RENDER) && self.implementsRender()) + return &pluginRender_; + if (!strcmp(id, CLAP_EXT_TRACK_INFO) && self.implementsTrackInfo()) return &pluginTrackInfo_; + if (!strcmp(id, CLAP_EXT_LATENCY) && self.implementsLatency()) + return &pluginLatency_; if (!strcmp(id, CLAP_EXT_AUDIO_PORTS) && self.implementsAudioPorts()) return &pluginAudioPorts_; if (!strcmp(id, CLAP_EXT_PARAMS) && self.implementsParams()) return &pluginParams_; + if (!strcmp(id, CLAP_EXT_NOTE_NAME) && self.implementsNoteName()) + return &pluginNoteName_; return from(plugin).extension(id); } - void Plugin::clapTrackInfoChanged(const clap_plugin *plugin) { + template <typename T> + void Plugin::initInterface(const T *&ptr, const char *id) noexcept { + assert(!ptr); + assert(id); + + if (host_->extension) + ptr = static_cast<const T *>(host_->extension(host_, id)); + } + + void Plugin::initInterfaces() noexcept { + initInterface(hostLog_, CLAP_EXT_LOG); + initInterface(hostThreadCheck_, CLAP_EXT_THREAD_CHECK); + initInterface(hostThreadPool_, CLAP_EXT_THREAD_POOL); + initInterface(hostAudioPorts_, CLAP_EXT_AUDIO_PORTS); + initInterface(hostEventLoop_, CLAP_EXT_EVENT_LOOP); + initInterface(hostEventFilter_, CLAP_EXT_EVENT_FILTER); + initInterface(hostFileReference_, CLAP_EXT_FILE_REFERENCE); + initInterface(hostLatency_, CLAP_EXT_LATENCY); + initInterface(hostGui_, CLAP_EXT_GUI); + initInterface(hostParams_, CLAP_EXT_PARAMS); + initInterface(hostTrackInfo_, CLAP_EXT_TRACK_INFO); + initInterface(hostState_, CLAP_EXT_STATE); + initInterface(hostNoteName_, CLAP_EXT_NOTE_NAME); + } + + //-------------------// + // clap_plugin_state // + //-------------------// + uint32_t Plugin::clapLatencyGet(const clap_plugin *plugin) noexcept { auto &self = from(plugin); - self.ensureMainThread("clap_plugin_track_info.changed"); + self.ensureMainThread("clap_plugin_latency.get"); - if (!self.canUseTrackInfo()) { - self.hostMisbehaving("Host called clap_plugin_track_info.changed() but does not provide a " - "complete clap_host_track_info interface"); - return; + return self.latencyGet(); + } + + //--------------------// + // clap_plugin_render // + //--------------------// + void Plugin::clapRenderSetMode(const clap_plugin *plugin, + clap_plugin_render_mode mode) noexcept { + auto &self = from(plugin); + self.ensureMainThread("clap_plugin_render.set_mode"); + + switch (mode) { + case CLAP_RENDER_REALTIME: + case CLAP_RENDER_OFFLINE: + self.renderSetMode(mode); + break; + + default: { + std::ostringstream msg; + msg << "host called clap_plugin_render.set_mode with an unknown mode : " << mode; + self.hostMisbehaving(msg.str()); + break; } + } + } - clap_track_info info; - if (!self.hostTrackInfo_->get(self.host_, &info)) { - self.hasTrackInfo_ = false; - self.hostMisbehaving( - "clap_host_track_info.get() failed after calling clap_plugin_track_info.changed()"); - return; + //-------------------// + // clap_plugin_state // + //-------------------// + bool Plugin::clapStateSave(const clap_plugin *plugin, clap_ostream *stream) noexcept { + auto &self = from(plugin); + self.ensureMainThread("clap_plugin_state.save"); + + return self.stateSave(stream); + } + + bool Plugin::clapStateLoad(const clap_plugin *plugin, clap_istream *stream) noexcept { + auto &self = from(plugin); + self.ensureMainThread("clap_plugin_state.load"); + + return self.stateLoad(stream); + } + + bool Plugin::clapStateIsDirty(const clap_plugin *plugin) noexcept { + auto &self = from(plugin); + self.ensureMainThread("clap_plugin_state.is_dirty"); + + return self.stateIsDirty(); + } + + //-------------------------// + // clap_plugin_preset_load // + //-------------------------// + bool Plugin::clapPresetLoadFromFile(const clap_plugin *plugin, const char *path) noexcept { + auto &self = from(plugin); + self.ensureMainThread("clap_plugin_preset_load.from_file"); + + if (!path) { + self.hostMisbehaving("host called clap_plugin_preset_load.from_file with a null path"); + return false; } - const bool didChannelChange = info.channel_count != self.trackInfo_.channel_count || - info.channel_map != self.trackInfo_.channel_map; - self.trackInfo_ = info; - self.hasTrackInfo_ = true; - self.trackInfoChanged(); + // TODO check if the file is readable + + return self.presetLoadFromFile(path); } - void Plugin::initTrackInfo() { - checkMainThread(); + //------------------------// + // clap_plugin_track_info // + //------------------------// - assert(!hasTrackInfo_); - if (!canUseTrackInfo()) + void Plugin::clapTrackInfoChanged(const clap_plugin *plugin) noexcept { + auto &self = from(plugin); + self.ensureMainThread("clap_plugin_track_info.changed"); + + if (!self.canUseTrackInfo()) { + self.hostMisbehaving("host called clap_plugin_track_info.changed() but does not provide a " + "complete clap_host_track_info interface"); return; + } - hasTrackInfo_ = hostTrackInfo_->get(host_, &trackInfo_); + self.trackInfoChanged(); } - uint32_t Plugin::clapAudioPortsCount(const clap_plugin *plugin, bool is_input) { + //-------------------------// + // clap_plugin_audio_ports // + //-------------------------// + + uint32_t Plugin::clapAudioPortsCount(const clap_plugin *plugin, bool is_input) noexcept { auto &self = from(plugin); self.ensureMainThread("clap_plugin_audio_ports.count"); return self.audioPortsCount(is_input); } - bool Plugin::clapAudioPortsInfo(const clap_plugin * plugin, - uint32_t index, - bool is_input, - clap_audio_port_info *info) { + bool Plugin::clapAudioPortsInfo(const clap_plugin *plugin, + uint32_t index, + bool is_input, + clap_audio_port_info *info) noexcept { auto &self = from(plugin); self.ensureMainThread("clap_plugin_audio_ports.info"); auto count = clapAudioPortsCount(plugin, is_input); @@ -230,15 +326,15 @@ namespace clap { return self.audioPortsInfo(index, is_input, info); } - uint32_t Plugin::clapAudioPortsConfigCount(const clap_plugin *plugin) { + uint32_t Plugin::clapAudioPortsConfigCount(const clap_plugin *plugin) noexcept { auto &self = from(plugin); self.ensureMainThread("clap_plugin_audio_ports.config_count"); return self.audioPortsConfigCount(); } - bool Plugin::clapAudioPortsGetConfig(const clap_plugin * plugin, - uint32_t index, - clap_audio_ports_config *config) { + bool Plugin::clapAudioPortsGetConfig(const clap_plugin *plugin, + uint32_t index, + clap_audio_ports_config *config) noexcept { auto &self = from(plugin); self.ensureMainThread("clap_plugin_audio_ports.get_config"); @@ -253,7 +349,7 @@ namespace clap { return self.audioPortsGetConfig(index, config); } - bool Plugin::clapAudioPortsSetConfig(const clap_plugin *plugin, clap_id config_id) { + bool Plugin::clapAudioPortsSetConfig(const clap_plugin *plugin, clap_id config_id) noexcept { auto &self = from(plugin); self.ensureMainThread("clap_plugin_audio_ports.get_config"); @@ -264,16 +360,19 @@ namespace clap { return self.audioPortsSetConfig(config_id); } - uint32_t Plugin::clapParamsCount(const clap_plugin *plugin) { + uint32_t Plugin::clapParamsCount(const clap_plugin *plugin) noexcept { auto &self = from(plugin); self.ensureMainThread("clap_plugin_params.count"); return self.paramsCount(); } + //--------------------// + // clap_plugin_params // + //--------------------// bool Plugin::clapParamsIinfo(const clap_plugin *plugin, - int32_t param_index, - clap_param_info * param_info) { + int32_t param_index, + clap_param_info *param_info) noexcept { auto &self = from(plugin); self.ensureMainThread("clap_plugin_params.info"); @@ -290,9 +389,9 @@ namespace clap { } bool Plugin::clapParamsEnumValue(const clap_plugin *plugin, - clap_id param_id, - int32_t value_index, - clap_param_value * value) { + clap_id param_id, + int32_t value_index, + clap_param_value *value) noexcept { auto &self = from(plugin); self.ensureMainThread("clap_plugin_params.enum_value"); @@ -308,8 +407,9 @@ namespace clap { return self.paramsEnumValue(param_id, value_index, value); } - bool - Plugin::clapParamsValue(const clap_plugin *plugin, clap_id param_id, clap_param_value *value) { + bool Plugin::clapParamsValue(const clap_plugin *plugin, + clap_id param_id, + clap_param_value *value) noexcept { auto &self = from(plugin); self.ensureMainThread("clap_plugin_params.value"); @@ -326,9 +426,9 @@ namespace clap { } bool Plugin::clapParamsSetValue(const clap_plugin *plugin, - clap_id param_id, - clap_param_value value, - clap_param_value modulation) { + clap_id param_id, + clap_param_value value, + clap_param_value modulation) noexcept { auto &self = from(plugin); self.ensureMainThread("clap_plugin_params.set_value"); @@ -351,10 +451,10 @@ namespace clap { } bool Plugin::clapParamsValueToText(const clap_plugin *plugin, - clap_id param_id, - clap_param_value value, - char * display, - uint32_t size) { + clap_id param_id, + clap_param_value value, + char *display, + uint32_t size) noexcept { auto &self = from(plugin); self.ensureMainThread("clap_plugin_params.value_to_text"); @@ -370,9 +470,9 @@ namespace clap { } bool Plugin::clapParamsTextToValue(const clap_plugin *plugin, - clap_id param_id, - const char * display, - clap_param_value * value) { + clap_id param_id, + const char *display, + clap_param_value *value) noexcept { auto &self = from(plugin); self.ensureMainThread("clap_plugin_params.text_to_value"); @@ -390,7 +490,7 @@ namespace clap { bool Plugin::isValidParamId(clap_id param_id) const noexcept { checkMainThread(); - auto count = paramsCount(); + auto count = paramsCount(); clap_param_info info; for (uint32_t i = 0; i < count; ++i) { if (!paramsInfo(i, &info)) @@ -403,17 +503,48 @@ namespace clap { return false; } + //-----------------------// + // clap_plugin_note_name // + //-----------------------// + + uint32_t Plugin::clapNoteNameCount(const clap_plugin *plugin) noexcept { + auto &self = from(plugin); + self.ensureMainThread("clap_plugin_note_name.count"); + return self.noteNameCount(); + } + + bool Plugin::clapNoteNameGet(const clap_plugin *plugin, + uint32_t index, + clap_note_name *note_name) noexcept { + auto &self = from(plugin); + self.ensureMainThread("clap_plugin_note_name.get"); + + // TODO check index + auto count = clapNoteNameCount(plugin); + if (index >= count) { + std::ostringstream msg; + msg << "host called clap_plugin_note_name.get with an index out of bounds: " << index + << " >= " << count; + self.hostMisbehaving(msg.str()); + return false; + } + + return self.noteNameGet(index, note_name); + } + ///////////// // Logging // ///////////// - void Plugin::log(clap_log_severity severity, const char *msg) const { + void Plugin::log(clap_log_severity severity, const char *msg) const noexcept { if (canUseHostLog()) hostLog_->log(host_, severity, msg); else std::clog << msg << std::endl; } - void Plugin::hostMisbehaving(const char *msg) { log(CLAP_LOG_HOST_MISBEHAVING, msg); } + void Plugin::hostMisbehaving(const char *msg) const noexcept { + log(CLAP_LOG_HOST_MISBEHAVING, msg); + } ///////////////////////////////// // Interface consistency check // @@ -430,7 +561,7 @@ namespace clap { // Thread Checking // ///////////////////// - void Plugin::checkMainThread() const { + void Plugin::checkMainThread() const noexcept { if (!hostThreadCheck_ || !hostThreadCheck_->is_main_thread || hostThreadCheck_->is_main_thread(host_)) return; @@ -438,7 +569,7 @@ namespace clap { std::terminate(); } - void Plugin::ensureMainThread(const char *method) { + void Plugin::ensureMainThread(const char *method) const noexcept { if (!hostThreadCheck_ || !hostThreadCheck_->is_main_thread || hostThreadCheck_->is_main_thread(host_)) return; @@ -450,7 +581,7 @@ namespace clap { std::terminate(); } - void Plugin::ensureAudioThread(const char *method) { + void Plugin::ensureAudioThread(const char *method) const noexcept { if (!hostThreadCheck_ || !hostThreadCheck_->is_audio_thread || hostThreadCheck_->is_audio_thread(host_)) return; @@ -465,7 +596,7 @@ namespace clap { /////////////// // Utilities // /////////////// - Plugin &Plugin::from(const clap_plugin *plugin) { + Plugin &Plugin::from(const clap_plugin *plugin) noexcept { if (!plugin) { std::cerr << "called with a null clap_plugin pointer!" << std::endl; std::terminate(); @@ -481,31 +612,6 @@ namespace clap { return *static_cast<Plugin *>(plugin->plugin_data); } - template <typename T> - void Plugin::initInterface(const T *&ptr, const char *id) { - assert(!ptr); - assert(id); - - if (host_->extension) - ptr = static_cast<const T *>(host_->extension(host_, id)); - } - - void Plugin::initInterfaces() { - initInterface(hostLog_, CLAP_EXT_LOG); - initInterface(hostThreadCheck_, CLAP_EXT_THREAD_CHECK); - initInterface(hostThreadPool_, CLAP_EXT_THREAD_POOL); - initInterface(hostAudioPorts_, CLAP_EXT_AUDIO_PORTS); - initInterface(hostEventLoop_, CLAP_EXT_EVENT_LOOP); - initInterface(hostEventFilter_, CLAP_EXT_EVENT_FILTER); - initInterface(hostFileReference_, CLAP_EXT_FILE_REFERENCE); - initInterface(hostLatency_, CLAP_EXT_LATENCY); - initInterface(hostGui_, CLAP_EXT_GUI); - initInterface(hostParams_, CLAP_EXT_PARAMS); - initInterface(hostTrackInfo_, CLAP_EXT_TRACK_INFO); - initInterface(hostState_, CLAP_EXT_STATE); - initInterface(hostNoteName_, CLAP_EXT_NOTE_NAME); - } - uint32_t Plugin::compareAudioPortsInfo(const clap_audio_port_info &a, const clap_audio_port_info &b) noexcept { if (a.sample_size != b.sample_size || a.in_place != b.in_place || a.is_cv != b.is_cv || @@ -518,11 +624,4 @@ namespace clap { return 0; } - - int Plugin::sampleRate() const noexcept { - assert(isActive_ && - "there is no point in querying the sample rate if the plugin isn't activated"); - assert(isActive_ ? sampleRate_ > 0 : sampleRate_ == 0); - return sampleRate_; - } } // namespace clap \ No newline at end of file diff --git a/examples/plugins/plugin.hh b/examples/plugins/plugin.hh @@ -10,6 +10,9 @@ #include "parameters.hh" namespace clap { + /// @brief C++ glue and checks + /// + /// @note for an higher level implementation, see @ref PluginHelper class Plugin { public: const clap_plugin *clapPlugin() noexcept { return &plugin_; } @@ -20,7 +23,7 @@ namespace clap { // not copyable, not moveable Plugin(const Plugin &) = delete; - Plugin(Plugin &&) = delete; + Plugin(Plugin &&) = delete; Plugin &operator=(const Plugin &) = delete; Plugin &operator=(Plugin &&) = delete; @@ -28,51 +31,107 @@ namespace clap { // Methods to override // ///////////////////////// - // clap_plugin - virtual bool init() { return true; } - virtual bool activate(int sampleRate) { return true; } - virtual void deactivate() {} - virtual bool startProcessing() { return true; } - virtual void stopProcessing() {} - virtual clap_process_status process(const clap_process *process) { + //-------------// + // clap_plugin // + //-------------// + virtual bool init() noexcept { return true; } + virtual bool activate(int sampleRate) noexcept { return true; } + virtual void deactivate() noexcept {} + virtual bool startProcessing() noexcept { return true; } + virtual void stopProcessing() noexcept {} + virtual clap_process_status process(const clap_process *process) noexcept { return CLAP_PROCESS_SLEEP; } - virtual const void *extension(const char *id) { return nullptr; } - - // clap_plugin_track_info - virtual void trackInfoChanged() {} + virtual const void *extension(const char *id) noexcept { return nullptr; } + + //---------------------// + // clap_plugin_latenxy // + //---------------------// + virtual bool implementsLatency() const noexcept { return false; } + virtual uint32_t latencyGet() const noexcept { return 0; } + + //--------------------// + // clap_plugin_render // + //--------------------// + virtual bool implementsRender() const noexcept { return false; } + virtual void renderSetMode(clap_plugin_render_mode mode) noexcept {} + + //-------------------// + // clap_plugin_state // + //-------------------// + virtual bool implementsState() const noexcept { return false; } + virtual bool stateSave(clap_ostream *stream) noexcept { return false; } + virtual bool stateLoad(clap_istream *stream) noexcept { return false; } + virtual bool stateIsDirty() const noexcept { return false; } + void stateMarkDirty() const noexcept { + if (canUseState()) + hostState_->mark_dirty(host_); + } - // 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) { + //-------------------------// + // clap_plugin_preset_load // + //-------------------------// + virtual bool implementsPresetLoad() const noexcept { return false; } + virtual bool presetLoadFromFile(const char *path) noexcept { return false; } + + //------------------------// + // clap_plugin_track_info // + //------------------------// + virtual bool implementsTrackInfo() const noexcept { return false; } + virtual void trackInfoChanged() noexcept {} + + //-------------------------// + // clap_plugin_audio_ports // + //-------------------------// + virtual bool implementsAudioPorts() const noexcept { return false; } + virtual uint32_t audioPortsCount(bool is_input) const noexcept { return 0; } + virtual bool + audioPortsInfo(uint32_t index, bool is_input, clap_audio_port_info *info) const noexcept { return false; } - virtual uint32_t audioPortsConfigCount() { return 0; } - virtual bool audioPortsGetConfig(uint32_t index, clap_audio_ports_config *config) { + virtual uint32_t audioPortsConfigCount() const noexcept { return 0; } + virtual bool audioPortsGetConfig(uint32_t index, + clap_audio_ports_config *config) const noexcept { 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) { + virtual bool audioPortsSetConfig(clap_id config_id) noexcept { return false; } + + //--------------------// + // clap_plugin_params // + //--------------------// + virtual bool implementsParams() const noexcept { return false; } + virtual uint32_t paramsCount() const noexcept { return 0; } + virtual bool paramsInfo(int32_t paramIndex, clap_param_info *info) const noexcept { return false; } - virtual bool paramsValue(clap_id paramId, clap_param_value *value) { return false; } - virtual bool - paramsSetValue(clap_id paramId, clap_param_value value, clap_param_value modulation) { return false; } virtual bool - paramsValueToText(clap_id paramId, clap_param_value value, char *display, uint32_t size) { + paramsEnumValue(clap_id paramId, int32_t valueIndex, clap_param_value *value) noexcept { + return false; + } + virtual bool paramsValue(clap_id paramId, clap_param_value *value) noexcept { return false; } + virtual bool paramsSetValue(clap_id paramId, + clap_param_value value, + clap_param_value modulation) noexcept { + return false; + } + virtual bool paramsValueToText(clap_id paramId, + clap_param_value value, + char *display, + uint32_t size) noexcept { return false; } virtual bool - paramsTextToValue(clap_id param_id, const char *display, clap_param_value *value) { + paramsTextToValue(clap_id param_id, const char *display, clap_param_value *value) noexcept { return false; } + //-----------------------// + // clap_plugin_note_name // + //-----------------------// + virtual bool implementsNoteName() const noexcept { return false; } + virtual int noteNameCount() noexcept { return 0; } + virtual bool noteNameGet(int index, clap_note_name *note_name) noexcept { return false; } + ////////////////// // Invalidation // ////////////////// @@ -81,9 +140,9 @@ namespace clap { ///////////// // Logging // ///////////// - void log(clap_log_severity severity, const char *msg) const; - void hostMisbehaving(const char *msg); - void hostMisbehaving(const std::string &msg) { hostMisbehaving(msg.c_str()); } + void log(clap_log_severity severity, const char *msg) const noexcept; + void hostMisbehaving(const char *msg) const noexcept; + void hostMisbehaving(const std::string &msg) const noexcept { hostMisbehaving(msg.c_str()); } ///////////////////////////////// // Interface consistency check // @@ -91,23 +150,24 @@ namespace clap { bool canUseHostLog() const noexcept; bool canUseThreadCheck() const noexcept; bool canUseTrackInfo() const noexcept; + bool canUseState() const noexcept; bool canChangeAudioPorts() const noexcept; ///////////////////// // Thread Checking // ///////////////////// - void checkMainThread() const; - void ensureMainThread(const char *method); - void ensureAudioThread(const char *method); + void checkMainThread() const noexcept; + void ensureMainThread(const char *method) const noexcept; + void ensureAudioThread(const char *method) const noexcept; /////////////// // Utilities // /////////////// - static Plugin &from(const clap_plugin *plugin); + static Plugin &from(const clap_plugin *plugin) noexcept; template <typename T> - void initInterface(const T *&ptr, const char *id); - void initInterfaces(); + void initInterface(const T *&ptr, const char *id) noexcept; + void initInterfaces() noexcept; static uint32_t compareAudioPortsInfo(const clap_audio_port_info &a, const clap_audio_port_info &b) noexcept; @@ -119,56 +179,40 @@ namespace clap { ////////////////////// bool isActive() const noexcept { return isActive_; } bool isProcessing() const noexcept { return isProcessing_; } - int sampleRate() const noexcept; - - ////////////////////// - // Cached Host Info // - ////////////////////// - bool hasTrackInfo() const noexcept { return hasTrackInfo_; } - const clap_track_info &trackInfo() const noexcept { - assert(hasTrackInfo_); - return trackInfo_; - } - uint32_t trackChannelCount() const noexcept { - return hasTrackInfo_ ? trackInfo_.channel_count : 2; - } - clap_chmap trackChannelMap() const noexcept { - return hasTrackInfo_ ? trackInfo_.channel_map : CLAP_CHMAP_STEREO; + int sampleRate() const noexcept { + assert(isActive_ && "sample rate is only known if the plugin is active"); + assert(sampleRate_ > 0); + return sampleRate_; } protected: clap_plugin_event_filter pluginEventFilter_; - clap_plugin_latency pluginLatency_; - clap_plugin_render pluginRender_; - clap_plugin_note_name pluginNoteName_; - clap_plugin_thread_pool pluginThreadPool_; + clap_plugin_thread_pool pluginThreadPool_; /* state related */ - clap_plugin_state pluginState_; - clap_plugin_preset_load pluginPresetLoad_; clap_plugin_file_reference pluginFileReference_; /* GUI related */ - clap_plugin_gui pluginGui_; - clap_plugin_gui_win32 pluginGuiWin32_; - clap_plugin_gui_cocoa pluginGuiCocoa_; - clap_plugin_gui_x11 pluginGuiX11_; + clap_plugin_gui pluginGui_; + clap_plugin_gui_win32 pluginGuiWin32_; + clap_plugin_gui_cocoa pluginGuiCocoa_; + clap_plugin_gui_x11 pluginGuiX11_; clap_plugin_event_loop pluginEventLoop_; - const clap_host *const host_ = nullptr; - const clap_host_log * hostLog_ = nullptr; - const clap_host_thread_check * hostThreadCheck_ = nullptr; - const clap_host_thread_pool * hostThreadPool_ = nullptr; - const clap_host_audio_ports * hostAudioPorts_ = nullptr; - const clap_host_event_filter * hostEventFilter_ = nullptr; + const clap_host *const host_ = nullptr; + const clap_host_log *hostLog_ = nullptr; + const clap_host_thread_check *hostThreadCheck_ = nullptr; + const clap_host_thread_pool *hostThreadPool_ = nullptr; + const clap_host_audio_ports *hostAudioPorts_ = nullptr; + const clap_host_event_filter *hostEventFilter_ = nullptr; const clap_host_file_reference *hostFileReference_ = nullptr; - const clap_host_latency * hostLatency_ = nullptr; - const clap_host_gui * hostGui_ = nullptr; - const clap_host_event_loop * hostEventLoop_ = nullptr; - const clap_host_params * hostParams_ = nullptr; - const clap_host_track_info * hostTrackInfo_ = nullptr; - const clap_host_state * hostState_ = nullptr; - const clap_host_note_name * hostNoteName_ = nullptr; + const clap_host_latency *hostLatency_ = nullptr; + const clap_host_gui *hostGui_ = nullptr; + const clap_host_event_loop *hostEventLoop_ = nullptr; + const clap_host_params *hostParams_ = nullptr; + const clap_host_track_info *hostTrackInfo_ = nullptr; + const clap_host_state *hostState_ = nullptr; + const clap_host_note_name *hostNoteName_ = nullptr; private: ///////////////////// @@ -177,77 +221,126 @@ namespace clap { clap_plugin plugin_; // clap_plugin - static bool clapInit(const clap_plugin *plugin); - static void clapDestroy(const clap_plugin *plugin); - static bool clapActivate(const clap_plugin *plugin, int sample_rate); - static void clapDeactivate(const clap_plugin *plugin); - static bool clapStartProcessing(const clap_plugin *plugin); - static void clapStopProcessing(const clap_plugin *plugin); - static clap_process_status clapProcess(const clap_plugin * plugin, - const clap_process *process); - static const void * clapExtension(const clap_plugin *plugin, const char *id); + static bool clapInit(const clap_plugin *plugin) noexcept; + static void clapDestroy(const clap_plugin *plugin) noexcept; + static bool clapActivate(const clap_plugin *plugin, int sample_rate) noexcept; + static void clapDeactivate(const clap_plugin *plugin) noexcept; + static bool clapStartProcessing(const clap_plugin *plugin) noexcept; + static void clapStopProcessing(const clap_plugin *plugin) noexcept; + static clap_process_status clapProcess(const clap_plugin *plugin, + const clap_process *process) noexcept; + static const void *clapExtension(const clap_plugin *plugin, const char *id) noexcept; + + // latency + static uint32_t clapLatencyGet(const clap_plugin *plugin) noexcept; + + // clap_plugin_render + static void clapRenderSetMode(const clap_plugin *plugin, + clap_plugin_render_mode mode) noexcept; + + // clap_plugin_state + static bool clapStateSave(const clap_plugin *plugin, clap_ostream *stream) noexcept; + static bool clapStateLoad(const clap_plugin *plugin, clap_istream *stream) noexcept; + static bool clapStateIsDirty(const clap_plugin *plugin) noexcept; + + // clap_plugin_preset + static bool clapPresetLoadFromFile(const clap_plugin *plugin, const char *path) noexcept; // clap_plugin_track_info - static void clapTrackInfoChanged(const clap_plugin *plugin); - void initTrackInfo(); + static void clapTrackInfoChanged(const clap_plugin *plugin) noexcept; // clap_plugin_audio_ports - static uint32_t clapAudioPortsCount(const clap_plugin *plugin, bool is_input); - static bool clapAudioPortsInfo(const clap_plugin * plugin, - uint32_t index, - bool is_input, - clap_audio_port_info *info); - 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); + static uint32_t clapAudioPortsCount(const clap_plugin *plugin, bool is_input) noexcept; + static bool clapAudioPortsInfo(const clap_plugin *plugin, + uint32_t index, + bool is_input, + clap_audio_port_info *info) noexcept; + static uint32_t clapAudioPortsConfigCount(const clap_plugin *plugin) noexcept; + static bool clapAudioPortsGetConfig(const clap_plugin *plugin, + uint32_t index, + clap_audio_ports_config *config) noexcept; + static bool clapAudioPortsSetConfig(const clap_plugin *plugin, clap_id config_id) noexcept; // 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 uint32_t clapParamsCount(const clap_plugin *plugin) noexcept; + static bool clapParamsIinfo(const clap_plugin *plugin, + int32_t param_index, + clap_param_info *param_info) noexcept; 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); + clap_id param_id, + int32_t value_index, + clap_param_value *value) noexcept; + static bool clapParamsValue(const clap_plugin *plugin, + clap_id param_id, + clap_param_value *value) noexcept; static bool clapParamsSetValue(const clap_plugin *plugin, - clap_id param_id, - clap_param_value value, - clap_param_value modulation); + clap_id param_id, + clap_param_value value, + clap_param_value modulation) noexcept; static bool clapParamsValueToText(const clap_plugin *plugin, - clap_id param_id, - clap_param_value value, - char * display, - uint32_t size); + clap_id param_id, + clap_param_value value, + char *display, + uint32_t size) noexcept; static bool clapParamsTextToValue(const clap_plugin *plugin, - clap_id param_id, - const char * display, - clap_param_value * value); + clap_id param_id, + const char *display, + clap_param_value *value) noexcept; + + // clap_note_name + static uint32_t clapNoteNameCount(const clap_plugin *plugin) noexcept; + static bool + clapNoteNameGet(const clap_plugin *plugin, uint32_t index, clap_note_name *note_name) noexcept; // interfaces - static const constexpr clap_plugin_track_info pluginTrackInfo_ = {clapTrackInfoChanged}; - static const constexpr clap_plugin_audio_ports pluginAudioPorts_ = {clapAudioPortsCount, - clapAudioPortsInfo, - clapAudioPortsConfigCount, - clapAudioPortsGetConfig, - clapAudioPortsSetConfig}; - static const constexpr clap_plugin_params pluginParams_ = {clapParamsCount, - clapParamsIinfo, - clapParamsEnumValue, - clapParamsValue, - clapParamsSetValue, - clapParamsValueToText, - clapParamsTextToValue}; + static const constexpr clap_plugin_render pluginRender_ = { + clapRenderSetMode, + }; + + static const constexpr clap_plugin_state pluginState_ = { + clapStateSave, + clapStateLoad, + clapStateIsDirty, + }; + + static const constexpr clap_plugin_preset_load pluginPresetLoad_ = { + clapPresetLoadFromFile, + }; + + static const constexpr clap_plugin_track_info pluginTrackInfo_ = { + clapTrackInfoChanged, + }; + + static const constexpr clap_plugin_audio_ports pluginAudioPorts_ = { + clapAudioPortsCount, + clapAudioPortsInfo, + clapAudioPortsConfigCount, + clapAudioPortsGetConfig, + clapAudioPortsSetConfig, + }; + + static const constexpr clap_plugin_params pluginParams_ = { + clapParamsCount, + clapParamsIinfo, + clapParamsEnumValue, + clapParamsValue, + clapParamsSetValue, + clapParamsValueToText, + clapParamsTextToValue, + }; + + static const constexpr clap_plugin_latency pluginLatency_ = { + clapLatencyGet, + }; + + static const constexpr clap_plugin_note_name pluginNoteName_ = { + clapNoteNameCount, + clapNoteNameGet, + }; // state - bool isActive_ = false; + bool isActive_ = false; bool isProcessing_ = false; - int sampleRate_ = 0; - - bool hasTrackInfo_ = false; - clap_track_info trackInfo_; + int sampleRate_ = 0; }; } // namespace clap \ No newline at end of file diff --git a/include/clap/ext/draft/key-name.h b/include/clap/ext/draft/key-name.h @@ -17,11 +17,11 @@ typedef struct clap_note_name { typedef struct clap_plugin_note_name { // Return the number of note names // [main-thread] - int (*count)(const clap_plugin *plugin); + uint32_t (*count)(const clap_plugin *plugin); // Returns true on success and stores the result into note_name // [main-thread] - bool (*get)(const clap_plugin *plugin, int index, clap_note_name *note_name); + bool (*get)(const clap_plugin *plugin, uint32_t index, clap_note_name *note_name); } clap_plugin_note_name; typedef struct clap_host_note_name { diff --git a/include/clap/ext/draft/preset-load.h b/include/clap/ext/draft/preset-load.h @@ -11,7 +11,7 @@ extern "C" { typedef struct clap_plugin_preset_load { // Loads a preset in the plugin native preset file format from a path. // [main-thread] - bool (*load_from_file)(const clap_plugin *plugin, const char *path); + bool (*from_file)(const clap_plugin *plugin, const char *path); } clap_plugin_preset_load; #ifdef __cplusplus diff --git a/include/clap/ext/render.h b/include/clap/ext/render.h @@ -21,7 +21,7 @@ typedef int32_t clap_plugin_render_mode; // pressure to process. typedef struct clap_plugin_render { // [main-thread] - void (*set_render_mode)(const clap_plugin *plugin, clap_plugin_render_mode mode); + void (*set_mode)(const clap_plugin *plugin, clap_plugin_render_mode mode); } clap_plugin_render; #ifdef __cplusplus diff --git a/include/clap/ext/state.h b/include/clap/ext/state.h @@ -16,13 +16,16 @@ typedef struct clap_plugin_state { /* Loads the plugin state from stream. * [main-thread] */ - bool (*restore)(const clap_plugin *plugin, clap_istream *stream); + bool (*load)(const clap_plugin *plugin, clap_istream *stream); + + // [main-thread] + bool (*is_dirty)(const clap_plugin *plugin); } clap_plugin_state; typedef struct clap_host_state { /* Tell the host that the plugin state has changed. * [thread-safe] */ - void (*set_dirty)(const clap_host *host); + void (*mark_dirty)(const clap_host *host); } clap_host_state; #ifdef __cplusplus