clap

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

commit 53f1ca8bfd31f5cecba529d8ef0d0905748dc759
parent a618ebfd1017f556b1a8badf71b81e0c29aeeeea
Author: Alexandre BIQUE <bique.alexandre@gmail.com>
Date:   Fri, 27 Aug 2021 14:50:02 +0200

More work

Diffstat:
Mexamples/CMakeLists.txt | 2++
Aexamples/common/CMakeLists.txt | 4++++
Aexamples/common/param-queue.hh | 32++++++++++++++++++++++++++++++++
Aexamples/common/param-queue.hxx | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mexamples/gui/parameter-proxy.cc | 12+++---------
Mexamples/host/CMakeLists.txt | 2--
Dexamples/host/param-queue.cc | 51---------------------------------------------------
Dexamples/host/param-queue.hh | 35-----------------------------------
Mexamples/host/plugin-host.cc | 26+++++++++++++-------------
Mexamples/host/plugin-host.hh | 13+++++++++----
Mexamples/io/messages.hh | 15+--------------
Mexamples/plugins/core-plugin.cc | 6++++++
Mexamples/plugins/core-plugin.hh | 12++++++++++++
Mexamples/plugins/dc-offset/dc-offset.cc | 19+++++++++++++++++++
Mexamples/plugins/remote-gui.cc | 16+---------------
15 files changed, 161 insertions(+), 143 deletions(-)

diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt @@ -1,3 +1,5 @@ +add_subdirectory(common) + if(ENABLE_CLAP_GLUE) add_subdirectory(glue) endif() diff --git a/examples/common/CMakeLists.txt b/examples/common/CMakeLists.txt @@ -0,0 +1,3 @@ +# add_library(clap-common EXCLUDE_FROM_ALL +# param-queue.hxx +# param-queue.hh) +\ No newline at end of file diff --git a/examples/common/param-queue.hh b/examples/common/param-queue.hh @@ -0,0 +1,31 @@ +#pragma once + +#include <atomic> +#include <functional> +#include <unordered_map> + +#include <clap/all.h> + +template <typename T> +class ParamQueue { +public: + using value_type = T; + using queue_type = std::unordered_map<clap_id, value_type>; + + ParamQueue(); + + void setCapacity(size_t capacity); + + void set(clap_id id, const value_type& value); + void producerDone(); + + void consume(const std::function<void(clap_id id, const value_type& value)> consumer); + + void reset(); + +private: + queue_type queues_[2]; + std::atomic<queue_type *> free_ = nullptr; + std::atomic<queue_type *> producer_ = nullptr; + std::atomic<queue_type *> consumer_ = nullptr; +}; +\ No newline at end of file diff --git a/examples/common/param-queue.hxx b/examples/common/param-queue.hxx @@ -0,0 +1,59 @@ +#pragma once + +#include <cassert> + +#include "param-queue.hh" + +template<typename T> +ParamQueue<T>::ParamQueue() { reset(); } + +template<typename T> +void ParamQueue<T>::reset() { + for (auto &q : queues_) + q.clear(); + + free_ = &queues_[0]; + producer_ = &queues_[1]; + consumer_ = nullptr; +} + +template<typename T> +void ParamQueue<T>::setCapacity(size_t capacity) { + for (auto &q : queues_) + q.reserve(2 * capacity); +} + +template<typename T> +void ParamQueue<T>::set(clap_id id, const value_type& value) { + producer_.load()->emplace(id, value); +} + +template<typename T> +void ParamQueue<T>::producerDone() { + if (consumer_) + return; + + consumer_.store(producer_.load()); + producer_.store(free_.load()); + free_.store(nullptr); + + assert(producer_); +} + +template<typename T> +void ParamQueue<T>::consume(const std::function<void(clap_id, const value_type& value)> consumer) { + assert(consumer); + + if (!consumer_) + return; + + for (auto &x : *consumer_) + consumer(x.first, x.second); + + consumer_.load()->clear(); + if (free_) + return; + + free_ = consumer_.load(); + consumer_ = nullptr; +} diff --git a/examples/gui/parameter-proxy.cc b/examples/gui/parameter-proxy.cc @@ -34,20 +34,14 @@ void ParameterProxy::setIsAdjusting(bool isAdjusting) { if (isAdjusting == isAdjusting_) return; - isAdjusting_ = isAdjusting; - if (isAdjusting) { - clap::messages::BeginAdjustRequest rq{id_}; - Application::instance().remoteChannel().sendRequestAsync(rq); - } else { - clap::messages::EndAdjustRequest rq{id_}; - Application::instance().remoteChannel().sendRequestAsync(rq); - } + clap::messages::AdjustRequest rq{id_, value_, isAdjusting ? CLAP_EVENT_PARAM_BEGIN_ADJUST : CLAP_EVENT_PARAM_END_ADJUST}; + Application::instance().remoteChannel().sendRequestAsync(rq); } void ParameterProxy::setValueFromUI(double value) { value_ = value; - clap::messages::AdjustRequest rq{id_, value_}; + clap::messages::AdjustRequest rq{id_, value_, 0}; Application::instance().remoteChannel().sendRequestAsync(rq); valueChanged(); } diff --git a/examples/host/CMakeLists.txt b/examples/host/CMakeLists.txt @@ -28,8 +28,6 @@ add_executable(clap-host plugin-param.cc plugin-param.hh - param-queue.cc - param-queue.hh plugin-host.cc plugin-host.hh plugin-quick-control-widget.cc diff --git a/examples/host/param-queue.cc b/examples/host/param-queue.cc @@ -1,51 +0,0 @@ -#include <QDebug> - -#include "param-queue.hh" - -ParamQueue::ParamQueue() { reset(); } - -void ParamQueue::reset() { - for (auto &q : queues_) - q.clear(); - - free_ = &queues_[0]; - producer_ = &queues_[1]; - consumer_ = nullptr; -} - -void ParamQueue::setCapacity(size_t capacity) { - for (auto &q : queues_) - q.reserve(2 * capacity); -} - -void ParamQueue::set(clap_id id, void *cookie, double value) { - producer_.load()->emplace(id, value_type{cookie, value}); -} - -void ParamQueue::producerDone() { - if (consumer_) - return; - - consumer_.store(producer_.load()); - producer_.store(free_.load()); - free_.store(nullptr); - - Q_ASSERT(producer_); -} - -void ParamQueue::consume(const std::function<void(clap_id, void *, double)> consumer) { - Q_ASSERT(consumer); - - if (!consumer_) - return; - - for (auto &x : *consumer_) - consumer(x.first, x.second.cookie, x.second.value); - - consumer_.load()->clear(); - if (free_) - return; - - free_ = consumer_.load(); - consumer_ = nullptr; -} diff --git a/examples/host/param-queue.hh b/examples/host/param-queue.hh @@ -1,34 +0,0 @@ -#pragma once - -#include <atomic> -#include <functional> -#include <unordered_map> - -#include <clap/all.h> - -class ParamQueue { -public: - using value_type = struct { - void *cookie; - double value; - }; - - using queue_type = std::unordered_map<clap_id, value_type>; - - ParamQueue(); - - void setCapacity(size_t capacity); - - void set(clap_id id, void *cookie, double value); - void producerDone(); - - void consume(const std::function<void(clap_id id, void *cookie, double value)> consumer); - - void reset(); - -private: - queue_type queues_[2]; - std::atomic<queue_type *> free_ = nullptr; - std::atomic<queue_type *> producer_ = nullptr; - std::atomic<queue_type *> consumer_ = nullptr; -}; -\ No newline at end of file diff --git a/examples/host/plugin-host.cc b/examples/host/plugin-host.cc @@ -13,6 +13,8 @@ #include "main-window.hh" #include "plugin-host.hh" +#include "../common/param-queue.hxx" + enum ThreadType { Unknown, MainThread, @@ -511,8 +513,6 @@ void PluginHost::eventLoopSetFdNotifierFlags(clap_fd fd, uint32_t flags) { bool PluginHost::clapGuiResize(const clap_host *host, uint32_t width, uint32_t height) { checkForMainThread(); - PluginHost *h = static_cast<PluginHost *>(host->host_data); - Application::instance().mainWindow()->resizePluginView(width, height); return true; } @@ -615,28 +615,28 @@ void PluginHost::process() { process_.audio_outputs_count = 1; evOut_.clear(); - appToEngineValueQueue_.consume([this](clap_id param_id, void *cookie, double value) { + appToEngineValueQueue_.consume([this](clap_id param_id, const ParamQueueValue& value) { clap_event ev; ev.time = 0; ev.type = CLAP_EVENT_PARAM_VALUE; ev.param_value.param_id = param_id; - ev.param_value.cookie = cookie; + ev.param_value.cookie = value.cookie; ev.param_value.key = -1; ev.param_value.channel = -1; - ev.param_value.value = value; + ev.param_value.value = value.value; ev.param_value.flags = 0; evIn_.push_back(ev); }); - appToEngineModQueue_.consume([this](clap_id param_id, void *cookie, double value) { + appToEngineModQueue_.consume([this](clap_id param_id, const ParamQueueValue& value) { clap_event ev; ev.time = 0; ev.type = CLAP_EVENT_PARAM_MOD; ev.param_mod.param_id = param_id; - ev.param_mod.cookie = cookie; + ev.param_mod.cookie = value.cookie; ev.param_mod.key = -1; ev.param_mod.channel = -1; - ev.param_mod.amount = value; + ev.param_mod.amount = value.value; evIn_.push_back(ev); }); @@ -655,7 +655,7 @@ void PluginHost::process() { switch (ev.type) { case CLAP_EVENT_PARAM_VALUE: engineToAppValueQueue_.set( - ev.param_value.param_id, ev.param_value.cookie, ev.param_value.value); + ev.param_value.param_id, {ev.param_value.cookie, ev.param_value.value}); break; } } @@ -678,7 +678,7 @@ void PluginHost::idle() { appToEngineValueQueue_.producerDone(); appToEngineModQueue_.producerDone(); - engineToAppValueQueue_.consume([this](clap_id param_id, void *cookie, double value) { + engineToAppValueQueue_.consume([this](clap_id param_id, const ParamQueueValue& value) { auto it = params_.find(param_id); if (it == params_.end()) { std::ostringstream msg; @@ -686,7 +686,7 @@ void PluginHost::idle() { throw std::invalid_argument(msg.str()); } - it->second->setValue(value); + it->second->setValue(value.value); }); } @@ -731,7 +731,7 @@ void PluginHost::setParamValueByHost(PluginParam &param, double value) { param.setValue(value); - appToEngineValueQueue_.set(param.info().id, param.info().cookie, value); + appToEngineValueQueue_.set(param.info().id, {param.info().cookie, value}); appToEngineValueQueue_.producerDone(); } @@ -740,7 +740,7 @@ void PluginHost::setParamModulationByHost(PluginParam &param, double value) { param.setModulation(value); - appToEngineModQueue_.set(param.info().id, param.info().cookie, value); + appToEngineModQueue_.set(param.info().id, {param.info().cookie, value}); appToEngineModQueue_.producerDone(); } diff --git a/examples/host/plugin-host.hh b/examples/host/plugin-host.hh @@ -16,7 +16,7 @@ #include <clap/all.h> #include "engine.hh" -#include "param-queue.hh" +#include "../common/param-queue.hh" #include "plugin-param.hh" class Engine; @@ -183,9 +183,14 @@ private: /* param update queues */ std::unordered_map<clap_id, std::unique_ptr<PluginParam>> params_; - ParamQueue appToEngineValueQueue_; - ParamQueue appToEngineModQueue_; - ParamQueue engineToAppValueQueue_; + struct ParamQueueValue { + void *cookie; + double value; + }; + + ParamQueue<ParamQueueValue> appToEngineValueQueue_; + ParamQueue<ParamQueueValue> appToEngineModQueue_; + ParamQueue<ParamQueueValue> engineToAppValueQueue_; std::unordered_map<clap_id, std::unique_ptr<clap_quick_controls_page>> quickControlsPages_; clap_id quickControlsSelectedPage_ = CLAP_INVALID_ID; diff --git a/examples/io/messages.hh b/examples/io/messages.hh @@ -11,9 +11,7 @@ namespace clap::messages { kParameterValueRequest, // GUI->DSP - kBeginAdjustRequest, kAdjustRequest, - kEndAdjustRequest, // Gui, Host->Plugin kSetScaleRequest, @@ -39,23 +37,12 @@ namespace clap::messages { kResizeResponse, }; - struct BeginAdjustRequest final { - static const constexpr Type type = clap::messages::kBeginAdjustRequest; - - clap_id paramId; - }; - struct AdjustRequest final { static const constexpr Type type = clap::messages::kAdjustRequest; clap_id paramId; double value; - }; - - struct EndAdjustRequest final { - static const constexpr Type type = clap::messages::kEndAdjustRequest; - - clap_id paramId; + clap_event_param_flags flags; }; struct DefineParameterRequest final { diff --git a/examples/plugins/core-plugin.cc b/examples/plugins/core-plugin.cc @@ -162,4 +162,10 @@ namespace clap { // TODO return false; } + + void CorePlugin::guiAdjust(clap_id paramId, double value, clap_event_param_flags flags) + { + guiToPluginQueue_.set(paramId, {value, flags}); + guiToPluginQueue_.producerDone(); + } } // namespace clap \ No newline at end of file diff --git a/examples/plugins/core-plugin.hh b/examples/plugins/core-plugin.hh @@ -8,6 +8,8 @@ #include "path-provider.hh" #include "remote-gui.hh" +#include "../common/param-queue.hxx" + namespace clap { class CorePlugin : public Plugin { public: @@ -145,6 +147,16 @@ namespace clap { protected: friend class RemoteGui; + void guiAdjust(clap_id paramId, double value, clap_event_param_flags flags); + + struct ParamQueueValue { + double value; + clap_event_param_flags flags; + }; + + ParamQueue<ParamQueueValue> guiToPluginQueue_; + ParamQueue<ParamQueueValue> pluginToGuiQueue_; + std::unique_ptr<PathProvider> pathProvider_; bool hasTrackInfo_ = false; diff --git a/examples/plugins/dc-offset/dc-offset.cc b/examples/plugins/dc-offset/dc-offset.cc @@ -78,6 +78,25 @@ namespace clap { const clap_event *ev = nullptr; uint32_t N = process->frames_count; + guiToPluginQueue_.consume([this, process] (clap_id paramId, const ParamQueueValue& value) { + auto p = parameters_.getById(paramId); + if (!p) + return; + p->setValue(value.value); + + clap_event ev; + ev.time = 0; + ev.type = CLAP_EVENT_PARAM_VALUE; + ev.param_value.param_id = paramId; + ev.param_value.value = value.value; + ev.param_value.channel = -1; + ev.param_value.key = -1; + ev.param_value.flags = value.flags; + ev.param_value.cookie = p; + + process->out_events->push_back(process->out_events, &ev); + }); + /* foreach frames */ for (uint32_t i = 0; i < process->frames_count; ++i) { diff --git a/examples/plugins/remote-gui.cc b/examples/plugins/remote-gui.cc @@ -94,24 +94,10 @@ namespace clap { void RemoteGui::onMessage(const RemoteChannel::Message &msg) { switch (msg.type) { - case messages::kBeginAdjustRequest: { - messages::BeginAdjustRequest rq; - msg.get(rq); - // TODO - break; - } - case messages::kAdjustRequest: { messages::AdjustRequest rq; msg.get(rq); - // TODO - break; - } - - case messages::kEndAdjustRequest: { - messages::EndAdjustRequest rq; - msg.get(rq); - // TODO + plugin_.guiAdjust(rq.paramId, rq.value, rq.flags); break; } }