 7fe70ed89b
			
		
	
	7fe70ed89b
	
	
	
		
			
			subrepo: subdir: "deps/clap-juce-extensions/clap-libs/clap-helpers" merged: "2bb43c187" upstream: origin: "https://github.com/free-audio/clap-helpers.git" branch: "main" commit: "2bb43c187" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596"
		
			
				
	
	
		
			435 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			435 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #pragma once
 | |
| 
 | |
| #include <cassert>
 | |
| #include <functional>
 | |
| #include <mutex>
 | |
| #include <queue>
 | |
| #include <string>
 | |
| #include <string_view>
 | |
| #include <vector>
 | |
| 
 | |
| #include <clap/clap.h>
 | |
| 
 | |
| #include "checking-level.hh"
 | |
| #include "host-proxy.hh"
 | |
| #include "misbehaviour-handler.hh"
 | |
| 
 | |
| namespace clap { namespace helpers {
 | |
| 
 | |
|    /// @brief C++ glue and checks
 | |
|    ///
 | |
|    /// @note for an higher level implementation, see @ref PluginHelper
 | |
|    template <MisbehaviourHandler h, CheckingLevel l>
 | |
|    class Plugin {
 | |
|    public:
 | |
|       const clap_plugin *clapPlugin() noexcept { return &_plugin; }
 | |
| 
 | |
|    protected:
 | |
|       Plugin(const clap_plugin_descriptor *desc, const clap_host *host);
 | |
|       virtual ~Plugin() = default;
 | |
| 
 | |
|       // not copyable, not moveable
 | |
|       Plugin(const Plugin &) = delete;
 | |
|       Plugin(Plugin &&) = delete;
 | |
|       Plugin &operator=(const Plugin &) = delete;
 | |
|       Plugin &operator=(Plugin &&) = delete;
 | |
| 
 | |
|       /////////////////////////
 | |
|       // Methods to override //
 | |
|       /////////////////////////
 | |
| 
 | |
|       //-------------//
 | |
|       // clap_plugin //
 | |
|       //-------------//
 | |
|       virtual bool init() noexcept { return true; }
 | |
|       virtual bool
 | |
|       activate(double sampleRate, uint32_t minFrameCount, uint32_t maxFrameCount) 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 void reset() noexcept {}
 | |
|       virtual void onMainThread() noexcept {}
 | |
|       virtual const void *extension(const char *id) noexcept { return nullptr; }
 | |
| 
 | |
|       //---------------------//
 | |
|       // clap_plugin_latency //
 | |
|       //---------------------//
 | |
|       virtual bool implementsLatency() const noexcept { return false; }
 | |
|       virtual uint32_t latencyGet() const noexcept { return 0; }
 | |
| 
 | |
|       //------------------//
 | |
|       // clap_plugin_tail //
 | |
|       //------------------//
 | |
|       virtual bool implementsTail() const noexcept { return false; }
 | |
|       virtual uint32_t tailGet(const clap_plugin_t *plugin) const noexcept { return 0; }
 | |
| 
 | |
|       //--------------------//
 | |
|       // clap_plugin_render //
 | |
|       //--------------------//
 | |
|       virtual bool implementsRender() const noexcept { return false; }
 | |
|       virtual bool renderHasHardRealtimeRequirement() noexcept { return false; }
 | |
|       virtual bool renderSetMode(clap_plugin_render_mode mode) noexcept { return false; }
 | |
| 
 | |
|       //-------------------------//
 | |
|       // clap_plugin_thread_pool //
 | |
|       //-------------------------//
 | |
|       virtual bool implementsThreadPool() const noexcept { return false; }
 | |
|       virtual void threadPoolExec(uint32_t taskIndex) noexcept {}
 | |
| 
 | |
|       //-------------------//
 | |
|       // clap_plugin_state //
 | |
|       //-------------------//
 | |
|       virtual bool implementsState() const noexcept { return false; }
 | |
|       virtual bool stateSave(const clap_ostream *stream) noexcept { return false; }
 | |
|       virtual bool stateLoad(const clap_istream *stream) noexcept { return false; }
 | |
| 
 | |
|       //-------------------------//
 | |
|       // 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 isInput) const noexcept { return 0; }
 | |
|       virtual bool
 | |
|       audioPortsInfo(uint32_t index, bool isInput, clap_audio_port_info *info) const noexcept {
 | |
|          return false;
 | |
|       }
 | |
|       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 configId) noexcept { return false; }
 | |
| 
 | |
|       //--------------------//
 | |
|       // clap_plugin_params //
 | |
|       //--------------------//
 | |
|       virtual bool implementsParams() const noexcept { return false; }
 | |
|       virtual uint32_t paramsCount() const noexcept { return 0; }
 | |
|       virtual bool paramsInfo(uint32_t paramIndex, clap_param_info *info) const noexcept {
 | |
|          return false;
 | |
|       }
 | |
|       virtual bool paramsValue(clap_id paramId, double *value) noexcept { return false; }
 | |
|       virtual bool
 | |
|       paramsValueToText(clap_id paramId, double value, char *display, uint32_t size) noexcept {
 | |
|          return false;
 | |
|       }
 | |
|       virtual bool paramsTextToValue(clap_id paramId, const char *display, double *value) noexcept {
 | |
|          return false;
 | |
|       }
 | |
|       virtual void paramsFlush(const clap_input_events *in,
 | |
|                                const clap_output_events *out) noexcept {}
 | |
|       virtual bool isValidParamId(clap_id paramId) const noexcept;
 | |
| 
 | |
|       //----------------------------//
 | |
|       // clap_plugin_quick_controls //
 | |
|       //----------------------------//
 | |
|       virtual bool implementQuickControls() const noexcept { return false; }
 | |
|       virtual uint32_t quickControlsPageCount() noexcept { return 0; }
 | |
|       virtual bool quickControlsPageGet(uint32_t pageIndex,
 | |
|                                         clap_quick_controls_page *page) noexcept {
 | |
|          return false;
 | |
|       }
 | |
|       virtual void quickControlsSelectPage(clap_id pageId) noexcept {}
 | |
|       virtual clap_id quickControlsSelectedPage() noexcept { return CLAP_INVALID_ID; }
 | |
| 
 | |
|       //------------------------//
 | |
|       // clap_plugin_note_ports //
 | |
|       //------------------------//
 | |
|       virtual bool implementsNotePorts() const noexcept { return false; }
 | |
|       virtual uint32_t notePortsCount(bool isInput) const noexcept { return 0; }
 | |
|       virtual bool
 | |
|       notePortsInfo(uint32_t index, bool isInput, clap_note_port_info *info) const 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 *noteName) noexcept { return false; }
 | |
| 
 | |
|       //---------------------------//
 | |
|       // clap_plugin_timer_support //
 | |
|       //---------------------------//
 | |
|       virtual bool implementsTimerSupport() const noexcept { return false; }
 | |
|       virtual void onTimer(clap_id timerId) noexcept {}
 | |
| 
 | |
|       //------------------------------//
 | |
|       // clap_plugin_posix_fd_support //
 | |
|       //------------------------------//
 | |
|       virtual bool implementsPosixFdSupport() const noexcept { return false; }
 | |
|       virtual void onPosixFd(int fd, int flags) noexcept {}
 | |
| 
 | |
|       //-----------------//
 | |
|       // clap_plugin_gui //
 | |
|       //-----------------//
 | |
|       virtual bool implementsGui() const noexcept { return false; }
 | |
|       virtual bool guiIsApiSupported(const char *api, bool isFloating) noexcept { return false; }
 | |
|       virtual bool guiGetPreferredApi(const char **api, bool *is_floating) noexcept {
 | |
|          return false;
 | |
|       }
 | |
|       virtual bool guiCreate(const char *api, bool isFloating) noexcept { return false; }
 | |
|       virtual void guiDestroy() noexcept {}
 | |
|       virtual bool guiSetScale(double scale) noexcept { return false; }
 | |
|       virtual bool guiShow() noexcept { return false; }
 | |
|       virtual bool guiHide() noexcept { return false; }
 | |
|       virtual bool guiGetSize(uint32_t *width, uint32_t *height) noexcept { return false; }
 | |
|       virtual bool guiCanResize() const noexcept { return false; }
 | |
|       virtual bool guiGetResizeHints(clap_gui_resize_hints_t *hints) noexcept { return false; }
 | |
|       virtual bool guiAdjustSize(uint32_t *width, uint32_t *height) noexcept {
 | |
|          return guiGetSize(width, height);
 | |
|       }
 | |
|       virtual bool guiSetSize(uint32_t width, uint32_t height) noexcept { return false; }
 | |
|       virtual void guiSuggestTitle(const char *title) noexcept {}
 | |
|       virtual bool guiSetParent(const clap_window *window) noexcept { return false; }
 | |
|       virtual bool guiSetTransient(const clap_window *window) noexcept { return false; }
 | |
| 
 | |
|       //------------------------//
 | |
|       // clap_plugin_voice_info //
 | |
|       //------------------------//
 | |
|       virtual bool implementsVoiceInfo() const noexcept { return false; }
 | |
|       virtual bool voiceInfoGet(clap_voice_info *info) noexcept { return false; }
 | |
| 
 | |
|       /////////////
 | |
|       // Logging //
 | |
|       /////////////
 | |
|       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()); }
 | |
| 
 | |
|       // Receives a copy of all the logging messages sent to the host.
 | |
|       // This is useful to have the messages in both the host's logs and the plugin's logs.
 | |
|       virtual void logTee(clap_log_severity severity, const char *msg) const noexcept {}
 | |
| 
 | |
|       /////////////////////
 | |
|       // Thread Checking //
 | |
|       /////////////////////
 | |
|       void checkMainThread() const noexcept;
 | |
|       void checkAudioThread() const noexcept;
 | |
|       void checkParamThread() const noexcept;
 | |
|       void ensureMainThread(const char *method) const noexcept;
 | |
|       void ensureAudioThread(const char *method) const noexcept;
 | |
|       void ensureParamThread(const char *method) const noexcept;
 | |
| 
 | |
|       ///////////////
 | |
|       // Utilities //
 | |
|       ///////////////
 | |
|       static Plugin &from(const clap_plugin *plugin, bool requireInitialized = true) noexcept;
 | |
| 
 | |
|       // runs the callback immediately if on the main thread, otherwise queue it.
 | |
|       // be aware that the callback may be ran during the plugin destruction phase,
 | |
|       // so check isBeingDestroyed() and ajust your code.
 | |
|       void runOnMainThread(std::function<void()> callback);
 | |
| 
 | |
|       // This actually runs callbacks on the main thread, you should not need to call it
 | |
|       void runCallbacksOnMainThread();
 | |
| 
 | |
|       template <typename T>
 | |
|       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;
 | |
| 
 | |
|       //////////////////////
 | |
|       // Processing State //
 | |
|       //////////////////////
 | |
|       bool isActive() const noexcept { return _isActive; }
 | |
|       bool isProcessing() const noexcept { return _isProcessing; }
 | |
|       int sampleRate() const noexcept {
 | |
|          assert(_isActive && "sample rate is only known if the plugin is active");
 | |
|          assert(_sampleRate > 0);
 | |
|          return _sampleRate;
 | |
|       }
 | |
| 
 | |
|       bool isBeingDestroyed() const noexcept { return _isBeingDestroyed; }
 | |
| 
 | |
|    protected:
 | |
|       HostProxy<h, l> _host;
 | |
| 
 | |
|    private:
 | |
|       /////////////////////
 | |
|       // CLAP Interfaces //
 | |
|       /////////////////////
 | |
| 
 | |
|       clap_plugin _plugin;
 | |
|       // clap_plugin
 | |
|       static bool clapInit(const clap_plugin *plugin) noexcept;
 | |
|       static void clapDestroy(const clap_plugin *plugin) noexcept;
 | |
|       static bool clapActivate(const clap_plugin *plugin,
 | |
|                                double sample_rate,
 | |
|                                uint32_t minFrameCount,
 | |
|                                uint32_t maxFrameCount) 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 void clapReset(const clap_plugin *plugin) noexcept;
 | |
|       static clap_process_status clapProcess(const clap_plugin *plugin,
 | |
|                                              const clap_process *process) noexcept;
 | |
|       static void clapOnMainThread(const clap_plugin *plugin) 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_tail
 | |
|       static uint32_t clapTailGet(const clap_plugin_t *plugin) noexcept;
 | |
| 
 | |
|       // clap_plugin_render
 | |
|       static bool clapRenderHasHardRealtimeRequirement(const clap_plugin_t *plugin) noexcept;
 | |
|       static bool clapRenderSetMode(const clap_plugin *plugin,
 | |
|                                     clap_plugin_render_mode mode) noexcept;
 | |
| 
 | |
|       // clap_plugin_thread_pool
 | |
|       static void clapThreadPoolExec(const clap_plugin *plugin, uint32_t task_index) noexcept;
 | |
| 
 | |
|       // clap_plugin_state
 | |
|       static bool clapStateSave(const clap_plugin *plugin, const clap_ostream *stream) noexcept;
 | |
|       static bool clapStateLoad(const clap_plugin *plugin, const clap_istream *stream) 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) noexcept;
 | |
| 
 | |
|       // clap_plugin_audio_ports
 | |
|       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) noexcept;
 | |
|       static bool clapParamsInfo(const clap_plugin *plugin,
 | |
|                                  uint32_t param_index,
 | |
|                                  clap_param_info *param_info) noexcept;
 | |
|       static bool
 | |
|       clapParamsValue(const clap_plugin *plugin, clap_id param_id, double *value) noexcept;
 | |
|       static bool clapParamsValueToText(const clap_plugin *plugin,
 | |
|                                         clap_id param_id,
 | |
|                                         double value,
 | |
|                                         char *display,
 | |
|                                         uint32_t size) noexcept;
 | |
|       static bool clapParamsTextToValue(const clap_plugin *plugin,
 | |
|                                         clap_id param_id,
 | |
|                                         const char *display,
 | |
|                                         double *value) noexcept;
 | |
|       static void clapParamsFlush(const clap_plugin *plugin,
 | |
|                                   const clap_input_events *in,
 | |
|                                   const clap_output_events *out) noexcept;
 | |
| 
 | |
|       // clap_plugin_quick_controls
 | |
|       static uint32_t clapQuickControlsPageCount(const clap_plugin *plugin) noexcept;
 | |
|       static bool clapQuickControlsPageGet(const clap_plugin *plugin,
 | |
|                                            uint32_t page_index,
 | |
|                                            clap_quick_controls_page *page) noexcept;
 | |
| 
 | |
|       // clap_plugin_note_port
 | |
|       static uint32_t clapNotePortsCount(const clap_plugin *plugin, bool is_input) noexcept;
 | |
|       static bool clapNotePortsInfo(const clap_plugin *plugin,
 | |
|                                     uint32_t index,
 | |
|                                     bool is_input,
 | |
|                                     clap_note_port_info *info) noexcept;
 | |
| 
 | |
|       // clap_plugin_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;
 | |
| 
 | |
|       // clap_plugin_timer_support
 | |
|       static void clapOnTimer(const clap_plugin *plugin, clap_id timer_id) noexcept;
 | |
| 
 | |
|       // clap_plugin_fd_support
 | |
|       static void
 | |
|       clapOnPosixFd(const clap_plugin *plugin, int fd, clap_posix_fd_flags_t flags) noexcept;
 | |
| 
 | |
|       // clap_plugin_gui
 | |
|       static bool
 | |
|       clapGuiIsApiSupported(const clap_plugin *plugin, const char *api, bool isFloating) noexcept;
 | |
|       static bool clapGuiGetPreferredApi(const clap_plugin_t *plugin,
 | |
|                                          const char **api,
 | |
|                                          bool *is_floating) noexcept;
 | |
|       static bool
 | |
|       clapGuiCreate(const clap_plugin *plugin, const char *api, bool isFloating) noexcept;
 | |
|       static void clapGuiDestroy(const clap_plugin *plugin) noexcept;
 | |
|       static bool clapGuiSetScale(const clap_plugin *plugin, double scale) noexcept;
 | |
|       static bool
 | |
|       clapGuiGetSize(const clap_plugin *plugin, uint32_t *width, uint32_t *height) noexcept;
 | |
|       static bool
 | |
|       clapGuiSetSize(const clap_plugin *plugin, uint32_t width, uint32_t height) noexcept;
 | |
|       static bool clapGuiCanResize(const clap_plugin *plugin) noexcept;
 | |
|       static bool clapGuiGetResizeHints(const clap_plugin_t *plugin,
 | |
|                                         clap_gui_resize_hints_t *hints) noexcept;
 | |
|       static bool
 | |
|       clapGuiAdjustSize(const clap_plugin *plugin, uint32_t *width, uint32_t *height) noexcept;
 | |
|       static bool clapGuiShow(const clap_plugin *plugin) noexcept;
 | |
|       static bool clapGuiHide(const clap_plugin *plugin) noexcept;
 | |
|       static bool clapGuiSetParent(const clap_plugin *plugin, const clap_window *window) noexcept;
 | |
|       static bool clapGuiSetTransient(const clap_plugin *plugin,
 | |
|                                       const clap_window *window) noexcept;
 | |
| 
 | |
|       static void clapGuiSuggestTitle(const clap_plugin *plugin, const char *title) noexcept;
 | |
| 
 | |
|       static bool clapVoiceInfoGet(const clap_plugin *plugin, clap_voice_info *info) noexcept;
 | |
| 
 | |
|       // interfaces
 | |
|       static const clap_plugin_render _pluginRender;
 | |
|       static const clap_plugin_thread_pool _pluginThreadPool;
 | |
|       static const clap_plugin_state _pluginState;
 | |
|       static const clap_plugin_preset_load _pluginPresetLoad;
 | |
|       static const clap_plugin_track_info _pluginTrackInfo;
 | |
|       static const clap_plugin_audio_ports _pluginAudioPorts;
 | |
|       static const clap_plugin_audio_ports_config _pluginAudioPortsConfig;
 | |
|       static const clap_plugin_params _pluginParams;
 | |
|       static const clap_plugin_quick_controls _pluginQuickControls;
 | |
|       static const clap_plugin_latency _pluginLatency;
 | |
|       static const clap_plugin_note_ports _pluginNotePorts;
 | |
|       static const clap_plugin_note_name _pluginNoteName;
 | |
|       static const clap_plugin_timer_support _pluginTimerSupport;
 | |
|       static const clap_plugin_posix_fd_support _pluginPosixFdSupport;
 | |
|       static const clap_plugin_gui _pluginGui;
 | |
|       static const clap_plugin_voice_info _pluginVoiceInfo;
 | |
|       static const clap_plugin_tail _pluginTail;
 | |
| 
 | |
|       // state
 | |
|       bool _wasInitialized = false;
 | |
|       bool _isActive = false;
 | |
|       bool _isProcessing = false;
 | |
|       bool _isBeingDestroyed = false;
 | |
|       double _sampleRate = 0;
 | |
| 
 | |
|       std::string _guiApi;
 | |
|       bool _isGuiCreated = false;
 | |
|       bool _isGuiFloating = false;
 | |
|       bool _isGuiEmbedded = false;
 | |
| 
 | |
|       std::mutex _mainThredCallbacksLock;
 | |
|       std::queue<std::function<void()>> _mainThredCallbacks;
 | |
|    };
 | |
| }} // namespace clap::helpers
 |