clap

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

commit 07a69059c1558fbe69562d46c1d38ec768cc86d0
parent 14e4af99d09e6de73c708f23344ebc3459470e71
Author: Alexandre BIQUE <bique.alexandre@gmail.com>
Date:   Mon,  6 Sep 2021 15:43:01 +0200

Big refactoring

Diffstat:
Mexamples/glue/clap-plugin.cc | 47+++++++++++++++++++++++++++++++----------------
Mexamples/glue/clap-plugin.hh | 41++++++++++++++++++++++++++++-------------
Mexamples/host/plugin-host.cc | 136++++++++++++++++++++++++++++++++++---------------------------------------------
Mexamples/host/plugin-host.hh | 61+++++++++++++++++++++++++++++++++++++++++++------------------
Mexamples/io/remote-channel.cc | 1-
Mexamples/plugins/core-plugin.cc | 4++--
Mexamples/plugins/core-plugin.hh | 13+++++++++----
Mexamples/plugins/remote-gui.cc | 13++++++++-----
Minclude/clap/all.h | 4+++-
Minclude/clap/clap.h | 7++++---
Minclude/clap/events.h | 28+++++++++++++++++-----------
Ainclude/clap/ext/audio-ports-config.h | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Minclude/clap/ext/audio-ports.h | 42++++++------------------------------------
Minclude/clap/ext/draft/quick-controls.h | 26+++++++++++++-------------
Minclude/clap/ext/draft/tuning.h | 2+-
Minclude/clap/ext/event-filter.h | 2+-
Dinclude/clap/ext/event-loop.h | 63---------------------------------------------------------------
Ainclude/clap/ext/fd-support.h | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Minclude/clap/ext/gui.h | 2+-
Minclude/clap/ext/params.h | 4++--
Minclude/clap/ext/render.h | 2+-
Ainclude/clap/ext/timer-support.h | 32++++++++++++++++++++++++++++++++
Minclude/clap/version.h | 2+-
23 files changed, 381 insertions(+), 270 deletions(-)

diff --git a/examples/glue/clap-plugin.cc b/examples/glue/clap-plugin.cc @@ -15,7 +15,7 @@ namespace clap { plugin_.desc = desc; plugin_.init = Plugin::clapInit; plugin_.destroy = Plugin::clapDestroy; - plugin_.extension = nullptr; + plugin_.get_extension = nullptr; plugin_.process = nullptr; plugin_.activate = nullptr; plugin_.deactivate = nullptr; @@ -35,7 +35,7 @@ namespace clap { bool Plugin::clapInit(const clap_plugin *plugin) noexcept { auto &self = from(plugin); - self.plugin_.extension = Plugin::clapExtension; + self.plugin_.get_extension = Plugin::clapExtension; self.plugin_.process = Plugin::clapProcess; self.plugin_.activate = Plugin::clapActivate; self.plugin_.deactivate = Plugin::clapDeactivate; @@ -185,8 +185,10 @@ namespace clap { return &pluginNoteName_; if (!strcmp(id, CLAP_EXT_THREAD_POOL) && self.implementsThreadPool()) return &pluginThreadPool_; - if (!strcmp(id, CLAP_EXT_EVENT_LOOP) && self.implementsEventLoop()) - return &pluginEventLoop_; + if (!strcmp(id, CLAP_EXT_TIMER_SUPPORT) && self.implementsTimerSupport()) + return &pluginTimerSupport_; + if (!strcmp(id, CLAP_EXT_FD_SUPPORT) && self.implementsFdSupport()) + return &pluginFdSupport_; if (!strcmp(id, CLAP_EXT_GUI) && self.implementsGui()) return &pluginGui_; if (!strcmp(id, CLAP_EXT_GUI_X11) && self.implementsGuiX11()) @@ -206,8 +208,8 @@ namespace clap { assert(!ptr); assert(id); - if (host_->extension) - ptr = static_cast<const T *>(host_->extension(host_, id)); + if (host_->get_extension) + ptr = static_cast<const T *>(host_->get_extension(host_, id)); } void Plugin::initInterfaces() noexcept { @@ -215,7 +217,8 @@ namespace clap { 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(hostTimerSupport_, CLAP_EXT_TIMER_SUPPORT); + initInterface(hostFdSupport_, CLAP_EXT_FD_SUPPORT); initInterface(hostEventFilter_, CLAP_EXT_EVENT_FILTER); initInterface(hostFileReference_, CLAP_EXT_FILE_REFERENCE); initInterface(hostLatency_, CLAP_EXT_LATENCY); @@ -554,7 +557,7 @@ namespace clap { //------------------------// // clap_plugin_event_loop // //------------------------// - void Plugin::clapEventLoopOnTimer(const clap_plugin *plugin, clap_id timer_id) noexcept { + void Plugin::clapOnTimer(const clap_plugin *plugin, clap_id timer_id) noexcept { auto &self = from(plugin); self.ensureMainThread("clap_plugin_event_loop.on_timer"); @@ -564,14 +567,14 @@ namespace clap { return; } - self.eventLoopOnTimer(timer_id); + self.onTimer(timer_id); } - void Plugin::clapEventLoopOnFd(const clap_plugin *plugin, clap_fd fd, uint32_t flags) noexcept { + void Plugin::clapOnFd(const clap_plugin *plugin, clap_fd fd, uint32_t flags) noexcept { auto &self = from(plugin); self.ensureMainThread("clap_plugin_event_loop.on_fd"); - self.eventLoopOnFd(fd, flags); + self.onFd(fd, flags); } //-----------------// @@ -857,15 +860,27 @@ namespace clap { hostThreadCheck_->is_main_thread; } - bool Plugin::canUseEventLoop() const noexcept { - if (!hostEventLoop_) + bool Plugin::canUseTimerSupport() const noexcept { + if (!hostTimerSupport_) return false; - auto &x = *hostEventLoop_; - if (x.modify_fd && x.register_fd && x.unregister_fd && x.register_timer && x.unregister_timer) + auto &x = *hostTimerSupport_; + if (x.register_timer && x.unregister_timer) return true; - hostMisbehaving("clap_event_loop is partially implemented"); + hostMisbehaving("clap_timer_support is partially implemented"); + return false; + } + + bool Plugin::canUseFdSupport() const noexcept { + if (!hostFdSupport_) + return false; + + auto &x = *hostFdSupport_; + if (x.modify_fd && x.register_fd && x.unregister_fd) + return true; + + hostMisbehaving("clap_fd_support is partially implemented"); return false; } diff --git a/examples/glue/clap-plugin.hh b/examples/glue/clap-plugin.hh @@ -136,12 +136,17 @@ namespace clap { virtual int noteNameCount() noexcept { return 0; } virtual bool noteNameGet(int index, clap_note_name *noteName) noexcept { return false; } + //---------------------------// + // clap_plugin_timer_support // + //---------------------------// + virtual bool implementsTimerSupport() const noexcept { return false; } + virtual void onTimer(clap_id timerId) noexcept {} + //------------------------// - // clap_plugin_event_loop // + // clap_plugin_fd_support // //------------------------// - virtual bool implementsEventLoop() const noexcept { return false; } - virtual void eventLoopOnTimer(clap_id timerId) noexcept {} - virtual void eventLoopOnFd(clap_fd fd, uint32_t flags) noexcept {} + virtual bool implementsFdSupport() const noexcept { return false; } + virtual void onFd(clap_fd fd, uint32_t flags) noexcept {} //-----------------// // clap_plugin_gui // @@ -199,7 +204,8 @@ namespace clap { bool canUseThreadCheck() const noexcept; bool canUseTrackInfo() const noexcept; bool canUseState() const noexcept; - bool canUseEventLoop() const noexcept; + bool canUseTimerSupport() const noexcept; + bool canUseFdSupport() const noexcept; bool canUseParams() const noexcept; bool canUseLatency() const noexcept; @@ -243,7 +249,8 @@ namespace clap { 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_timer_support *hostTimerSupport_ = nullptr; + const clap_host_fd_support *hostFdSupport_ = nullptr; const clap_host_params *hostParams_ = nullptr; const clap_host_track_info *hostTrackInfo_ = nullptr; const clap_host_state *hostState_ = nullptr; @@ -329,9 +336,11 @@ namespace clap { uint32_t index, clap_note_name *note_name) noexcept; - // clap_plugin_event_loop - static void clapEventLoopOnTimer(const clap_plugin *plugin, clap_id timer_id) noexcept; - static void clapEventLoopOnFd(const clap_plugin *plugin, clap_fd fd, uint32_t flags) noexcept; + // clap_plugin_timer_support + static void clapOnTimer(const clap_plugin *plugin, clap_id timer_id) noexcept; + + // clap_plugin_fd_support + static void clapOnFd(const clap_plugin *plugin, clap_fd fd, uint32_t flags) noexcept; // clap_plugin_gui static bool clapGuiCreate(const clap_plugin *plugin) noexcept; @@ -385,7 +394,10 @@ namespace clap { static const constexpr clap_plugin_audio_ports pluginAudioPorts_ = { clapAudioPortsCount, - clapAudioPortsInfo, + clapAudioPortsInfo + }; + + static const constexpr clap_plugin_audio_ports_config pluginAudioPortsConfig_ = { clapAudioPortsConfigCount, clapAudioPortsGetConfig, clapAudioPortsSetConfig, @@ -415,9 +427,12 @@ namespace clap { clapNoteNameGet, }; - static const constexpr clap_plugin_event_loop pluginEventLoop_ = { - clapEventLoopOnTimer, - clapEventLoopOnFd, + static const constexpr clap_plugin_timer_support pluginTimerSupport_ = { + clapOnTimer + }; + + static const constexpr clap_plugin_fd_support pluginFdSupport_ = { + clapOnFd, }; static const constexpr clap_plugin_gui pluginGui_ = { diff --git a/examples/host/plugin-host.cc b/examples/host/plugin-host.cc @@ -29,34 +29,12 @@ PluginHost::PluginHost(Engine &engine) : QObject(&engine), engine_(engine) { host_.host_data = this; host_.clap_version = CLAP_VERSION; - host_.extension = PluginHost::clapExtension; + host_.get_extension = PluginHost::clapExtension; host_.name = "Clap Test Host"; host_.version = "0.1.0"; host_.vendor = "clap"; host_.url = "https://github.com/free-audio/clap"; - hostLog_.log = PluginHost::clapLog; - - hostGui_.resize = PluginHost::clapGuiResize; - - hostThreadCheck_.is_main_thread = PluginHost::clapIsMainThread; - hostThreadCheck_.is_audio_thread = PluginHost::clapIsAudioThread; - - hostThreadPool_.request_exec = PluginHost::clapThreadPoolRequestExec; - - hostEventLoop_.register_timer = PluginHost::clapEventLoopRegisterTimer; - hostEventLoop_.unregister_timer = PluginHost::clapEventLoopUnregisterTimer; - hostEventLoop_.register_fd = PluginHost::clapEventLoopRegisterFd; - hostEventLoop_.modify_fd = PluginHost::clapEventLoopModifyFd; - hostEventLoop_.unregister_fd = PluginHost::clapEventLoopUnregisterFd; - - hostParams_.rescan = PluginHost::clapParamsRescan; - - hostQuickControls_.pages_changed = PluginHost::clapQuickControlsPagesChanged; - hostQuickControls_.selected_page_changed = PluginHost::clapQuickControlsSelectedPageChanged; - - hostState_.mark_dirty = PluginHost::clapStateMarkDirty; - initThreadPool(); } @@ -171,7 +149,8 @@ void PluginHost::initPluginExtensions() { initPluginExtension(pluginGuiWin32_, CLAP_EXT_GUI_WIN32); initPluginExtension(pluginGuiCocoa_, CLAP_EXT_GUI_COCOA); initPluginExtension(pluginGuiFreeStanding_, CLAP_EXT_GUI_FREE_STANDING); - initPluginExtension(pluginEventLoop_, CLAP_EXT_EVENT_LOOP); + initPluginExtension(pluginTimerSupport_, CLAP_EXT_TIMER_SUPPORT); + initPluginExtension(pluginFdSupport_, CLAP_EXT_FD_SUPPORT); initPluginExtension(pluginThreadPool_, CLAP_EXT_THREAD_POOL); initPluginExtension(pluginPresetLoad_, CLAP_EXT_PRESET_LOAD); initPluginExtension(pluginState_, CLAP_EXT_STATE); @@ -255,8 +234,7 @@ void PluginHost::setPorts(int numInputs, float **inputs, int numOutputs, float * void PluginHost::setParentWindow(WId parentWindow) { checkForMainThread(); - if (isGuiCreated_) - { + if (isGuiCreated_) { pluginGui_->destroy(plugin_); isGuiCreated_ = false; isGuiVisible_ = false; @@ -272,7 +250,7 @@ void PluginHost::setParentWindow(WId parentWindow) { uint32_t height = 0; if (pluginGui_) - pluginGui_->size(plugin_, &width, &height); + pluginGui_->get_size(plugin_, &width, &height); #if defined(Q_OS_LINUX) if (pluginGuiX11_) @@ -301,8 +279,7 @@ void PluginHost::setPluginWindowVisibility(bool isVisible) { if (isVisible && !isGuiVisible_) { pluginGui_->show(plugin_); isGuiVisible_ = true; - } else if (!isVisible && isGuiVisible_) - { + } else if (!isVisible && isGuiVisible_) { pluginGui_->hide(plugin_); isGuiVisible_ = false; } @@ -332,7 +309,7 @@ void PluginHost::initPluginExtension(const T *&ext, const char *id) { checkForMainThread(); if (!ext) - ext = static_cast<const T *>(plugin_->extension(plugin_, id)); + ext = static_cast<const T *>(plugin_->get_extension(plugin_, id)); } const void *PluginHost::clapExtension(const clap_host *host, const char *extension) { @@ -349,8 +326,10 @@ const void *PluginHost::clapExtension(const clap_host *host, const char *extensi return &h->hostLog_; if (!strcmp(extension, CLAP_EXT_THREAD_CHECK)) return &h->hostThreadCheck_; - if (!strcmp(extension, CLAP_EXT_EVENT_LOOP)) - return &h->hostEventLoop_; + if (!strcmp(extension, CLAP_EXT_TIMER_SUPPORT)) + return &h->hostTimerSupport_; + if (!strcmp(extension, CLAP_EXT_FD_SUPPORT)) + return &h->hostFdSupport_; if (!strcmp(extension, CLAP_EXT_PARAMS)) return &h->hostParams_; if (!strcmp(extension, CLAP_EXT_QUICK_CONTROLS)) @@ -405,16 +384,15 @@ bool PluginHost::clapThreadPoolRequestExec(const clap_host *host, uint32_t num_t return true; } -bool PluginHost::clapEventLoopRegisterTimer(const clap_host *host, - uint32_t period_ms, - clap_id *timer_id) { +bool PluginHost::clapRegisterTimer(const clap_host *host, uint32_t period_ms, clap_id *timer_id) { checkForMainThread(); auto h = fromHost(host); h->initPluginExtensions(); - if (!h->pluginEventLoop_ || !h->pluginEventLoop_->on_timer) - throw std::logic_error("Called register_timer() without providing clap_plugin_event_loop to " - "receive the timer event."); + if (!h->pluginTimerSupport_ || !h->pluginTimerSupport_->on_timer) + throw std::logic_error( + "Called register_timer() without providing clap_plugin_timer_support.on_timer() to " + "receive the timer event."); auto id = h->nextTimerId_++; *timer_id = id; @@ -422,7 +400,7 @@ bool PluginHost::clapEventLoopRegisterTimer(const clap_host *host, QObject::connect(timer.get(), &QTimer::timeout, [h, id] { checkForMainThread(); - h->pluginEventLoop_->on_timer(h->plugin_, id); + h->pluginTimerSupport_->on_timer(h->plugin_, id); }); auto t = timer.get(); @@ -431,13 +409,13 @@ bool PluginHost::clapEventLoopRegisterTimer(const clap_host *host, return true; } -bool PluginHost::clapEventLoopUnregisterTimer(const clap_host *host, clap_id timer_id) { +bool PluginHost::clapUnregisterTimer(const clap_host *host, clap_id timer_id) { checkForMainThread(); auto h = fromHost(host); - if (!h->pluginEventLoop_ || !h->pluginEventLoop_->on_timer) + if (!h->pluginTimerSupport_ || !h->pluginTimerSupport_->on_timer) throw std::logic_error( - "Called unregister_timer() without providing clap_plugin_event_loop to " + "Called unregister_timer() without providing clap_plugin_timer_support.on_timer() to " "receive the timer event."); auto it = h->timers_.find(timer_id); @@ -448,13 +426,13 @@ bool PluginHost::clapEventLoopUnregisterTimer(const clap_host *host, clap_id tim return true; } -bool PluginHost::clapEventLoopRegisterFd(const clap_host *host, clap_fd fd, uint32_t flags) { +bool PluginHost::clapRegisterFd(const clap_host *host, clap_fd fd, uint32_t flags) { checkForMainThread(); auto h = fromHost(host); h->initPluginExtensions(); - if (!h->pluginEventLoop_ || !h->pluginEventLoop_->on_fd) - throw std::logic_error("Called register_fd() without providing clap_plugin_event_loop to " + if (!h->pluginFdSupport_ || !h->pluginFdSupport_->on_fd) + throw std::logic_error("Called register_fd() without providing clap_plugin_fd_support to " "receive the fd event."); auto it = h->fds_.find(fd); @@ -467,12 +445,12 @@ bool PluginHost::clapEventLoopRegisterFd(const clap_host *host, clap_fd fd, uint return true; } -bool PluginHost::clapEventLoopModifyFd(const clap_host *host, clap_fd fd, uint32_t flags) { +bool PluginHost::clapModifyFd(const clap_host *host, clap_fd fd, uint32_t flags) { checkForMainThread(); auto h = fromHost(host); - if (!h->pluginEventLoop_ || !h->pluginEventLoop_->on_fd) - throw std::logic_error("Called modify_fd() without providing clap_plugin_event_loop to " + if (!h->pluginFdSupport_ || !h->pluginFdSupport_->on_fd) + throw std::logic_error("Called modify_fd() without providing clap_plugin_fd_support to " "receive the timer event."); auto it = h->fds_.find(fd); @@ -485,12 +463,12 @@ bool PluginHost::clapEventLoopModifyFd(const clap_host *host, clap_fd fd, uint32 return true; } -bool PluginHost::clapEventLoopUnregisterFd(const clap_host *host, clap_fd fd) { +bool PluginHost::clapUnregisterFd(const clap_host *host, clap_fd fd) { checkForMainThread(); auto h = fromHost(host); - if (!h->pluginEventLoop_ || !h->pluginEventLoop_->on_fd) - throw std::logic_error("Called unregister_fd() without providing clap_plugin_event_loop to " + if (!h->pluginFdSupport_ || !h->pluginFdSupport_->on_fd) + throw std::logic_error("Called unregister_fd() without providing clap_plugin_fd_support to " "receive the fd event."); auto it = h->fds_.find(fd); @@ -512,7 +490,7 @@ void PluginHost::eventLoopSetFdNotifierFlags(clap_fd fd, uint32_t flags) { it->second->rd.reset(new QSocketNotifier(fd, QSocketNotifier::Read)); QObject::connect(it->second->rd.get(), &QSocketNotifier::activated, [this, fd] { checkForMainThread(); - this->pluginEventLoop_->on_fd(this->plugin_, fd, CLAP_FD_READ); + this->pluginFdSupport_->on_fd(this->plugin_, fd, CLAP_FD_READ); }); } it->second->rd->setEnabled(true); @@ -524,7 +502,7 @@ void PluginHost::eventLoopSetFdNotifierFlags(clap_fd fd, uint32_t flags) { it->second->wr.reset(new QSocketNotifier(fd, QSocketNotifier::Write)); QObject::connect(it->second->wr.get(), &QSocketNotifier::activated, [this, fd] { checkForMainThread(); - this->pluginEventLoop_->on_fd(this->plugin_, fd, CLAP_FD_WRITE); + this->pluginFdSupport_->on_fd(this->plugin_, fd, CLAP_FD_WRITE); }); } it->second->wr->setEnabled(true); @@ -536,7 +514,7 @@ void PluginHost::eventLoopSetFdNotifierFlags(clap_fd fd, uint32_t flags) { it->second->err.reset(new QSocketNotifier(fd, QSocketNotifier::Exception)); QObject::connect(it->second->err.get(), &QSocketNotifier::activated, [this, fd] { checkForMainThread(); - this->pluginEventLoop_->on_fd(this->plugin_, fd, CLAP_FD_ERROR); + this->pluginFdSupport_->on_fd(this->plugin_, fd, CLAP_FD_ERROR); }); } it->second->err->setEnabled(true); @@ -552,6 +530,15 @@ bool PluginHost::clapGuiResize(const clap_host *host, uint32_t width, uint32_t h } void PluginHost::processBegin(int nframes) { + g_thread_type = AudioThread; + + process_.frames_count = nframes; + process_.steady_time = engine_.steadyTime_; +} + +void PluginHost::processEnd(int nframes) { + g_thread_type = Unknown; + process_.frames_count = nframes; process_.steady_time = engine_.steadyTime_; } @@ -635,7 +622,6 @@ void clap_host_event_list_push_back(const struct clap_event_list *list, } void PluginHost::process() { - g_thread_type = AudioThread; checkForAudioThread(); if (!isPluginProcessing() && !isPluginSleeping()) @@ -807,7 +793,7 @@ void PluginHost::clapParamsRescan(const clap_host *host, uint32_t flags) { for (int32_t i = 0; i < count; ++i) { clap_param_info info; - if (!h->pluginParams_->info(h->plugin_, i, &info)) + if (!h->pluginParams_->get_info(h->plugin_, i, &info)) throw std::logic_error("clap_plugin_params.get_info did return false!"); if (info.id == CLAP_INVALID_ID) { @@ -914,7 +900,7 @@ void PluginHost::clapParamsRescan(const clap_host *host, uint32_t flags) { double PluginHost::getParamValue(const clap_param_info &info) { checkForMainThread(); double value; - if (pluginParams_->value(plugin_, info.id, &value)) + if (pluginParams_->get_value(plugin_, info.id, &value)) return value; std::ostringstream msg; @@ -929,7 +915,7 @@ void PluginHost::scanQuickControls() { if (!pluginQuickControls_) return; - if (!pluginQuickControls_->page_info || !pluginQuickControls_->page_count) { + if (!pluginQuickControls_->get || !pluginQuickControls_->count) { std::ostringstream msg; msg << "clap_plugin_quick_controls is partially implemented."; throw std::logic_error(msg.str()); @@ -938,7 +924,7 @@ void PluginHost::scanQuickControls() { quickControlsSetSelectedPage(CLAP_INVALID_ID); quickControlsPages_.clear(); - const auto N = pluginQuickControls_->page_count(plugin_); + const auto N = pluginQuickControls_->count(plugin_); if (N == 0) return; @@ -947,7 +933,7 @@ void PluginHost::scanQuickControls() { clap_id firstPageId = CLAP_INVALID_ID; for (int i = 0; i < N; ++i) { auto page = std::make_unique<clap_quick_controls_page>(); - if (!pluginQuickControls_->page_info(plugin_, i, page.get())) { + if (!pluginQuickControls_->get(plugin_, i, page.get())) { std::ostringstream msg; msg << "clap_plugin_quick_controls.get_page(" << i << ") failed, while the page count is " << N; @@ -978,7 +964,7 @@ void PluginHost::scanQuickControls() { quickControlsPagesChanged(); - auto pageId = pluginQuickControls_->selected_page(plugin_); + auto pageId = pluginQuickControls_->get_selected(plugin_); quickControlsSetSelectedPage(pageId == CLAP_INVALID_ID ? firstPageId : pageId); } @@ -1008,34 +994,29 @@ void PluginHost::setQuickControlsSelectedPageByHost(clap_id page_id) { quickControlsSelectedPage_ = page_id; - if (pluginQuickControls_ && pluginQuickControls_->select_page) - pluginQuickControls_->select_page(plugin_, page_id); + if (pluginQuickControls_ && pluginQuickControls_->select) + pluginQuickControls_->select(plugin_, page_id); } -void PluginHost::clapQuickControlsPagesChanged(const clap_host *host) { +void PluginHost::clapQuickControlsChanged(const clap_host *host, + clap_quick_controls_changed_flags flags) { checkForMainThread(); auto h = fromHost(host); if (!h->pluginQuickControls_) { std::ostringstream msg; - msg << "Plugin called clap_host_quick_controls.pages_changed() but does not provide " + msg << "Plugin called clap_host_quick_controls.changed() but does not provide " "clap_plugin_quick_controls"; throw std::logic_error(msg.str()); } - h->scanQuickControls(); -} -void PluginHost::clapQuickControlsSelectedPageChanged(const clap_host *host, clap_id page_id) { - checkForMainThread(); + if (flags & CLAP_QUICK_CONTROLS_PAGES_CHANGED) + h->scanQuickControls(); - auto h = fromHost(host); - if (!h->pluginQuickControls_) { - std::ostringstream msg; - msg << "Plugin called clap_host_quick_controls.selected_page_changed() but does not provide " - "clap_plugin_quick_controls"; - throw std::logic_error(msg.str()); + if (flags & CLAP_QUICK_CONTROLS_SELECTED_PAGE_CHANGED) { + auto selectedPageId = h->pluginQuickControls_->get_selected(h->plugin_); + h->quickControlsSetSelectedPage(selectedPageId); } - h->quickControlsSetSelectedPage(page_id); } bool PluginHost::loadNativePluginPreset(const std::string &path) { @@ -1085,7 +1066,8 @@ void PluginHost::setPluginState(PluginState state) { break; case ActiveAndReadyToDeactivate: - Q_ASSERT(state_ == ActiveAndProcessing || state_ == ActiveAndSleeping || state_ == ActiveWithError); + Q_ASSERT(state_ == ActiveAndProcessing || state_ == ActiveAndSleeping || + state_ == ActiveWithError); break; default: diff --git a/examples/host/plugin-host.hh b/examples/host/plugin-host.hh @@ -15,8 +15,8 @@ #include <clap/all.h> -#include "engine.hh" #include "../common/param-queue.hh" +#include "engine.hh" #include "plugin-param.hh" class Engine; @@ -47,6 +47,7 @@ public: void processPitchBend(int sampleOffset, int channel, int value); void processCC(int sampleOffset, int channel, int cc, int value); void process(); + void processEnd(int nframes); void idle(); @@ -104,15 +105,14 @@ private: void scanQuickControls(); void quickControlsSetSelectedPage(clap_id pageId); - static void clapQuickControlsPagesChanged(const clap_host *host); - static void clapQuickControlsSelectedPageChanged(const clap_host *host, clap_id page_id); + static void clapQuickControlsChanged(const clap_host *host, clap_quick_controls_changed_flags flags); static bool - clapEventLoopRegisterTimer(const clap_host *host, uint32_t period_ms, clap_id *timer_id); - static bool clapEventLoopUnregisterTimer(const clap_host *host, clap_id timer_id); - static bool clapEventLoopRegisterFd(const clap_host *host, clap_fd fd, uint32_t flags); - static bool clapEventLoopModifyFd(const clap_host *host, clap_fd fd, uint32_t flags); - static bool clapEventLoopUnregisterFd(const clap_host *host, clap_fd fd); + clapRegisterTimer(const clap_host *host, uint32_t period_ms, clap_id *timer_id); + static bool clapUnregisterTimer(const clap_host *host, clap_id timer_id); + static bool clapRegisterFd(const clap_host *host, clap_fd fd, uint32_t flags); + static bool clapModifyFd(const clap_host *host, clap_fd fd, uint32_t flags); + static bool clapUnregisterFd(const clap_host *host, clap_fd fd); void eventLoopSetFdNotifierFlags(clap_fd fd, uint32_t flags); static bool clapThreadPoolRequestExec(const clap_host *host, uint32_t num_tasks); @@ -130,15 +130,39 @@ private: QLibrary library_; clap_host host_; - clap_host_log hostLog_; - clap_host_gui hostGui_; - clap_host_audio_ports hostAudioPorts_; - clap_host_params hostParams_; - clap_host_quick_controls hostQuickControls_; - clap_host_event_loop hostEventLoop_; - clap_host_thread_check hostThreadCheck_; - clap_host_thread_pool hostThreadPool_; - clap_host_state hostState_; + static const constexpr clap_host_log hostLog_ = { + PluginHost::clapLog, + }; + static const constexpr clap_host_gui hostGui_ = { + PluginHost::clapGuiResize, + }; + //static const constexpr clap_host_audio_ports hostAudioPorts_; + //static const constexpr clap_host_audio_ports_config hostAudioPortsConfig_; + static const constexpr clap_host_params hostParams_ = { +PluginHost::clapParamsRescan, + }; + static const constexpr clap_host_quick_controls hostQuickControls_ = { + PluginHost::clapQuickControlsChanged, + }; + static const constexpr clap_host_timer_support hostTimerSupport_ = { + PluginHost::clapRegisterTimer, + PluginHost::clapUnregisterTimer, + }; + static const constexpr clap_host_fd_support hostFdSupport_ = { + PluginHost::clapRegisterFd, + PluginHost::clapModifyFd, + PluginHost::clapUnregisterFd, + }; + static const constexpr clap_host_thread_check hostThreadCheck_ = { + PluginHost::clapIsMainThread, + PluginHost::clapIsAudioThread, + }; + static const constexpr clap_host_thread_pool hostThreadPool_ = { + PluginHost::clapThreadPoolRequestExec, + }; + static const constexpr clap_host_state hostState_ = { + PluginHost::clapStateMarkDirty, + }; const struct clap_plugin_entry *pluginEntry_ = nullptr; const clap_plugin *plugin_ = nullptr; @@ -150,7 +174,8 @@ private: const clap_plugin_gui_win32 *pluginGuiWin32_ = nullptr; const clap_plugin_gui_cocoa *pluginGuiCocoa_ = nullptr; const clap_plugin_gui_free_standing *pluginGuiFreeStanding_ = nullptr; - const clap_plugin_event_loop *pluginEventLoop_ = nullptr; + const clap_plugin_timer_support *pluginTimerSupport_ = nullptr; + const clap_plugin_fd_support *pluginFdSupport_ = nullptr; const clap_plugin_thread_pool *pluginThreadPool_ = nullptr; const clap_plugin_preset_load *pluginPresetLoad_ = nullptr; const clap_plugin_state *pluginState_ = nullptr; diff --git a/examples/io/remote-channel.cc b/examples/io/remote-channel.cc @@ -95,7 +95,6 @@ namespace clap { if (socket_ == -1) return; - modifyFd(0); evControl_.removeFd(); ::close(socket_); diff --git a/examples/plugins/core-plugin.cc b/examples/plugins/core-plugin.cc @@ -134,12 +134,12 @@ namespace clap { remoteGui_->hide(); } - void CorePlugin::eventLoopOnFd(clap_fd fd, uint32_t flags) noexcept { + void CorePlugin::onFd(clap_fd fd, uint32_t flags) noexcept { if (remoteGui_ && fd == remoteGui_->fd()) remoteGui_->onFd(flags); } - void CorePlugin::eventLoopOnTimer(clap_id timerId) noexcept { + void CorePlugin::onTimer(clap_id timerId) noexcept { if (remoteGui_ && timerId == remoteGui_->timerId()) remoteGui_->onTimer(); } diff --git a/examples/plugins/core-plugin.hh b/examples/plugins/core-plugin.hh @@ -138,12 +138,17 @@ namespace clap { return hasTrackInfo_ ? trackInfo_.channel_map : CLAP_CHMAP_STEREO; } + //---------------------------// + // clap_plugin_timer_support // + //---------------------------// + bool implementsTimerSupport() const noexcept override { return true; } + void onTimer(clap_id timerId) noexcept override; + //------------------------// - // clap_plugin_event_loop // + // clap_plugin_fd_support // //------------------------// - bool implementsEventLoop() const noexcept override { return true; } - void eventLoopOnFd(clap_fd fd, uint32_t flags) noexcept override; - void eventLoopOnTimer(clap_id timerId) noexcept override; + bool implementsFdSupport() const noexcept override { return true; } + void onFd(clap_fd fd, uint32_t flags) noexcept override; protected: friend class RemoteGui; diff --git a/examples/plugins/remote-gui.cc b/examples/plugins/remote-gui.cc @@ -22,6 +22,9 @@ namespace clap { assert(child_ == -1); assert(!channel_); + if (!plugin_.canUseTimerSupport() || !plugin_.canUseFdSupport()) + return false; + auto &pathProvider = plugin_.pathProvider(); #ifdef __unix__ @@ -70,8 +73,8 @@ namespace clap { } timerId_ = CLAP_INVALID_ID; - plugin_.hostEventLoop_->register_timer(plugin_.host_, 1000 / 60, &timerId_); - plugin_.hostEventLoop_->register_fd(plugin_.host_, sockets[0], CLAP_FD_READ | CLAP_FD_ERROR); + plugin_.hostTimerSupport_->register_timer(plugin_.host_, 1000 / 60, &timerId_); + plugin_.hostFdSupport_->register_fd(plugin_.host_, sockets[0], CLAP_FD_READ | CLAP_FD_ERROR); channel_.reset(new RemoteChannel( [this](const RemoteChannel::Message &msg) { onMessage(msg); }, *this, sockets[0], true)); @@ -82,12 +85,12 @@ namespace clap { } void RemoteGui::modifyFd(clap_fd_flags flags) { - plugin_.hostEventLoop_->modify_fd(plugin_.host_, channel_->fd(), flags); + plugin_.hostFdSupport_->modify_fd(plugin_.host_, channel_->fd(), flags); } void RemoteGui::removeFd() { - plugin_.hostEventLoop_->unregister_fd(plugin_.host_, channel_->fd()); - plugin_.hostEventLoop_->unregister_timer(plugin_.host_, timerId_); + plugin_.hostFdSupport_->unregister_fd(plugin_.host_, channel_->fd()); + plugin_.hostTimerSupport_->unregister_timer(plugin_.host_, timerId_); } clap_fd RemoteGui::fd() const { return channel_ ? channel_->fd() : -1; } diff --git a/include/clap/all.h b/include/clap/all.h @@ -3,6 +3,7 @@ #include "clap.h" #include "ext/audio-ports.h" +#include "ext/audio-ports-config.h" #include "ext/gui.h" #include "ext/gui-x11.h" #include "ext/gui-win32.h" @@ -14,7 +15,8 @@ #include "ext/state.h" #include "ext/latency.h" #include "ext/thread-check.h" -#include "ext/event-loop.h" +#include "ext/timer-support.h" +#include "ext/fd-support.h" #include "ext/note-name.h" #include "ext/event-filter.h" diff --git a/include/clap/clap.h b/include/clap/clap.h @@ -108,7 +108,7 @@ typedef struct clap_host { // Query an extension. // [thread-safe] - const void *(*extension)(const struct clap_host *host, const char *extension_id); + const void *(*get_extension)(const struct clap_host *host, const char *extension_id); // Request the host to deactivate and then reactivate the plugin. // The operation may be delayed by the host. @@ -199,9 +199,10 @@ typedef struct clap_plugin { * [audio-thread] */ clap_process_status (*process)(const struct clap_plugin *plugin, const clap_process *process); - /* query an extension + /* Query an extension. + * The returned pointer is owned by the plugin. * [thread-safe] */ - const void *(*extension)(const struct clap_plugin *plugin, const char *id); + const void *(*get_extension)(const struct clap_plugin *plugin, const char *id); } clap_plugin; ///////////////// diff --git a/include/clap/events.h b/include/clap/events.h @@ -11,16 +11,17 @@ extern "C" { #endif enum { - CLAP_EVENT_NOTE_ON, // note attribute - CLAP_EVENT_NOTE_OFF, // note attribute - CLAP_EVENT_NOTE_EXPRESSION, // note_expression attribute - CLAP_EVENT_CHOKE, // no attribute - CLAP_EVENT_PARAM_VALUE, // param_value attribute - CLAP_EVENT_PARAM_MOD, // param_mod attribute - CLAP_EVENT_TRANSPORT, // transport attribute - CLAP_EVENT_NOTE_MASK, // note_mask attribute - CLAP_EVENT_MIDI, // midi attribute - CLAP_EVENT_MIDI_SYSEX, // midi attribute + CLAP_EVENT_NOTE_ON, // press a key; note attribute + CLAP_EVENT_NOTE_OFF, // release a key; note attribute + CLAP_EVENT_NOTE_END, // playback of a note is terminated (sent by the plugin); note attribute + CLAP_EVENT_NOTE_CHOKE, // chokes a set of notes; note attribute + CLAP_EVENT_NOTE_EXPRESSION, // plays standard note expression; note_expression attribute + CLAP_EVENT_NOTE_MASK, // current chord/scale; note_mask attribute + CLAP_EVENT_PARAM_VALUE, // sets a parameter value; param_value attribute + CLAP_EVENT_PARAM_MOD, // sets a parameter modulation; param_mod attribute + CLAP_EVENT_TRANSPORT, // update the transport info; transport attribute + CLAP_EVENT_MIDI, // raw midi event; midi attribute + CLAP_EVENT_MIDI_SYSEX, // raw midi sysex event; midi_sysex attribute }; typedef int32_t clap_event_type; @@ -28,7 +29,12 @@ typedef uint32_t clap_id; static const clap_id CLAP_INVALID_ID = UINT32_MAX; -/** Note On/Off event. */ +/** + * Note on, off, end and choke events. + * In the case of note choke or end events: + * - the velocity is ignored. + * - key and channel are used to match active notes, a value of -1 matches all. + */ typedef struct clap_event_note { int32_t key; // 0..127 int32_t channel; // 0..15 diff --git a/include/clap/ext/audio-ports-config.h b/include/clap/ext/audio-ports-config.h @@ -0,0 +1,68 @@ +#pragma once + +#include "../clap.h" +#include "../chmap.h" + +/// @page Audio Ports Config +/// +/// This extension provides a way for the plugin to describe possible ports configurations, for +/// example mono, stereo, surround, ... and a way for the host to select a configuration. +/// +/// After the plugin initialization, the host may scan the list of configurations and eventually +/// select one that fits the plugin context. The host can only select a configuration if the plugin +/// is deactivated. +/// +/// A configuration is a very simple description of the audio ports: +/// - it describes the main input and output ports +/// - it has a name that can be displayed to the user +/// +/// The idea behind the configurations, is to let the user choose one via a menu. +/// +/// Plugin with very complex configuration possibilities should let the user configure the ports +/// from the plugin GUI, and call @ref clap_host_audio_ports.rescan(CLAP_AUDIO_PORTS_RESCAN_ALL). + +static CLAP_CONSTEXPR const char CLAP_EXT_AUDIO_PORTS_CONFIG[] = "clap.audio-ports-config"; + +#ifdef __cplusplus +extern "C" { +#endif + +// Minimalistic description of ports configuration +typedef struct clap_audio_ports_config { + clap_id id; + char name[CLAP_NAME_SIZE]; + + // main input info + uint32_t input_channel_count; + clap_chmap input_channel_map; + + // main output info + uint32_t output_channel_count; + clap_chmap output_channel_map; +} clap_audio_ports_config; + +// The audio ports config scan has to be done while the plugin is deactivated. +typedef struct clap_plugin_audio_ports_config { + // gets the number of available configurations + // [main-thread] + uint32_t (*count)(const clap_plugin *plugin); + + // gets information about a configuration + // [main-thread] + bool (*get)(const clap_plugin *plugin, uint32_t index, clap_audio_ports_config *config); + + // selects the configuration designated by id + // returns true if the configuration could be applied + // [main-thread,plugin-deactivated] + bool (*select)(const clap_plugin *plugin, clap_id config_id); +} clap_plugin_audio_ports_config; + +typedef struct clap_host_audio_ports_config { + // Rescan the full list of configs. + // [main-thread] + void (*rescan)(const clap_host *host); +} clap_host_audio_ports_config; + +#ifdef __cplusplus +} +#endif diff --git a/include/clap/ext/audio-ports.h b/include/clap/ext/audio-ports.h @@ -51,45 +51,18 @@ typedef struct clap_audio_port_info { } clap_audio_port_info; -// Minimalistic description of ports configuration -typedef struct clap_audio_ports_config { - clap_id id; - char name[CLAP_NAME_SIZE]; - - // main input info - uint32_t input_channel_count; - clap_chmap input_channel_map; - - // main output info - uint32_t output_channel_count; - clap_chmap output_channel_map; -} clap_audio_ports_config; - // The audio ports scan has to be done while the plugin is deactivated. typedef struct clap_plugin_audio_ports { // number of ports, for either input or output // [main-thread] - uint32_t (*port_count)(const clap_plugin *plugin, bool is_input); + uint32_t (*count)(const clap_plugin *plugin, bool is_input); // get info about about an audio port. // [main-thread] - bool (*port_info)(const clap_plugin * plugin, - uint32_t index, - bool is_input, - clap_audio_port_info *info); - - // gets the number of available configurations - // [main-thread] - uint32_t (*config_count)(const clap_plugin *plugin); - - // gets information about a configuration - // [main-thread] - bool (*config_info)(const clap_plugin *plugin, uint32_t index, clap_audio_ports_config *config); - - // selects the configuration designated by id - // returns true if the configuration could be applied - // [main-thread,plugin-deactivated] - bool (*select_config)(const clap_plugin *plugin, clap_id config_id); + bool (*get)(const clap_plugin * plugin, + uint32_t index, + bool is_input, + clap_audio_port_info *info); } clap_plugin_audio_ports; enum { @@ -101,14 +74,11 @@ enum { // The ports name did change, the host can scan them right away. CLAP_AUDIO_PORTS_RESCAN_NAMES = 1 << 1, - - // The list of configurations did change. - CLAP_AUDIO_PORTS_RESCAN_CONFIGS = 1 << 2, }; typedef struct clap_host_audio_ports { // [main-thread] - uint32_t (*preferred_sample_size)(const clap_host *host); + uint32_t (*get_preferred_sample_size)(const clap_host *host); // Rescan the full list of audio ports according to the flags. // [main-thread] diff --git a/include/clap/ext/draft/quick-controls.h b/include/clap/ext/draft/quick-controls.h @@ -19,28 +19,28 @@ typedef struct clap_quick_controls_page { typedef struct clap_plugin_quick_controls { // [main-thread] - uint32_t (*page_count)(const clap_plugin *plugin); + uint32_t (*count)(const clap_plugin *plugin); // [main-thread] - bool (*page_info)(const clap_plugin * plugin, - uint32_t page_index, - clap_quick_controls_page *page); + bool (*get)(const clap_plugin *plugin, uint32_t page_index, clap_quick_controls_page *page); // [main-thread] - void (*select_page)(const clap_plugin *plugin, clap_id page_id); + void (*select)(const clap_plugin *plugin, clap_id page_id); // [main-thread] - clap_id (*selected_page)(const clap_plugin *plugin); -} clap_host_plugin_info; + clap_id (*get_selected)(const clap_plugin *plugin); +} clap_plugin_quick_controls; -typedef struct clap_host_quick_controls { - // Informs the host that the quick controls pages has changed. - // [main-thread] - void (*pages_changed)(const clap_host *host); +enum { + CLAP_QUICK_CONTROLS_PAGES_CHANGED = 1 << 0, + CLAP_QUICK_CONTROLS_SELECTED_PAGE_CHANGED = 1 << 1, +}; +typedef uint32_t clap_quick_controls_changed_flags; - // Informs the host that the user did change the selected page, from the plugin. +typedef struct clap_host_quick_controls { + // Informs the host that the quick controls have changed. // [main-thread] - void (*selected_page_changed)(const clap_host *host, clap_id page_id); + void (*changed)(const clap_host *host, clap_quick_controls_changed_flags flags); } clap_host_quick_controls; #ifdef __cplusplus diff --git a/include/clap/ext/draft/tuning.h b/include/clap/ext/draft/tuning.h @@ -16,7 +16,7 @@ typedef struct clap_host_tuning { // The plugin is not supposed to query it for each samples, // but at a rate that makes sense for low frequency modulations. // [audio-thread] - double (*key_freq)(const clap_host *host, int32_t key, int32_t channel, int32_t frameIndex); + double (*get)(const clap_host *host, int32_t key, int32_t channel); } clap_host_tuning; #ifdef __cplusplus diff --git a/include/clap/ext/event-filter.h b/include/clap/ext/event-filter.h @@ -12,7 +12,7 @@ extern "C" { // in. typedef struct clap_plugin_event_filter { // Returns true if the plugin is interested in the given event type. - // [audio-thread] + // [main-thread] bool (*accepts)(const clap_plugin *plugin, clap_event_type event_type); } clap_plugin_event_filter; diff --git a/include/clap/ext/event-loop.h b/include/clap/ext/event-loop.h @@ -1,62 +0,0 @@ -#pragma once - -#include <stddef.h> - -#include "../clap.h" - -static CLAP_CONSTEXPR const char CLAP_EXT_EVENT_LOOP[] = "clap.event-loop"; - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef _WIN32 -typedef void *clap_fd; -#else -typedef int clap_fd; -#endif - -enum { - // IO events - CLAP_FD_READ = 1 << 0, - CLAP_FD_WRITE = 1 << 1, - CLAP_FD_ERROR = 1 << 2, -}; -typedef uint32_t clap_fd_flags; - -typedef struct clap_plugin_event_loop { - // [main-thread] - void (*on_timer)(const clap_plugin *plugin, clap_id timer_id); - - // This callback is "level-triggered". - // It means that a writable fd will continuously produce "on_fd()" events; - // don't forget using modify_fd() to remove the write notification once you're - // done writting. - // - // [main-thread] - void (*on_fd)(const clap_plugin *plugin, clap_fd fd, clap_fd_flags flags); -} clap_plugin_event_loop; - -typedef struct clap_host_event_loop { - // Registers a periodic timer. - // The host may adjust the period if it is under a certain threshold. - // 30 Hz should be allowed. - // [main-thread] - bool (*register_timer)(const clap_host *host, uint32_t period_ms, clap_id *timer_id); - - // [main-thread] - bool (*unregister_timer)(const clap_host *host, clap_id timer_id); - - // [main-thread] - bool (*register_fd)(const clap_host *host, clap_fd fd, clap_fd_flags flags); - - // [main-thread] - bool (*modify_fd)(const clap_host *host, clap_fd fd, clap_fd_flags flags); - - // [main-thread] - bool (*unregister_fd)(const clap_host *host, clap_fd fd); -} clap_host_event_loop; - -#ifdef __cplusplus -} -#endif -\ No newline at end of file diff --git a/include/clap/ext/fd-support.h b/include/clap/ext/fd-support.h @@ -0,0 +1,50 @@ +#pragma once + +#include <stddef.h> + +#include "../clap.h" + +static CLAP_CONSTEXPR const char CLAP_EXT_FD_SUPPORT[] = "clap.fd-support"; + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _WIN32 +typedef void *clap_fd; +#else +typedef int clap_fd; +#endif + +enum { + // IO events + CLAP_FD_READ = 1 << 0, + CLAP_FD_WRITE = 1 << 1, + CLAP_FD_ERROR = 1 << 2, +}; +typedef uint32_t clap_fd_flags; + +typedef struct clap_plugin_fd_support { + // This callback is "level-triggered". + // It means that a writable fd will continuously produce "on_fd()" events; + // don't forget using modify_fd() to remove the write notification once you're + // done writting. + // + // [main-thread] + void (*on_fd)(const clap_plugin *plugin, clap_fd fd, clap_fd_flags flags); +} clap_plugin_fd_support; + +typedef struct clap_host_fd_support { + // [main-thread] + bool (*register_fd)(const clap_host *host, clap_fd fd, clap_fd_flags flags); + + // [main-thread] + bool (*modify_fd)(const clap_host *host, clap_fd fd, clap_fd_flags flags); + + // [main-thread] + bool (*unregister_fd)(const clap_host *host, clap_fd fd); +} clap_host_fd_support; + +#ifdef __cplusplus +} +#endif +\ No newline at end of file diff --git a/include/clap/ext/gui.h b/include/clap/ext/gui.h @@ -46,7 +46,7 @@ typedef struct clap_plugin_gui { // Get the current size of the plugin UI, with the scaling applied. // clap_plugin_gui->create() must have been called prior to asking the size. // [main-thread] - bool (*size)(const clap_plugin *plugin, uint32_t *width, uint32_t *height); + bool (*get_size)(const clap_plugin *plugin, uint32_t *width, uint32_t *height); // [main-thread] bool (*can_resize)(const clap_plugin *plugin); diff --git a/include/clap/ext/params.h b/include/clap/ext/params.h @@ -155,11 +155,11 @@ typedef struct clap_plugin_params { // Copies the parameter's info to param_info and returns true on success. // [main-thread] - bool (*info)(const clap_plugin *plugin, int32_t param_index, clap_param_info *param_info); + bool (*get_info)(const clap_plugin *plugin, int32_t param_index, clap_param_info *param_info); // Gets the parameter plain value. // [main-thread] - bool (*value)(const clap_plugin *plugin, clap_id param_id, double *value); + bool (*get_value)(const clap_plugin *plugin, clap_id param_id, double *value); // Formats the display text for the given parameter value. // [main-thread] diff --git a/include/clap/ext/render.h b/include/clap/ext/render.h @@ -24,7 +24,7 @@ typedef int32_t clap_plugin_render_mode; // implement this extension. typedef struct clap_plugin_render { // [main-thread] - void (*set_mode)(const clap_plugin *plugin, clap_plugin_render_mode mode); + void (*set)(const clap_plugin *plugin, clap_plugin_render_mode mode); } clap_plugin_render; #ifdef __cplusplus diff --git a/include/clap/ext/timer-support.h b/include/clap/ext/timer-support.h @@ -0,0 +1,31 @@ +#pragma once + +#include <stddef.h> + +#include "../clap.h" + +static CLAP_CONSTEXPR const char CLAP_EXT_TIMER_SUPPORT[] = "clap.timer-support"; + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct clap_plugin_timer_support { + // [main-thread] + void (*on_timer)(const clap_plugin *plugin, clap_id timer_id); +} clap_plugin_timer_support; + +typedef struct clap_host_timer_support { + // Registers a periodic timer. + // The host may adjust the period if it is under a certain threshold. + // 30 Hz should be allowed. + // [main-thread] + bool (*register_timer)(const clap_host *host, uint32_t period_ms, clap_id *timer_id); + + // [main-thread] + bool (*unregister_timer)(const clap_host *host, clap_id timer_id); +} clap_host_timer_support; + +#ifdef __cplusplus +} +#endif +\ No newline at end of file diff --git a/include/clap/version.h b/include/clap/version.h @@ -22,7 +22,7 @@ typedef struct clap_version { } #endif -static CLAP_CONSTEXPR const clap_version CLAP_VERSION = {0, 10, 0}; +static CLAP_CONSTEXPR const clap_version CLAP_VERSION = {0, 11, 0}; static CLAP_CONSTEXPR inline bool clap_version_is_compatible(const clap_version &v) { // For version 0, we require the same minor version because