diff --git a/.clang-format b/.clang-format index 8ac1fa7c..f3155627 100644 --- a/.clang-format +++ b/.clang-format @@ -14,7 +14,7 @@ BreakConstructorInitializers: BeforeComma BreakBeforeBraces: Allman ColumnLimit: 105 SortIncludes: false -NamespaceIndentation: All +NamespaceIndentation: Inner ReflowComments: false AllowShortFunctionsOnASingleLine: None --- @@ -30,7 +30,7 @@ BreakConstructorInitializers: BeforeComma BreakBeforeBraces: Allman ColumnLimit: 105 SortIncludes: false -NamespaceIndentation: All +NamespaceIndentation: Inner ReflowComments: false AllowShortFunctionsOnASingleLine: None ... diff --git a/src/clap_proxy.cpp b/src/clap_proxy.cpp index ec87f5c5..b8d34752 100644 --- a/src/clap_proxy.cpp +++ b/src/clap_proxy.cpp @@ -10,468 +10,468 @@ namespace Clap { - namespace HostExt +namespace HostExt +{ + static Plugin* self(const clap_host_t* host) { - static Plugin* self(const clap_host_t* host) - { - return static_cast(host->host_data); - } + return static_cast(host->host_data); + } - void host_log(const clap_host_t* host, clap_log_severity severity, const char* msg) - { - self(host)->log(severity, msg); - } + void host_log(const clap_host_t* host, clap_log_severity severity, const char* msg) + { + self(host)->log(severity, msg); + } - clap_host_log_t log = {host_log}; + clap_host_log_t log = {host_log}; - void rescan(const clap_host_t* host, clap_param_rescan_flags flags) - { - self(host)->param_rescan(flags); - } + void rescan(const clap_host_t* host, clap_param_rescan_flags flags) + { + self(host)->param_rescan(flags); + } - // Clears references to a parameter. - // [main-thread] - void clear(const clap_host_t* host, clap_id param_id, clap_param_clear_flags flags) - { - } + // Clears references to a parameter. + // [main-thread] + void clear(const clap_host_t* host, clap_id param_id, clap_param_clear_flags flags) + { + } - // Request a parameter flush. - // - // If the plugin is processing, this will result in no action. The process call - // will run normally. If plugin isn't processing, the host will make a subsequent - // call to clap_plugin_params->flush(). As a result, this function is always - // safe to call from a non-audio thread (typically the UI thread on a gesture) - // whether processing is active or not. - // - // This must not be called on the [audio-thread]. - // [thread-safe,!audio-thread] - void request_flush(const clap_host_t* host) - { - self(host)->param_request_flush(); - } - clap_host_params_t params = {rescan, clear, request_flush}; + // Request a parameter flush. + // + // If the plugin is processing, this will result in no action. The process call + // will run normally. If plugin isn't processing, the host will make a subsequent + // call to clap_plugin_params->flush(). As a result, this function is always + // safe to call from a non-audio thread (typically the UI thread on a gesture) + // whether processing is active or not. + // + // This must not be called on the [audio-thread]. + // [thread-safe,!audio-thread] + void request_flush(const clap_host_t* host) + { + self(host)->param_request_flush(); + } + clap_host_params_t params = {rescan, clear, request_flush}; - bool is_main_thread(const clap_host_t* host) - { - return self(host)->is_main_thread(); - } + bool is_main_thread(const clap_host_t* host) + { + return self(host)->is_main_thread(); + } - // Returns true if "this" thread is one of the audio threads. - // [thread-safe] - bool is_audio_thread(const clap_host_t* host) - { - return self(host)->is_audio_thread(); - } + // Returns true if "this" thread is one of the audio threads. + // [thread-safe] + bool is_audio_thread(const clap_host_t* host) + { + return self(host)->is_audio_thread(); + } - clap_host_thread_check_t threadcheck = {is_main_thread, is_audio_thread}; + clap_host_thread_check_t threadcheck = {is_main_thread, is_audio_thread}; - static void resize_hints_changed(const clap_host_t* host) - { - self(host)->resize_hints_changed(); - } - static bool request_resize(const clap_host_t* host, uint32_t width, uint32_t height) - { - return self(host)->request_resize(width, height); - } - static bool request_show(const clap_host_t* host) - { - return self(host)->request_show(); - } - static bool request_hide(const clap_host_t* host) - { - return self(host)->request_hide(); - } - static void closed(const clap_host_t* host, bool was_destroyed) - { - self(host)->closed(was_destroyed); - } + static void resize_hints_changed(const clap_host_t* host) + { + self(host)->resize_hints_changed(); + } + static bool request_resize(const clap_host_t* host, uint32_t width, uint32_t height) + { + return self(host)->request_resize(width, height); + } + static bool request_show(const clap_host_t* host) + { + return self(host)->request_show(); + } + static bool request_hide(const clap_host_t* host) + { + return self(host)->request_hide(); + } + static void closed(const clap_host_t* host, bool was_destroyed) + { + self(host)->closed(was_destroyed); + } - const clap_host_gui hostgui = {resize_hints_changed, request_resize, request_show, request_hide, - closed}; + const clap_host_gui hostgui = {resize_hints_changed, request_resize, request_show, request_hide, + closed}; - const clap_host_timer_support hosttimer = { - /* register_timer */ [](const clap_host_t* host, uint32_t period_ms, clap_id* timer_id) -> bool - { return self(host)->register_timer(period_ms, timer_id); }, - /* unregister_timer */ - [](const clap_host_t* host, clap_id timer_id) -> bool - { return self(host)->unregister_timer(timer_id); }}; + const clap_host_timer_support hosttimer = { + /* register_timer */ [](const clap_host_t* host, uint32_t period_ms, clap_id* timer_id) -> bool + { return self(host)->register_timer(period_ms, timer_id); }, + /* unregister_timer */ + [](const clap_host_t* host, clap_id timer_id) -> bool + { return self(host)->unregister_timer(timer_id); }}; #if LIN - const clap_host_posix_fd_support hostposixfd = { - [](const clap_host_t* host, int fd, clap_posix_fd_flags_t flags) -> bool - { return self(host)->register_fd(fd, flags); }, - [](const clap_host_t* host, int fd, clap_posix_fd_flags_t flags) -> bool - { return self(host)->modify_fd(fd, flags); }, - [](const clap_host_t* host, int fd) -> bool { return self(host)->unregister_fd(fd); }}; + const clap_host_posix_fd_support hostposixfd = { + [](const clap_host_t* host, int fd, clap_posix_fd_flags_t flags) -> bool + { return self(host)->register_fd(fd, flags); }, + [](const clap_host_t* host, int fd, clap_posix_fd_flags_t flags) -> bool + { return self(host)->modify_fd(fd, flags); }, + [](const clap_host_t* host, int fd) -> bool { return self(host)->unregister_fd(fd); }}; #endif - const clap_host_latency latency = {[](const clap_host_t* host) -> void - { self(host)->latency_changed(); }}; - - static void tail_changed(const clap_host_t* host) - { - self(host)->tail_changed(); - } - - const clap_host_tail tail = {tail_changed}; + const clap_host_latency latency = {[](const clap_host_t* host) -> void + { self(host)->latency_changed(); }}; - } // namespace HostExt - - std::shared_ptr Plugin::createInstance(Clap::Library& library, size_t index, IHost* host) + static void tail_changed(const clap_host_t* host) { - if (library.plugins.size() > index) - { - auto plug = std::shared_ptr(new Plugin(host)); - auto instance = library._pluginFactory->create_plugin( - library._pluginFactory, plug->getClapHostInterface(), library.plugins[index]->id); - plug->connectClap(instance); - - return plug; - } - return nullptr; + self(host)->tail_changed(); } - Plugin::Plugin(IHost* host) - : _host{CLAP_VERSION, - this, - "Clap-As-VST3-Wrapper", - "defiant nerd", - "https://www.defiantnerd.com", - "0.0.1", - Plugin::clapExtension, - Plugin::clapRequestRestart, - Plugin::clapRequestProcess, - Plugin::clapRequestCallback} - , _parentHost(host) - { - } + const clap_host_tail tail = {tail_changed}; - template - void getExtension(const clap_plugin_t* plugin, T& ref, const char* name) - { - ref = static_cast(plugin->get_extension(plugin, name)); - } +} // namespace HostExt - void Plugin::connectClap(const clap_plugin_t* clap) - { - _plugin = clap; +std::shared_ptr Plugin::createInstance(Clap::Library& library, size_t index, IHost* host) +{ + if (library.plugins.size() > index) + { + auto plug = std::shared_ptr(new Plugin(host)); + auto instance = library._pluginFactory->create_plugin( + library._pluginFactory, plug->getClapHostInterface(), library.plugins[index]->id); + plug->connectClap(instance); + + return plug; + } + return nullptr; +} + +Plugin::Plugin(IHost* host) + : _host{CLAP_VERSION, + this, + "Clap-As-VST3-Wrapper", + "defiant nerd", + "https://www.defiantnerd.com", + "0.0.1", + Plugin::clapExtension, + Plugin::clapRequestRestart, + Plugin::clapRequestProcess, + Plugin::clapRequestCallback} + , _parentHost(host) +{ +} - // initialize the plugin - if (!_plugin->init(_plugin)) - { - _plugin->destroy(_plugin); - _plugin = nullptr; - return; - } +template +void getExtension(const clap_plugin_t* plugin, T& ref, const char* name) +{ + ref = static_cast(plugin->get_extension(plugin, name)); +} + +void Plugin::connectClap(const clap_plugin_t* clap) +{ + _plugin = clap; - // if successful, query the extensions the wrapper might want to use - getExtension(_plugin, _ext._state, CLAP_EXT_STATE); - getExtension(_plugin, _ext._params, CLAP_EXT_PARAMS); - getExtension(_plugin, _ext._audioports, CLAP_EXT_AUDIO_PORTS); - getExtension(_plugin, _ext._noteports, CLAP_EXT_NOTE_PORTS); - getExtension(_plugin, _ext._midimap, CLAP_EXT_MIDI_MAPPINGS); - getExtension(_plugin, _ext._latency, CLAP_EXT_LATENCY); - getExtension(_plugin, _ext._render, CLAP_EXT_RENDER); - getExtension(_plugin, _ext._tail, CLAP_EXT_TAIL); - getExtension(_plugin, _ext._gui, CLAP_EXT_GUI); - getExtension(_plugin, _ext._timer, CLAP_EXT_TIMER_SUPPORT); + // initialize the plugin + if (!_plugin->init(_plugin)) + { + _plugin->destroy(_plugin); + _plugin = nullptr; + return; + } + + // if successful, query the extensions the wrapper might want to use + getExtension(_plugin, _ext._state, CLAP_EXT_STATE); + getExtension(_plugin, _ext._params, CLAP_EXT_PARAMS); + getExtension(_plugin, _ext._audioports, CLAP_EXT_AUDIO_PORTS); + getExtension(_plugin, _ext._noteports, CLAP_EXT_NOTE_PORTS); + getExtension(_plugin, _ext._midimap, CLAP_EXT_MIDI_MAPPINGS); + getExtension(_plugin, _ext._latency, CLAP_EXT_LATENCY); + getExtension(_plugin, _ext._render, CLAP_EXT_RENDER); + getExtension(_plugin, _ext._tail, CLAP_EXT_TAIL); + getExtension(_plugin, _ext._gui, CLAP_EXT_GUI); + getExtension(_plugin, _ext._timer, CLAP_EXT_TIMER_SUPPORT); #if LIN - getExtension(_plugin, _ext._posixfd, CLAP_EXT_POSIX_FD_SUPPORT); + getExtension(_plugin, _ext._posixfd, CLAP_EXT_POSIX_FD_SUPPORT); #endif - if (_ext._gui) - { - const char* api; + if (_ext._gui) + { + const char* api; #if WIN - api = CLAP_WINDOW_API_WIN32; + api = CLAP_WINDOW_API_WIN32; #endif #if MAC - api = CLAP_WINDOW_API_COCOA; + api = CLAP_WINDOW_API_COCOA; #endif #if LIN - api = CLAP_WINDOW_API_X11; + api = CLAP_WINDOW_API_X11; #endif - if (!_ext._gui->is_api_supported(_plugin, api, false)) - { - // disable GUI if not win32 - _ext._gui = nullptr; - } - } - } - - Plugin::~Plugin() - { - if (_plugin) + if (!_ext._gui->is_api_supported(_plugin, api, false)) { - _plugin->destroy(_plugin); - _plugin = nullptr; + // disable GUI if not win32 + _ext._gui = nullptr; } } +} - void Plugin::schnick() - { - } - - bool Plugin::initialize() - { - fprintf(stderr, "Plugin Initialize\n"); - if (_ext._audioports) - { - _parentHost->setupAudioBusses(_plugin, _ext._audioports); - } - if (_ext._noteports) - { - _parentHost->setupMIDIBusses(_plugin, _ext._noteports); - } - if (_ext._params) - { - _parentHost->setupParameters(_plugin, _ext._params); - } - - _parentHost->setupWrapperSpecifics(_plugin); - return true; - } - - void Plugin::terminate() +Plugin::~Plugin() +{ + if (_plugin) { _plugin->destroy(_plugin); _plugin = nullptr; } +} - void Plugin::setSampleRate(double sampleRate) - { - _audioSetup.sampleRate = sampleRate; - } +void Plugin::schnick() +{ +} - void Plugin::setBlockSizes(uint32_t minFrames, uint32_t maxFrames) +bool Plugin::initialize() +{ + fprintf(stderr, "Plugin Initialize\n"); + if (_ext._audioports) { - _audioSetup.minFrames = minFrames; - _audioSetup.maxFrames = maxFrames; + _parentHost->setupAudioBusses(_plugin, _ext._audioports); } - - bool Plugin::load(const clap_istream_t* stream) + if (_ext._noteports) { - if (_ext._state) - { - return _ext._state->load(_plugin, stream); - } - return false; + _parentHost->setupMIDIBusses(_plugin, _ext._noteports); } - - bool Plugin::save(const clap_ostream_t* stream) + if (_ext._params) { - if (_ext._state) - { - return _ext._state->save(_plugin, stream); - } - return false; + _parentHost->setupParameters(_plugin, _ext._params); } - bool Plugin::activate() - { - return _plugin->activate(_plugin, _audioSetup.sampleRate, _audioSetup.minFrames, - _audioSetup.maxFrames); - } + _parentHost->setupWrapperSpecifics(_plugin); + return true; +} - void Plugin::deactivate() - { - _plugin->deactivate(_plugin); - } +void Plugin::terminate() +{ + _plugin->destroy(_plugin); + _plugin = nullptr; +} + +void Plugin::setSampleRate(double sampleRate) +{ + _audioSetup.sampleRate = sampleRate; +} + +void Plugin::setBlockSizes(uint32_t minFrames, uint32_t maxFrames) +{ + _audioSetup.minFrames = minFrames; + _audioSetup.maxFrames = maxFrames; +} - bool Plugin::start_processing() +bool Plugin::load(const clap_istream_t* stream) +{ + if (_ext._state) { - auto thisFn = AlwaysAudioThread(); - return _plugin->start_processing(_plugin); + return _ext._state->load(_plugin, stream); } + return false; +} - void Plugin::stop_processing() +bool Plugin::save(const clap_ostream_t* stream) +{ + if (_ext._state) { - auto thisFn = AlwaysAudioThread(); - _plugin->stop_processing(_plugin); + return _ext._state->save(_plugin, stream); } + return false; +} + +bool Plugin::activate() +{ + return _plugin->activate(_plugin, _audioSetup.sampleRate, _audioSetup.minFrames, + _audioSetup.maxFrames); +} + +void Plugin::deactivate() +{ + _plugin->deactivate(_plugin); +} - //void Plugin::process(const clap_process_t* data) - //{ - // auto thisFn = AlwaysAudioThread(); - // _plugin->process(_plugin, data); - //} +bool Plugin::start_processing() +{ + auto thisFn = AlwaysAudioThread(); + return _plugin->start_processing(_plugin); +} + +void Plugin::stop_processing() +{ + auto thisFn = AlwaysAudioThread(); + _plugin->stop_processing(_plugin); +} - const clap_plugin_gui_t* Plugin::getUI() +//void Plugin::process(const clap_process_t* data) +//{ +// auto thisFn = AlwaysAudioThread(); +// _plugin->process(_plugin, data); +//} + +const clap_plugin_gui_t* Plugin::getUI() +{ + if (_ext._gui) { - if (_ext._gui) + if (_ext._gui->is_api_supported(_plugin, CLAP_WINDOW_API_WIN32, false)) { - if (_ext._gui->is_api_supported(_plugin, CLAP_WINDOW_API_WIN32, false)) - { - // _ext._g - } + // _ext._g } - return nullptr; } + return nullptr; +} - void Plugin::latency_changed() - { - _parentHost->latency_changed(); - } +void Plugin::latency_changed() +{ + _parentHost->latency_changed(); +} - void Plugin::tail_changed() - { - _parentHost->tail_changed(); - } +void Plugin::tail_changed() +{ + _parentHost->tail_changed(); +} - void Plugin::log(clap_log_severity severity, const char* msg) - { - std::string n; - switch (severity) - { - case CLAP_LOG_DEBUG: - n.append("PLUGIN: DEBUG: "); - break; - case CLAP_LOG_INFO: - n.append("PLUGIN: INFO: "); - break; - case CLAP_LOG_WARNING: - n.append("PLUGIN: WARNING: "); - break; - case CLAP_LOG_ERROR: - n.append("PLUGIN: ERROR: "); - break; - case CLAP_LOG_FATAL: - n.append("PLUGIN: FATAL: "); - break; - case CLAP_LOG_PLUGIN_MISBEHAVING: - n.append("PLUGIN: MISBEHAVING: "); - break; - case CLAP_LOG_HOST_MISBEHAVING: - n.append("PLUGIN: HOST MISBEHAVING: "); +void Plugin::log(clap_log_severity severity, const char* msg) +{ + std::string n; + switch (severity) + { + case CLAP_LOG_DEBUG: + n.append("PLUGIN: DEBUG: "); + break; + case CLAP_LOG_INFO: + n.append("PLUGIN: INFO: "); + break; + case CLAP_LOG_WARNING: + n.append("PLUGIN: WARNING: "); + break; + case CLAP_LOG_ERROR: + n.append("PLUGIN: ERROR: "); + break; + case CLAP_LOG_FATAL: + n.append("PLUGIN: FATAL: "); + break; + case CLAP_LOG_PLUGIN_MISBEHAVING: + n.append("PLUGIN: MISBEHAVING: "); + break; + case CLAP_LOG_HOST_MISBEHAVING: + n.append("PLUGIN: HOST MISBEHAVING: "); #if WIN32 - OutputDebugStringA(msg); - _CrtDbgBreak(); + OutputDebugStringA(msg); + _CrtDbgBreak(); #endif #if MAC - fprintf(stderr, "%s\n", msg); + fprintf(stderr, "%s\n", msg); #endif - break; - } - n.append(msg); + break; + } + n.append(msg); #if WIN32 - OutputDebugStringA(n.c_str()); - OutputDebugStringA("\n"); + OutputDebugStringA(n.c_str()); + OutputDebugStringA("\n"); #endif #if MAC - fprintf(stderr, "%s\n", n.c_str()); + fprintf(stderr, "%s\n", n.c_str()); #endif - } +} - bool Plugin::is_main_thread() const - { - return _main_thread_id == std::this_thread::get_id(); - } +bool Plugin::is_main_thread() const +{ + return _main_thread_id == std::this_thread::get_id(); +} - bool Plugin::is_audio_thread() const +bool Plugin::is_audio_thread() const +{ + if (this->_audio_thread_override > 0) { - if (this->_audio_thread_override > 0) - { - return true; - } - return !is_main_thread(); + return true; } + return !is_main_thread(); +} - CLAP_NODISCARD Raise Plugin::AlwaysAudioThread() - { - return Raise(this->_audio_thread_override); - } +CLAP_NODISCARD Raise Plugin::AlwaysAudioThread() +{ + return Raise(this->_audio_thread_override); +} - void Plugin::param_rescan(clap_param_rescan_flags flags) - { - _parentHost->param_rescan(flags); - } +void Plugin::param_rescan(clap_param_rescan_flags flags) +{ + _parentHost->param_rescan(flags); +} - void Plugin::param_clear(clap_id param, clap_param_clear_flags flags) - { - _parentHost->param_clear(param, flags); - } - void Plugin::param_request_flush() - { - _parentHost->param_request_flush(); - } +void Plugin::param_clear(clap_id param, clap_param_clear_flags flags) +{ + _parentHost->param_clear(param, flags); +} +void Plugin::param_request_flush() +{ + _parentHost->param_request_flush(); +} - // Query an extension. - // [thread-safe] - const void* Plugin::clapExtension(const clap_host* host, const char* extension) - { - if (!strcmp(extension, CLAP_EXT_LOG)) return &HostExt::log; - if (!strcmp(extension, CLAP_EXT_PARAMS)) return &HostExt::params; - if (!strcmp(extension, CLAP_EXT_THREAD_CHECK)) return &HostExt::threadcheck; - if (!strcmp(extension, CLAP_EXT_GUI)) return &HostExt::hostgui; - if (!strcmp(extension, CLAP_EXT_TIMER_SUPPORT)) return &HostExt::hosttimer; +// Query an extension. +// [thread-safe] +const void* Plugin::clapExtension(const clap_host* host, const char* extension) +{ + if (!strcmp(extension, CLAP_EXT_LOG)) return &HostExt::log; + if (!strcmp(extension, CLAP_EXT_PARAMS)) return &HostExt::params; + if (!strcmp(extension, CLAP_EXT_THREAD_CHECK)) return &HostExt::threadcheck; + if (!strcmp(extension, CLAP_EXT_GUI)) return &HostExt::hostgui; + if (!strcmp(extension, CLAP_EXT_TIMER_SUPPORT)) return &HostExt::hosttimer; #if LIN - if (!strcmp(extension, CLAP_EXT_POSIX_FD_SUPPORT)) return &HostExt::hostposixfd; + if (!strcmp(extension, CLAP_EXT_POSIX_FD_SUPPORT)) return &HostExt::hostposixfd; #endif - if (!strcmp(extension, CLAP_EXT_LATENCY)) return &HostExt::latency; - if (!strcmp(extension, CLAP_EXT_TAIL)) - { - return &HostExt::tail; - } - if (!strcmp(extension, CLAP_EXT_RENDER)) - { - // TODO: implement CLAP_EXT_RENDER - } - - return nullptr; - } - - // Request the host to schedule a call to plugin->on_main_thread(plugin) on the main thread. - // [thread-safe] - void Plugin::clapRequestCallback(const clap_host* host) + if (!strcmp(extension, CLAP_EXT_LATENCY)) return &HostExt::latency; + if (!strcmp(extension, CLAP_EXT_TAIL)) { - auto self = static_cast(host->host_data); - self->_parentHost->request_callback(); + return &HostExt::tail; } - - // Request the host to deactivate and then reactivate the plugin. - // The operation may be delayed by the host. - // [thread-safe] - void Plugin::clapRequestRestart(const clap_host* host) + if (!strcmp(extension, CLAP_EXT_RENDER)) { - auto self = static_cast(host->host_data); - self->_parentHost->restartPlugin(); + // TODO: implement CLAP_EXT_RENDER } - // Request the host to activate and start processing the plugin. - // This is useful if you have external IO and need to wake up the plugin from "sleep". - // [thread-safe] - void Plugin::clapRequestProcess(const clap_host* host) - { - // right now, I don't know how to communicate this to the host - // in VST3 you can't force processing... - } + return nullptr; +} - // 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 Plugin::register_timer(uint32_t period_ms, clap_id* timer_id) - { - return _parentHost->register_timer(period_ms, timer_id); - } - bool Plugin::unregister_timer(clap_id timer_id) - { - return _parentHost->unregister_timer(timer_id); - } +// Request the host to schedule a call to plugin->on_main_thread(plugin) on the main thread. +// [thread-safe] +void Plugin::clapRequestCallback(const clap_host* host) +{ + auto self = static_cast(host->host_data); + self->_parentHost->request_callback(); +} + +// Request the host to deactivate and then reactivate the plugin. +// The operation may be delayed by the host. +// [thread-safe] +void Plugin::clapRequestRestart(const clap_host* host) +{ + auto self = static_cast(host->host_data); + self->_parentHost->restartPlugin(); +} + +// Request the host to activate and start processing the plugin. +// This is useful if you have external IO and need to wake up the plugin from "sleep". +// [thread-safe] +void Plugin::clapRequestProcess(const clap_host* host) +{ + // right now, I don't know how to communicate this to the host + // in VST3 you can't force processing... +} + +// 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 Plugin::register_timer(uint32_t period_ms, clap_id* timer_id) +{ + return _parentHost->register_timer(period_ms, timer_id); +} +bool Plugin::unregister_timer(clap_id timer_id) +{ + return _parentHost->unregister_timer(timer_id); +} #if LIN - bool Plugin::register_fd(int fd, clap_posix_fd_flags_t flags) - { - return _parentHost->register_fd(fd, flags); - } - bool Plugin::modify_fd(int fd, clap_posix_fd_flags_t flags) - { - return _parentHost->modify_fd(fd, flags); - } - bool Plugin::unregister_fd(int fd) - { - return _parentHost->unregister_fd(fd); - } +bool Plugin::register_fd(int fd, clap_posix_fd_flags_t flags) +{ + return _parentHost->register_fd(fd, flags); +} +bool Plugin::modify_fd(int fd, clap_posix_fd_flags_t flags) +{ + return _parentHost->modify_fd(fd, flags); +} +bool Plugin::unregister_fd(int fd) +{ + return _parentHost->unregister_fd(fd); +} #endif } // namespace Clap diff --git a/src/clap_proxy.h b/src/clap_proxy.h index 53f7cb27..e73a709a 100644 --- a/src/clap_proxy.h +++ b/src/clap_proxy.h @@ -28,205 +28,204 @@ namespace Clap { - class Plugin; - class Raise; +class Plugin; +class Raise; - // the IHost interface is being implemented by the actual wrapper class - class IHost - { - public: - virtual void mark_dirty() = 0; - virtual void restartPlugin() = 0; - virtual void request_callback() = 0; - - virtual void setupWrapperSpecifics( - const clap_plugin_t* - plugin) = 0; // called when a wrapper could scan for wrapper specific plugins - - virtual void setupAudioBusses( - const clap_plugin_t* plugin, - const clap_plugin_audio_ports_t* - audioports) = 0; // called from initialize() to allow the setup of audio ports - virtual void setupMIDIBusses( - const clap_plugin_t* plugin, - const clap_plugin_note_ports_t* - noteports) = 0; // called from initialize() to allow the setup of MIDI ports - virtual void setupParameters(const clap_plugin_t* plugin, const clap_plugin_params_t* params) = 0; - - virtual void param_rescan(clap_param_rescan_flags flags) = 0; // ext_host_params - virtual void param_clear(clap_id param, clap_param_clear_flags flags) = 0; - virtual void param_request_flush() = 0; - - virtual bool gui_can_resize() = 0; - virtual bool gui_request_resize(uint32_t width, uint32_t height) = 0; - virtual bool gui_request_show() = 0; - virtual bool gui_request_hide() = 0; - - virtual bool register_timer(uint32_t period_ms, clap_id* timer_id) = 0; - virtual bool unregister_timer(clap_id timer_id) = 0; +// the IHost interface is being implemented by the actual wrapper class +class IHost +{ + public: + virtual void mark_dirty() = 0; + virtual void restartPlugin() = 0; + virtual void request_callback() = 0; + + virtual void setupWrapperSpecifics( + const clap_plugin_t* plugin) = 0; // called when a wrapper could scan for wrapper specific plugins + + virtual void setupAudioBusses( + const clap_plugin_t* plugin, + const clap_plugin_audio_ports_t* + audioports) = 0; // called from initialize() to allow the setup of audio ports + virtual void setupMIDIBusses( + const clap_plugin_t* plugin, + const clap_plugin_note_ports_t* + noteports) = 0; // called from initialize() to allow the setup of MIDI ports + virtual void setupParameters(const clap_plugin_t* plugin, const clap_plugin_params_t* params) = 0; + + virtual void param_rescan(clap_param_rescan_flags flags) = 0; // ext_host_params + virtual void param_clear(clap_id param, clap_param_clear_flags flags) = 0; + virtual void param_request_flush() = 0; + + virtual bool gui_can_resize() = 0; + virtual bool gui_request_resize(uint32_t width, uint32_t height) = 0; + virtual bool gui_request_show() = 0; + virtual bool gui_request_hide() = 0; + + virtual bool register_timer(uint32_t period_ms, clap_id* timer_id) = 0; + virtual bool unregister_timer(clap_id timer_id) = 0; #if LIN - virtual bool register_fd(int fd, clap_posix_fd_flags_t flags) = 0; - virtual bool modify_fd(int fd, clap_posix_fd_flags_t flags) = 0; - virtual bool unregister_fd(int fd) = 0; + virtual bool register_fd(int fd, clap_posix_fd_flags_t flags) = 0; + virtual bool modify_fd(int fd, clap_posix_fd_flags_t flags) = 0; + virtual bool unregister_fd(int fd) = 0; #endif - virtual void latency_changed() = 0; + virtual void latency_changed() = 0; - virtual void tail_changed() = 0; - }; + virtual void tail_changed() = 0; +}; - struct ClapPluginExtensions; +struct ClapPluginExtensions; - struct AudioSetup - { - double sampleRate = 44100.; - uint32_t minFrames = 0; - uint32_t maxFrames = 0; - }; +struct AudioSetup +{ + double sampleRate = 44100.; + uint32_t minFrames = 0; + uint32_t maxFrames = 0; +}; - struct ClapPluginExtensions - { - const clap_plugin_state_t* _state = nullptr; - const clap_plugin_params_t* _params = nullptr; - const clap_plugin_audio_ports_t* _audioports = nullptr; - const clap_plugin_gui_t* _gui = nullptr; - const clap_plugin_note_ports_t* _noteports = nullptr; - const clap_plugin_midi_mappings_t* _midimap = nullptr; - const clap_plugin_latency_t* _latency = nullptr; - const clap_plugin_render_t* _render = nullptr; - const clap_plugin_tail_t* _tail = nullptr; - const clap_plugin_timer_support_t* _timer = nullptr; +struct ClapPluginExtensions +{ + const clap_plugin_state_t* _state = nullptr; + const clap_plugin_params_t* _params = nullptr; + const clap_plugin_audio_ports_t* _audioports = nullptr; + const clap_plugin_gui_t* _gui = nullptr; + const clap_plugin_note_ports_t* _noteports = nullptr; + const clap_plugin_midi_mappings_t* _midimap = nullptr; + const clap_plugin_latency_t* _latency = nullptr; + const clap_plugin_render_t* _render = nullptr; + const clap_plugin_tail_t* _tail = nullptr; + const clap_plugin_timer_support_t* _timer = nullptr; #if LIN - const clap_plugin_posix_fd_support* _posixfd = nullptr; + const clap_plugin_posix_fd_support* _posixfd = nullptr; #endif - }; +}; - class Raise +class Raise +{ + public: + Raise(std::atomic& counter) : ctx(counter) { - public: - Raise(std::atomic& counter) : ctx(counter) - { - ++ctx; - } - ~Raise() - { - ctx--; - } - - private: - std::atomic& ctx; - }; - - /// - /// Plugin is the `host` for the CLAP plugin instance - /// and the interface for the VST3 plugin wrapper - /// - class Plugin + ++ctx; + } + ~Raise() { - public: - static std::shared_ptr createInstance(Clap::Library& library, size_t index, IHost* host); + ctx--; + } + + private: + std::atomic& ctx; +}; + +/// +/// Plugin is the `host` for the CLAP plugin instance +/// and the interface for the VST3 plugin wrapper +/// +class Plugin +{ + public: + static std::shared_ptr createInstance(Clap::Library& library, size_t index, IHost* host); - protected: - // only the Clap::Library is allowed to create instances - Plugin(IHost* host); - const clap_host_t* getClapHostInterface() - { - return &_host; - } - void connectClap(const clap_plugin_t* clap); - - public: - Plugin(const Plugin&) = delete; - Plugin(Plugin&&) = delete; - Plugin& operator=(const Plugin&) = delete; - Plugin& operator=(Plugin&&) = delete; - ~Plugin(); - - void schnick(); - bool initialize(); - void terminate(); - void setSampleRate(double sampleRate); - void setBlockSizes(uint32_t minFrames, uint32_t maxFrames); - - bool load(const clap_istream_t* stream); - bool save(const clap_ostream_t* stream); - bool activate(); - void deactivate(); - bool start_processing(); - void stop_processing(); - // void process(const clap_process_t* data); - const clap_plugin_gui_t* getUI(); - - ClapPluginExtensions _ext; - const clap_plugin_t* _plugin = nullptr; - void log(clap_log_severity severity, const char* msg); - - // threadcheck - bool is_main_thread() const; - bool is_audio_thread() const; - - // param - void param_rescan(clap_param_rescan_flags flags); - void param_clear(clap_id param, clap_param_clear_flags flags); - void param_request_flush(); - - // latency - void latency_changed(); - - // tail - void tail_changed(); - - // hostgui - void resize_hints_changed() - { - } - bool request_resize(uint32_t width, uint32_t height) - { - if (_parentHost->gui_can_resize()) - { - _parentHost->gui_request_resize(width, height); - return true; - } - return false; - } - bool request_show() - { - return _parentHost->gui_request_show(); - } - bool request_hide() - { - return false; - } - void closed(bool was_destroyed) + protected: + // only the Clap::Library is allowed to create instances + Plugin(IHost* host); + const clap_host_t* getClapHostInterface() + { + return &_host; + } + void connectClap(const clap_plugin_t* clap); + + public: + Plugin(const Plugin&) = delete; + Plugin(Plugin&&) = delete; + Plugin& operator=(const Plugin&) = delete; + Plugin& operator=(Plugin&&) = delete; + ~Plugin(); + + void schnick(); + bool initialize(); + void terminate(); + void setSampleRate(double sampleRate); + void setBlockSizes(uint32_t minFrames, uint32_t maxFrames); + + bool load(const clap_istream_t* stream); + bool save(const clap_ostream_t* stream); + bool activate(); + void deactivate(); + bool start_processing(); + void stop_processing(); + // void process(const clap_process_t* data); + const clap_plugin_gui_t* getUI(); + + ClapPluginExtensions _ext; + const clap_plugin_t* _plugin = nullptr; + void log(clap_log_severity severity, const char* msg); + + // threadcheck + bool is_main_thread() const; + bool is_audio_thread() const; + + // param + void param_rescan(clap_param_rescan_flags flags); + void param_clear(clap_id param, clap_param_clear_flags flags); + void param_request_flush(); + + // latency + void latency_changed(); + + // tail + void tail_changed(); + + // hostgui + void resize_hints_changed() + { + } + bool request_resize(uint32_t width, uint32_t height) + { + if (_parentHost->gui_can_resize()) { + _parentHost->gui_request_resize(width, height); + return true; } + return false; + } + bool request_show() + { + return _parentHost->gui_request_show(); + } + bool request_hide() + { + return false; + } + void closed(bool was_destroyed) + { + } - // clap_timer support - bool register_timer(uint32_t period_ms, clap_id* timer_id); - bool unregister_timer(clap_id timer_id); + // clap_timer support + bool register_timer(uint32_t period_ms, clap_id* timer_id); + bool unregister_timer(clap_id timer_id); #if LIN - bool register_fd(int fd, clap_posix_fd_flags_t flags); - bool modify_fd(int fd, clap_posix_fd_flags_t flags); - bool unregister_fd(int fd); + bool register_fd(int fd, clap_posix_fd_flags_t flags); + bool modify_fd(int fd, clap_posix_fd_flags_t flags); + bool unregister_fd(int fd); #endif - CLAP_NODISCARD Raise AlwaysAudioThread(); - - private: - static const void* clapExtension(const clap_host* host, const char* extension); - static void clapRequestCallback(const clap_host* host); - static void clapRequestRestart(const clap_host* host); - static void clapRequestProcess(const clap_host* host); - - //static bool clapIsMainThread(const clap_host* host); - //static bool clapIsAudioThread(const clap_host* host); - - clap_host_t _host; // the host_t structure for the proxy - IHost* _parentHost = nullptr; - const std::thread::id _main_thread_id = std::this_thread::get_id(); - std::atomic _audio_thread_override = 0; - AudioSetup _audioSetup; - }; + CLAP_NODISCARD Raise AlwaysAudioThread(); + + private: + static const void* clapExtension(const clap_host* host, const char* extension); + static void clapRequestCallback(const clap_host* host); + static void clapRequestRestart(const clap_host* host); + static void clapRequestProcess(const clap_host* host); + + //static bool clapIsMainThread(const clap_host* host); + //static bool clapIsAudioThread(const clap_host* host); + + clap_host_t _host; // the host_t structure for the proxy + IHost* _parentHost = nullptr; + const std::thread::id _main_thread_id = std::this_thread::get_id(); + std::atomic _audio_thread_override = 0; + AudioSetup _audioSetup; +}; } // namespace Clap \ No newline at end of file diff --git a/src/detail/auv2/auv2_base_classes.h b/src/detail/auv2/auv2_base_classes.h index ce06a101..ff3f1d45 100644 --- a/src/detail/auv2/auv2_base_classes.h +++ b/src/detail/auv2/auv2_base_classes.h @@ -15,68 +15,68 @@ namespace free_audio::auv2_wrapper { - // ------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- - class ClapWrapper_AUV2_Effect : public ausdk::AUEffectBase +class ClapWrapper_AUV2_Effect : public ausdk::AUEffectBase +{ + using Base = ausdk::AUEffectBase; + ClapBridge bridge; + + public: + explicit ClapWrapper_AUV2_Effect(const std::string &clapname, const std::string &clapid, int clapidx, + AudioComponentInstance ci) + : Base{ci, true}, bridge(clapname, clapid, clapidx) { - using Base = ausdk::AUEffectBase; - ClapBridge bridge; - - public: - explicit ClapWrapper_AUV2_Effect(const std::string &clapname, const std::string &clapid, int clapidx, - AudioComponentInstance ci) - : Base{ci, true}, bridge(clapname, clapid, clapidx) - { - std::cout << "[clap-wrapper] auv2: creating effect" << std::endl; - std::cout << "[clap-wrapper] auv2: id='" << clapid << "' index=" << clapidx << std::endl; - - bridge.initialize(); - } - }; - - class ClapWrapper_AUV2_NoteEffect : public ausdk::AUMIDIEffectBase + std::cout << "[clap-wrapper] auv2: creating effect" << std::endl; + std::cout << "[clap-wrapper] auv2: id='" << clapid << "' index=" << clapidx << std::endl; + + bridge.initialize(); + } +}; + +class ClapWrapper_AUV2_NoteEffect : public ausdk::AUMIDIEffectBase +{ + using Base = ausdk::AUMIDIEffectBase; + ClapBridge bridge; + + public: + explicit ClapWrapper_AUV2_NoteEffect(const std::string &clapname, const std::string &clapid, + int clapidx, AudioComponentInstance ci) + : Base{ci, true}, bridge(clapname, clapid, clapidx) { - using Base = ausdk::AUMIDIEffectBase; - ClapBridge bridge; + std::cout << "[clap-wrapper] auv2: creating note effect" << std::endl; + std::cout << "[clap-wrapper] auv2: id='" << clapid << "' index=" << clapidx << std::endl; - public: - explicit ClapWrapper_AUV2_NoteEffect(const std::string &clapname, const std::string &clapid, - int clapidx, AudioComponentInstance ci) - : Base{ci, true}, bridge(clapname, clapid, clapidx) - { - std::cout << "[clap-wrapper] auv2: creating note effect" << std::endl; - std::cout << "[clap-wrapper] auv2: id='" << clapid << "' index=" << clapidx << std::endl; + bridge.initialize(); + } +}; - bridge.initialize(); - } - }; +// ------------------------------------------------------------------------------------------------- - // ------------------------------------------------------------------------------------------------- +class ClapWrapper_AUV2_Instrument : public ausdk::MusicDeviceBase +{ + using Base = ausdk::MusicDeviceBase; + ClapBridge bridge; + + public: + explicit ClapWrapper_AUV2_Instrument(const std::string &clapname, const std::string &clapid, + int clapidx, AudioComponentInstance ci) + : Base{ci, 0, 1}, bridge(clapname, clapid, clapidx) + { + std::cout << "[clap-wrapper] auv2: creating instrument" << std::endl; + std::cout << "[clap-wrapper] auv2: id='" << clapid << "' index=" << clapidx << std::endl; + + bridge.initialize(); + } + + bool StreamFormatWritable(AudioUnitScope, AudioUnitElement) override + { + return true; + } - class ClapWrapper_AUV2_Instrument : public ausdk::MusicDeviceBase + bool CanScheduleParameters() const override { - using Base = ausdk::MusicDeviceBase; - ClapBridge bridge; - - public: - explicit ClapWrapper_AUV2_Instrument(const std::string &clapname, const std::string &clapid, - int clapidx, AudioComponentInstance ci) - : Base{ci, 0, 1}, bridge(clapname, clapid, clapidx) - { - std::cout << "[clap-wrapper] auv2: creating instrument" << std::endl; - std::cout << "[clap-wrapper] auv2: id='" << clapid << "' index=" << clapidx << std::endl; - - bridge.initialize(); - } - - bool StreamFormatWritable(AudioUnitScope, AudioUnitElement) override - { - return true; - } - - bool CanScheduleParameters() const override - { - return false; - } - }; + return false; + } +}; } // namespace free_audio::auv2_wrapper \ No newline at end of file diff --git a/src/detail/auv2/auv2_shared.h b/src/detail/auv2/auv2_shared.h index 57e5ea64..99ce22df 100644 --- a/src/detail/auv2/auv2_shared.h +++ b/src/detail/auv2/auv2_shared.h @@ -6,79 +6,79 @@ namespace free_audio::auv2_wrapper { - struct ClapBridge - { - std::string _clapname; - std::string _clapid; - int _idx; +struct ClapBridge +{ + std::string _clapname; + std::string _clapid; + int _idx; - Clap::Library _library; + Clap::Library _library; - const clap_plugin_descriptor_t *_desc{nullptr}; + const clap_plugin_descriptor_t *_desc{nullptr}; - ClapBridge(const std::string &clapname, const std::string &clapid, int idx) - : _clapname(clapname), _clapid(clapid), _idx(idx) - { - std::cout << "[clap-wraper] auv2: creating clap bridge nm=" << clapname << " id=" << clapid - << " idx=" << idx << std::endl; - } + ClapBridge(const std::string &clapname, const std::string &clapid, int idx) + : _clapname(clapname), _clapid(clapid), _idx(idx) + { + std::cout << "[clap-wraper] auv2: creating clap bridge nm=" << clapname << " id=" << clapid + << " idx=" << idx << std::endl; + } - void initialize() + void initialize() + { + if (!_library.hasEntryPoint()) { - if (!_library.hasEntryPoint()) + if (_clapname.empty()) { - if (_clapname.empty()) - { - std::cout << "[ERROR] _clapname (" << _clapname << ") empty and no internal entry point" - << std::endl; - } - bool loaded{false}; - auto csp = Clap::getValidCLAPSearchPaths(); - for (auto &cs : csp) - { - if (fs::is_directory(cs / (_clapname + ".clap"))) - if (_library.load(_clapname.c_str())) - { - std::cout << "[clap-wrapper] auv2 loaded clap from " << cs.u8string() << std::endl; - loaded = true; - break; - } - } - if (!loaded) - { - std::cout << "[ERROR] cannot load clap" << std::endl; - return; - } - } - - if (_clapid.empty()) - { - if (_idx < 0 || _idx >= _library.plugins.size()) - { - std::cout << "[ERROR] cannot load by index" << std::endl; - return; - } - _desc = _library.plugins[_idx]; + std::cout << "[ERROR] _clapname (" << _clapname << ") empty and no internal entry point" + << std::endl; } - else + bool loaded{false}; + auto csp = Clap::getValidCLAPSearchPaths(); + for (auto &cs : csp) { - for (auto *d : _library.plugins) - { - if (strcmp(d->id, _clapid.c_str()) == 0) + if (fs::is_directory(cs / (_clapname + ".clap"))) + if (_library.load(_clapname.c_str())) { - _desc = d; + std::cout << "[clap-wrapper] auv2 loaded clap from " << cs.u8string() << std::endl; + loaded = true; + break; } - } } + if (!loaded) + { + std::cout << "[ERROR] cannot load clap" << std::endl; + return; + } + } - if (!_desc) + if (_clapid.empty()) + { + if (_idx < 0 || _idx >= _library.plugins.size()) { - std::cout << "[ERROR] cannot determine plugin description" << std::endl; + std::cout << "[ERROR] cannot load by index" << std::endl; return; } + _desc = _library.plugins[_idx]; + } + else + { + for (auto *d : _library.plugins) + { + if (strcmp(d->id, _clapid.c_str()) == 0) + { + _desc = d; + } + } + } - std::cout << "[clap-wrapper] auv2: Initialized '" << _desc->id << "' / '" << _desc->name << "'" - << std::endl; + if (!_desc) + { + std::cout << "[ERROR] cannot determine plugin description" << std::endl; + return; } - }; + + std::cout << "[clap-wrapper] auv2: Initialized '" << _desc->id << "' / '" << _desc->name << "'" + << std::endl; + } +}; } // namespace free_audio::auv2_wrapper \ No newline at end of file diff --git a/src/detail/clap/automation.h b/src/detail/clap/automation.h index 98535b9f..c6a30179 100644 --- a/src/detail/clap/automation.h +++ b/src/detail/clap/automation.h @@ -4,14 +4,14 @@ namespace Clap { - class IAutomation +class IAutomation +{ + public: + virtual void onBeginEdit(clap_id id) = 0; + virtual void onPerformEdit(const clap_event_param_value_t* value) = 0; + virtual void onEndEdit(clap_id id) = 0; + virtual ~IAutomation() { - public: - virtual void onBeginEdit(clap_id id) = 0; - virtual void onPerformEdit(const clap_event_param_value_t* value) = 0; - virtual void onEndEdit(clap_id id) = 0; - virtual ~IAutomation() - { - } - }; + } +}; } // namespace Clap \ No newline at end of file diff --git a/src/detail/clap/fsutil.cpp b/src/detail/clap/fsutil.cpp index a1fa15b8..d84246b3 100644 --- a/src/detail/clap/fsutil.cpp +++ b/src/detail/clap/fsutil.cpp @@ -27,312 +27,312 @@ namespace Clap { #if WIN - std::string getEnvVariable(const char *varname) - { - char *val; - size_t len; - auto err = _dupenv_s(&val, &len, varname); - if (err) return std::string(); - if (val == nullptr) return std::string(); - std::string result(val); - free(val); - return result; - } +std::string getEnvVariable(const char *varname) +{ + char *val; + size_t len; + auto err = _dupenv_s(&val, &len, varname); + if (err) return std::string(); + if (val == nullptr) return std::string(); + std::string result(val); + free(val); + return result; +} #endif - std::vector getValidCLAPSearchPaths() - { - std::vector res; +std::vector getValidCLAPSearchPaths() +{ + std::vector res; #if MAC - extern std::vector getMacCLAPSearchPaths(); - res = getMacCLAPSearchPaths(); - // getSystemPaths(res); + extern std::vector getMacCLAPSearchPaths(); + res = getMacCLAPSearchPaths(); + // getSystemPaths(res); #endif #if LIN - res.emplace_back("/usr/lib/clap"); - res.emplace_back(fs::path(getenv("HOME")) / fs::path(".clap")); + res.emplace_back("/usr/lib/clap"); + res.emplace_back(fs::path(getenv("HOME")) / fs::path(".clap")); #endif #if WIN + { + // I think this should use SHGetKnownFilderLocation but I don't know windows well enough + auto p = getEnvVariable("COMMONPROGRAMFILES"); + if (!p.empty()) { - // I think this should use SHGetKnownFilderLocation but I don't know windows well enough - auto p = getEnvVariable("COMMONPROGRAMFILES"); - if (!p.empty()) - { - res.emplace_back(fs::path{p} / "CLAP"); - } - auto q = getEnvVariable("LOCALAPPDATA"); - if (!q.empty()) - { - res.emplace_back(fs::path{q} / "Programs" / "Common" / "CLAP"); - } + res.emplace_back(fs::path{p} / "CLAP"); } - auto cp = getEnvVariable("CLAP_PATH"); - auto sep = ';'; -#else - std::string cp; - auto p = getenv("CLAP_PATH"); - if (p) + auto q = getEnvVariable("LOCALAPPDATA"); + if (!q.empty()) { - cp = std::string(p); + res.emplace_back(fs::path{q} / "Programs" / "Common" / "CLAP"); } - auto sep = ':'; + } + auto cp = getEnvVariable("CLAP_PATH"); + auto sep = ';'; +#else + std::string cp; + auto p = getenv("CLAP_PATH"); + if (p) + { + cp = std::string(p); + } + auto sep = ':'; #endif - if (cp.empty()) + if (cp.empty()) + { + size_t pos; + while ((pos = cp.find(sep)) != std::string::npos) { - size_t pos; - while ((pos = cp.find(sep)) != std::string::npos) - { - auto item = cp.substr(0, pos); - cp = cp.substr(pos + 1); - res.emplace_back(fs::path{item}); - } - if (cp.size()) res.emplace_back(fs::path{cp}); + auto item = cp.substr(0, pos); + cp = cp.substr(pos + 1); + res.emplace_back(fs::path{item}); } - - return res; + if (cp.size()) res.emplace_back(fs::path{cp}); } - bool Library::load(const char *name) - { + return res; +} + +bool Library::load(const char *name) +{ #if MAC - _pluginEntry = nullptr; + _pluginEntry = nullptr; - auto cs = CFStringCreateWithBytes(kCFAllocatorDefault, (uint8_t *)name, strlen(name), - kCFStringEncodingUTF8, false); - auto bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, cs, kCFURLPOSIXPathStyle, true); + auto cs = CFStringCreateWithBytes(kCFAllocatorDefault, (uint8_t *)name, strlen(name), + kCFStringEncodingUTF8, false); + auto bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, cs, kCFURLPOSIXPathStyle, true); - _bundle = CFBundleCreate(kCFAllocatorDefault, bundleURL); - CFRelease(bundleURL); - CFRelease(cs); + _bundle = CFBundleCreate(kCFAllocatorDefault, bundleURL); + CFRelease(bundleURL); + CFRelease(cs); - if (!_bundle) - { - return false; - } + if (!_bundle) + { + return false; + } - auto db = CFBundleGetDataPointerForName(_bundle, CFSTR("clap_entry")); + auto db = CFBundleGetDataPointerForName(_bundle, CFSTR("clap_entry")); - _pluginEntry = (const clap_plugin_entry *)db; + _pluginEntry = (const clap_plugin_entry *)db; - setupPluginsFromPluginEntry(name); - return _pluginEntry != nullptr; + setupPluginsFromPluginEntry(name); + return _pluginEntry != nullptr; #endif #if WIN - if (_handle && !_selfcontained) + if (_handle && !_selfcontained) + { + if (_pluginEntry) { - if (_pluginEntry) - { - _pluginEntry->deinit(); - } - FreeLibrary(_handle); + _pluginEntry->deinit(); } - _handle = 0; - _pluginEntry = nullptr; - _handle = LoadLibraryA(name); - if (_handle) + FreeLibrary(_handle); + } + _handle = 0; + _pluginEntry = nullptr; + _handle = LoadLibraryA(name); + if (_handle) + { + if (!getEntryFunction(_handle, name)) { - if (!getEntryFunction(_handle, name)) - { - FreeLibrary(_handle); - _handle = NULL; - } + FreeLibrary(_handle); + _handle = NULL; } + } - return _handle != 0; + return _handle != 0; #endif #if LIN - int *iptr; + int *iptr; - _handle = dlopen(name, RTLD_LOCAL | RTLD_LAZY); - if (!_handle) return false; + _handle = dlopen(name, RTLD_LOCAL | RTLD_LAZY); + if (!_handle) return false; - iptr = (int *)dlsym(_handle, "clap_entry"); - if (!iptr) return false; + iptr = (int *)dlsym(_handle, "clap_entry"); + if (!iptr) return false; - _pluginEntry = (const clap_plugin_entry_t *)iptr; - setupPluginsFromPluginEntry(name); - return true; + _pluginEntry = (const clap_plugin_entry_t *)iptr; + setupPluginsFromPluginEntry(name); + return true; #endif - } +} - const clap_plugin_info_as_vst3_t *Library::get_vst3_info(uint32_t index) +const clap_plugin_info_as_vst3_t *Library::get_vst3_info(uint32_t index) +{ + if (_pluginFactoryVst3Info && _pluginFactoryVst3Info->get_vst3_info) { - if (_pluginFactoryVst3Info && _pluginFactoryVst3Info->get_vst3_info) - { - return _pluginFactoryVst3Info->get_vst3_info(_pluginFactoryVst3Info, index); - } - return nullptr; + return _pluginFactoryVst3Info->get_vst3_info(_pluginFactoryVst3Info, index); } + return nullptr; +} #if WIN - bool Library::getEntryFunction(HMODULE handle, const char *path) +bool Library::getEntryFunction(HMODULE handle, const char *path) +{ + if (handle) { - if (handle) + _pluginEntry = reinterpret_cast(GetProcAddress(handle, "clap_entry")); + if (_pluginEntry) { - _pluginEntry = reinterpret_cast(GetProcAddress(handle, "clap_entry")); - if (_pluginEntry) - { - setupPluginsFromPluginEntry(path); - } + setupPluginsFromPluginEntry(path); } - return (_pluginEntry && !plugins.empty()); } + return (_pluginEntry && !plugins.empty()); +} #endif - void Library::setupPluginsFromPluginEntry(const char *path) +void Library::setupPluginsFromPluginEntry(const char *path) +{ + if (clap_version_is_compatible(_pluginEntry->clap_version)) { - if (clap_version_is_compatible(_pluginEntry->clap_version)) + if (_pluginEntry->init(path)) { - if (_pluginEntry->init(path)) + _pluginFactory = + static_cast(_pluginEntry->get_factory(CLAP_PLUGIN_FACTORY_ID)); + _pluginFactoryVst3Info = static_cast( + _pluginEntry->get_factory(CLAP_PLUGIN_FACTORY_INFO_VST3)); + _pluginFactoryAUv2Info = static_cast( + _pluginEntry->get_factory(CLAP_PLUGIN_FACTORY_INFO_AUV2)); + + // detect plugins that do not check the CLAP_PLUGIN_FACTORY_ID + if ((void *)_pluginFactory == (void *)_pluginFactoryVst3Info) { - _pluginFactory = - static_cast(_pluginEntry->get_factory(CLAP_PLUGIN_FACTORY_ID)); - _pluginFactoryVst3Info = static_cast( - _pluginEntry->get_factory(CLAP_PLUGIN_FACTORY_INFO_VST3)); - _pluginFactoryAUv2Info = static_cast( - _pluginEntry->get_factory(CLAP_PLUGIN_FACTORY_INFO_AUV2)); - - // detect plugins that do not check the CLAP_PLUGIN_FACTORY_ID - if ((void *)_pluginFactory == (void *)_pluginFactoryVst3Info) - { - _pluginFactoryVst3Info = nullptr; - _pluginFactoryAUv2Info = nullptr; - } + _pluginFactoryVst3Info = nullptr; + _pluginFactoryAUv2Info = nullptr; + } - auto count = _pluginFactory->get_plugin_count(_pluginFactory); + auto count = _pluginFactory->get_plugin_count(_pluginFactory); - for (decltype(count) i = 0; i < count; ++i) + for (decltype(count) i = 0; i < count; ++i) + { + auto desc = _pluginFactory->get_plugin_descriptor(_pluginFactory, i); + if (clap_version_is_compatible(desc->clap_version)) + { + plugins.push_back(desc); + } + else { - auto desc = _pluginFactory->get_plugin_descriptor(_pluginFactory, i); - if (clap_version_is_compatible(desc->clap_version)) - { - plugins.push_back(desc); - } - else - { - // incompatible - } + // incompatible } } } } +} #if WIN || LIN - // This is a small stub to resolve the self dll. MacOs uses a different approach - // in sharedLibraryBundlePath - static void ffeomwe() - { - } +// This is a small stub to resolve the self dll. MacOs uses a different approach +// in sharedLibraryBundlePath +static void ffeomwe() +{ +} #endif - Library::Library() - { +Library::Library() +{ #if WIN - static TCHAR modulename[2048]; - HMODULE selfmodule; - if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)ffeomwe, &selfmodule)) + static TCHAR modulename[2048]; + HMODULE selfmodule; + if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)ffeomwe, &selfmodule)) + { + auto size = GetModuleFileName(selfmodule, modulename, 2048); + (void)size; + } + if (selfmodule) + { + if (this->getEntryFunction(selfmodule, (const char *)modulename)) { - auto size = GetModuleFileName(selfmodule, modulename, 2048); - (void)size; - } - if (selfmodule) - { - if (this->getEntryFunction(selfmodule, (const char *)modulename)) - { - _selfcontained = true; - } + _selfcontained = true; } + } #endif #if LIN - Dl_info info; - if (dladdr(reinterpret_cast(&ffeomwe), &info) && info.dli_fname[0]) + Dl_info info; + if (dladdr(reinterpret_cast(&ffeomwe), &info) && info.dli_fname[0]) + { + auto lhandle = dlopen(info.dli_fname, RTLD_LOCAL | RTLD_LAZY); + if (lhandle) { - auto lhandle = dlopen(info.dli_fname, RTLD_LOCAL | RTLD_LAZY); - if (lhandle) + auto liptr = (int *)dlsym(_handle, "clap_entry"); + if (liptr) { - auto liptr = (int *)dlsym(_handle, "clap_entry"); - if (liptr) - { - _handle = lhandle; // as a result the Library dtor will dlclose me - _pluginEntry = (const clap_plugin_entry_t *)liptr; - _selfcontained = true; + _handle = lhandle; // as a result the Library dtor will dlclose me + _pluginEntry = (const clap_plugin_entry_t *)liptr; + _selfcontained = true; - setupPluginsFromPluginEntry(info.dli_fname); - } + setupPluginsFromPluginEntry(info.dli_fname); } } + } #endif #if MAC - extern fs::path sharedLibraryBundlePath(); - auto selfp = sharedLibraryBundlePath(); - if (!selfp.empty()) + extern fs::path sharedLibraryBundlePath(); + auto selfp = sharedLibraryBundlePath(); + if (!selfp.empty()) + { + std::string name = selfp.u8string(); + CFURLRef bundleUrl = CFURLCreateFromFileSystemRepresentation(0, (const unsigned char *)name.c_str(), + name.size(), true); + if (bundleUrl) { - std::string name = selfp.u8string(); - CFURLRef bundleUrl = CFURLCreateFromFileSystemRepresentation( - 0, (const unsigned char *)name.c_str(), name.size(), true); - if (bundleUrl) + auto pluginBundle = CFBundleCreate(0, bundleUrl); + CFRelease(bundleUrl); + + if (pluginBundle) { - auto pluginBundle = CFBundleCreate(0, bundleUrl); - CFRelease(bundleUrl); + auto db = CFBundleGetDataPointerForName(pluginBundle, CFSTR("clap_entry")); + if (db) + { + _bundle = pluginBundle; + _pluginEntry = (const clap_plugin_entry_t *)db; + _selfcontained = true; - if (pluginBundle) + setupPluginsFromPluginEntry(selfp.u8string().c_str()); + } + else { - auto db = CFBundleGetDataPointerForName(pluginBundle, CFSTR("clap_entry")); - if (db) - { - _bundle = pluginBundle; - _pluginEntry = (const clap_plugin_entry_t *)db; - _selfcontained = true; - - setupPluginsFromPluginEntry(selfp.u8string().c_str()); - } - else - { - CFRelease(pluginBundle); - } + CFRelease(pluginBundle); } } } -#endif } +#endif +} - Library::~Library() +Library::~Library() +{ + if (_pluginEntry) { - if (_pluginEntry) - { - _pluginEntry->deinit(); - } + _pluginEntry->deinit(); + } #if MAC - // FIXME keep the bundle ref and free it here - if (_bundle) - { - CFRelease(_bundle); - _bundle = nullptr; - } + // FIXME keep the bundle ref and free it here + if (_bundle) + { + CFRelease(_bundle); + _bundle = nullptr; + } #endif #if LIN - if (_handle) - { - dlclose(_handle); - _handle = nullptr; - } + if (_handle) + { + dlclose(_handle); + _handle = nullptr; + } #endif #if WIN - if (_handle && !_selfcontained) - { - FreeLibrary(_handle); - } -#endif + if (_handle && !_selfcontained) + { + FreeLibrary(_handle); } +#endif +} } // namespace Clap diff --git a/src/detail/clap/fsutil.h b/src/detail/clap/fsutil.h index e1fcdb0c..fd1f8c82 100644 --- a/src/detail/clap/fsutil.h +++ b/src/detail/clap/fsutil.h @@ -40,55 +40,55 @@ namespace fs = std::filesystem; namespace Clap { - std::vector getValidCLAPSearchPaths(); - class Plugin; - class IHost; +std::vector getValidCLAPSearchPaths(); +class Plugin; +class IHost; - class Library +class Library +{ + public: + Library(); + ~Library(); + bool load(const char* name); + + const clap_plugin_entry_t* _pluginEntry = nullptr; + const clap_plugin_factory_t* _pluginFactory = nullptr; + const clap_plugin_factory_as_vst3* _pluginFactoryVst3Info = nullptr; + const clap_plugin_factory_as_auv2* _pluginFactoryAUv2Info = nullptr; + std::vector plugins; + const clap_plugin_info_as_vst3_t* get_vst3_info(uint32_t index); + + bool hasEntryPoint() const { - public: - Library(); - ~Library(); - bool load(const char* name); - - const clap_plugin_entry_t* _pluginEntry = nullptr; - const clap_plugin_factory_t* _pluginFactory = nullptr; - const clap_plugin_factory_as_vst3* _pluginFactoryVst3Info = nullptr; - const clap_plugin_factory_as_auv2* _pluginFactoryAUv2Info = nullptr; - std::vector plugins; - const clap_plugin_info_as_vst3_t* get_vst3_info(uint32_t index); - - bool hasEntryPoint() const - { #if WIN - return _handle != 0 || _selfcontained; + return _handle != 0 || _selfcontained; #endif #if MAC - return _bundle != nullptr || _selfcontained; + return _bundle != nullptr || _selfcontained; #endif #if LIN - return _handle != nullptr || _selfcontained; + return _handle != nullptr || _selfcontained; #endif - } + } - private: + private: #if MAC - CFBundleRef _bundle{nullptr}; + CFBundleRef _bundle{nullptr}; #endif #if LIN - void* _handle{nullptr}; + void* _handle{nullptr}; #endif #if WIN - HMODULE _handle = 0; - bool getEntryFunction(HMODULE handle, const char* path); + HMODULE _handle = 0; + bool getEntryFunction(HMODULE handle, const char* path); #endif - void setupPluginsFromPluginEntry(const char* p); - bool _selfcontained = false; - }; + void setupPluginsFromPluginEntry(const char* p); + bool _selfcontained = false; +}; } // namespace Clap diff --git a/src/detail/clap/mac_helpers.mm b/src/detail/clap/mac_helpers.mm index d89b32e1..69e5399e 100644 --- a/src/detail/clap/mac_helpers.mm +++ b/src/detail/clap/mac_helpers.mm @@ -25,80 +25,80 @@ Timo Kaluza (defiantnerd) namespace Clap { - fs::path sharedLibraryBundlePath() +fs::path sharedLibraryBundlePath() +{ + Dl_info info; + if (!dladdr(reinterpret_cast(&sharedLibraryBundlePath), &info) || !info.dli_fname[0]) { - Dl_info info; - if (!dladdr(reinterpret_cast(&sharedLibraryBundlePath), &info) || !info.dli_fname[0]) - { - // If dladdr(3) returns zero, dlerror(3) won't know why either - return {}; - } - try - { - auto res = fs::path{info.dli_fname}; - res = res.parent_path().parent_path(); // this might throw if not in bundle so catch - if (res.filename().u8string() == "Contents" && res.has_parent_path()) - { - // We are properly situated in a bundle in either a MacOS ir an iOS location - return res.parent_path(); - } - } - catch (const fs::filesystem_error &) + // If dladdr(3) returns zero, dlerror(3) won't know why either + return {}; + } + try + { + auto res = fs::path{info.dli_fname}; + res = res.parent_path().parent_path(); // this might throw if not in bundle so catch + if (res.filename().u8string() == "Contents" && res.has_parent_path()) { - // oh well + // We are properly situated in a bundle in either a MacOS ir an iOS location + return res.parent_path(); } - return {}; } - - std::vector getMacCLAPSearchPaths() + catch (const fs::filesystem_error &) { - auto res = std::vector(); + // oh well + } + return {}; +} - auto bundlePath = sharedLibraryBundlePath(); - if (!bundlePath.empty()) +std::vector getMacCLAPSearchPaths() +{ + auto res = std::vector(); + + auto bundlePath = sharedLibraryBundlePath(); + if (!bundlePath.empty()) + { + std::string name = bundlePath.u8string(); + CFURLRef bundleUrl = CFURLCreateFromFileSystemRepresentation(0, (const unsigned char *)name.c_str(), + name.size(), true); + if (bundleUrl) { - std::string name = bundlePath.u8string(); - CFURLRef bundleUrl = CFURLCreateFromFileSystemRepresentation( - 0, (const unsigned char *)name.c_str(), name.size(), true); - if (bundleUrl) + auto pluginBundle = CFBundleCreate(0, bundleUrl); + CFRelease(bundleUrl); + + if (pluginBundle) { - auto pluginBundle = CFBundleCreate(0, bundleUrl); - CFRelease(bundleUrl); + auto pluginFoldersUrl = CFBundleCopyBuiltInPlugInsURL(pluginBundle); - if (pluginBundle) + if (pluginFoldersUrl) { - auto pluginFoldersUrl = CFBundleCopyBuiltInPlugInsURL(pluginBundle); - - if (pluginFoldersUrl) - { - // Remember CFURL and NSURL are toll free bridged - auto *ns = (NSURL *)pluginFoldersUrl; - auto pp = fs::path{[ns fileSystemRepresentation]}; - res.push_back(pp); - CFRelease(pluginFoldersUrl); - } - CFRelease(pluginBundle); + // Remember CFURL and NSURL are toll free bridged + auto *ns = (NSURL *)pluginFoldersUrl; + auto pp = fs::path{[ns fileSystemRepresentation]}; + res.push_back(pp); + CFRelease(pluginFoldersUrl); } + CFRelease(pluginBundle); } } + } - auto *fileManager = [NSFileManager defaultManager]; - auto *userLibURLs = [fileManager URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask]; - auto *sysLibURLs = [fileManager URLsForDirectory:NSLibraryDirectory inDomains:NSLocalDomainMask]; + auto *fileManager = [NSFileManager defaultManager]; + auto *userLibURLs = [fileManager URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask]; + auto *sysLibURLs = [fileManager URLsForDirectory:NSLibraryDirectory inDomains:NSLocalDomainMask]; - if (userLibURLs) - { - auto *u = [userLibURLs objectAtIndex:0]; - auto p = fs::path{[u fileSystemRepresentation]} / "Audio" / "Plug-Ins" / "CLAP"; - res.push_back(p); - } + if (userLibURLs) + { + auto *u = [userLibURLs objectAtIndex:0]; + auto p = fs::path{[u fileSystemRepresentation]} / "Audio" / "Plug-Ins" / "CLAP"; + res.push_back(p); + } - if (sysLibURLs) - { - auto *u = [sysLibURLs objectAtIndex:0]; - auto p = fs::path{[u fileSystemRepresentation]} / "Audio" / "Plug-Ins" / "CLAP"; - res.push_back(p); - } - return res; + if (sysLibURLs) + { + auto *u = [sysLibURLs objectAtIndex:0]; + auto p = fs::path{[u fileSystemRepresentation]} / "Audio" / "Plug-Ins" / "CLAP"; + res.push_back(p); } + return res; +} } \ No newline at end of file diff --git a/src/detail/sha1.cpp b/src/detail/sha1.cpp index d12673b3..79cdd2ff 100644 --- a/src/detail/sha1.cpp +++ b/src/detail/sha1.cpp @@ -8,335 +8,334 @@ static constexpr bool isBigEndian = false; namespace Crypto { - class Sha1 +class Sha1 +{ + public: + Sha1() { - public: - Sha1() - { - reset(); - } - Sha1(const unsigned char* message_array, size_t length) - { - reset(); - input(message_array, length); - } - void input(const unsigned char* message_array, size_t length); - struct sha1hash hash(); - - private: - void reset(); - void processMessageBlock(); - void padmessage(); - inline uint32_t circularShift(int bits, uint32_t word) - { - return ((word << bits) & 0xFFFFFFFF) | ((word & 0xFFFFFFFF) >> (32 - bits)); - } + reset(); + } + Sha1(const unsigned char* message_array, size_t length) + { + reset(); + input(message_array, length); + } + void input(const unsigned char* message_array, size_t length); + struct sha1hash hash(); + + private: + void reset(); + void processMessageBlock(); + void padmessage(); + inline uint32_t circularShift(int bits, uint32_t word) + { + return ((word << bits) & 0xFFFFFFFF) | ((word & 0xFFFFFFFF) >> (32 - bits)); + } + + unsigned H[5] = // Message digest buffers + {0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0}; - unsigned H[5] = // Message digest buffers - {0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0}; + uint32_t _lengthLow = 0; // Message length in bits + uint32_t _length_high = 0; // Message length in bits - uint32_t _lengthLow = 0; // Message length in bits - uint32_t _length_high = 0; // Message length in bits + unsigned char _messageBlock[64] = {0}; // 512-bit message blocks + int _messageBlockIndex = 0; // Index into message block array - unsigned char _messageBlock[64] = {0}; // 512-bit message blocks - int _messageBlockIndex = 0; // Index into message block array + bool _computed = false; // Is the digest computed? + bool _corrupted = false; // Is the message digest corruped? +}; + +void Sha1::reset() +{ + _lengthLow = 0; + _length_high = 0; + _messageBlockIndex = 0; - bool _computed = false; // Is the digest computed? - bool _corrupted = false; // Is the message digest corruped? - }; + H[0] = 0x67452301; + H[1] = 0xEFCDAB89; + H[2] = 0x98BADCFE; + H[3] = 0x10325476; + H[4] = 0xC3D2E1F0; - void Sha1::reset() + _computed = false; + _corrupted = false; +} + +void Sha1::input(const unsigned char* message_array, size_t length) +{ + if (length == 0) { - _lengthLow = 0; - _length_high = 0; - _messageBlockIndex = 0; - - H[0] = 0x67452301; - H[1] = 0xEFCDAB89; - H[2] = 0x98BADCFE; - H[3] = 0x10325476; - H[4] = 0xC3D2E1F0; - - _computed = false; - _corrupted = false; + return; } - void Sha1::input(const unsigned char* message_array, size_t length) + if (_computed || _corrupted) { - if (length == 0) - { - return; - } + _corrupted = true; + return; + } - if (_computed || _corrupted) - { - _corrupted = true; - return; - } + if (_messageBlockIndex >= 64) + { + return; + } - if (_messageBlockIndex >= 64) - { - return; - } + while (length-- && !_corrupted) + { + _messageBlock[_messageBlockIndex++] = (*message_array & 0xFF); - while (length-- && !_corrupted) + _lengthLow += 8; + _lengthLow &= 0xFFFFFFFF; // Force it to 32 bits + if (_lengthLow == 0) { - _messageBlock[_messageBlockIndex++] = (*message_array & 0xFF); - - _lengthLow += 8; - _lengthLow &= 0xFFFFFFFF; // Force it to 32 bits - if (_lengthLow == 0) - { - _length_high++; - _length_high &= 0xFFFFFFFF; // Force it to 32 bits - if (_length_high == 0) - { - _corrupted = true; // Message is too long - } - } - - if (_messageBlockIndex == 64) + _length_high++; + _length_high &= 0xFFFFFFFF; // Force it to 32 bits + if (_length_high == 0) { - processMessageBlock(); + _corrupted = true; // Message is too long } + } - message_array++; + if (_messageBlockIndex == 64) + { + processMessageBlock(); } + + message_array++; } +} - void Sha1::processMessageBlock() - { - const unsigned K[] = {// Constants defined for SHA-1 - 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6}; - int t; // Loop counter - unsigned temp; // Temporary word value - unsigned W[80]; // Word sequence - unsigned A, B, C, D, E; // Word buffers - - /* +void Sha1::processMessageBlock() +{ + const unsigned K[] = {// Constants defined for SHA-1 + 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6}; + int t; // Loop counter + unsigned temp; // Temporary word value + unsigned W[80]; // Word sequence + unsigned A, B, C, D, E; // Word buffers + + /* * Initialize the first 16 words in the array W */ - for (t = 0; t < 16; t++) - { - W[t] = ((unsigned)_messageBlock[t * 4]) << 24; - W[t] |= ((unsigned)_messageBlock[t * 4 + 1]) << 16; - W[t] |= ((unsigned)_messageBlock[t * 4 + 2]) << 8; - W[t] |= ((unsigned)_messageBlock[t * 4 + 3]); - } + for (t = 0; t < 16; t++) + { + W[t] = ((unsigned)_messageBlock[t * 4]) << 24; + W[t] |= ((unsigned)_messageBlock[t * 4 + 1]) << 16; + W[t] |= ((unsigned)_messageBlock[t * 4 + 2]) << 8; + W[t] |= ((unsigned)_messageBlock[t * 4 + 3]); + } - for (t = 16; t < 80; t++) - { - W[t] = circularShift(1, W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]); - } + for (t = 16; t < 80; t++) + { + W[t] = circularShift(1, W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]); + } - A = H[0]; - B = H[1]; - C = H[2]; - D = H[3]; - E = H[4]; + A = H[0]; + B = H[1]; + C = H[2]; + D = H[3]; + E = H[4]; - for (t = 0; t < 20; t++) - { - temp = circularShift(5, A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0]; - temp &= 0xFFFFFFFF; - E = D; - D = C; - C = circularShift(30, B); - B = A; - A = temp; - } + for (t = 0; t < 20; t++) + { + temp = circularShift(5, A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0]; + temp &= 0xFFFFFFFF; + E = D; + D = C; + C = circularShift(30, B); + B = A; + A = temp; + } - for (t = 20; t < 40; t++) - { - temp = circularShift(5, A) + (B ^ C ^ D) + E + W[t] + K[1]; - temp &= 0xFFFFFFFF; - E = D; - D = C; - C = circularShift(30, B); - B = A; - A = temp; - } + for (t = 20; t < 40; t++) + { + temp = circularShift(5, A) + (B ^ C ^ D) + E + W[t] + K[1]; + temp &= 0xFFFFFFFF; + E = D; + D = C; + C = circularShift(30, B); + B = A; + A = temp; + } - for (t = 40; t < 60; t++) - { - temp = circularShift(5, A) + ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]; - temp &= 0xFFFFFFFF; - E = D; - D = C; - C = circularShift(30, B); - B = A; - A = temp; - } + for (t = 40; t < 60; t++) + { + temp = circularShift(5, A) + ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]; + temp &= 0xFFFFFFFF; + E = D; + D = C; + C = circularShift(30, B); + B = A; + A = temp; + } - for (t = 60; t < 80; t++) - { - temp = circularShift(5, A) + (B ^ C ^ D) + E + W[t] + K[3]; - temp &= 0xFFFFFFFF; - E = D; - D = C; - C = circularShift(30, B); - B = A; - A = temp; - } + for (t = 60; t < 80; t++) + { + temp = circularShift(5, A) + (B ^ C ^ D) + E + W[t] + K[3]; + temp &= 0xFFFFFFFF; + E = D; + D = C; + C = circularShift(30, B); + B = A; + A = temp; + } - H[0] = (H[0] + A) & 0xFFFFFFFF; - H[1] = (H[1] + B) & 0xFFFFFFFF; - H[2] = (H[2] + C) & 0xFFFFFFFF; - H[3] = (H[3] + D) & 0xFFFFFFFF; - H[4] = (H[4] + E) & 0xFFFFFFFF; + H[0] = (H[0] + A) & 0xFFFFFFFF; + H[1] = (H[1] + B) & 0xFFFFFFFF; + H[2] = (H[2] + C) & 0xFFFFFFFF; + H[3] = (H[3] + D) & 0xFFFFFFFF; + H[4] = (H[4] + E) & 0xFFFFFFFF; - _messageBlockIndex = 0; - } + _messageBlockIndex = 0; +} - void Sha1::padmessage() - { - /* +void Sha1::padmessage() +{ + /* * Check to see if the current message block is too small to hold * the initial padding bits and length. If so, we will pad the * block, process it, and then continue padding into a second block. */ - if (_messageBlockIndex > 55) + if (_messageBlockIndex > 55) + { + _messageBlock[_messageBlockIndex++] = 0x80; + while (_messageBlockIndex < 64) { - _messageBlock[_messageBlockIndex++] = 0x80; - while (_messageBlockIndex < 64) - { - _messageBlock[_messageBlockIndex++] = 0; - } + _messageBlock[_messageBlockIndex++] = 0; + } - processMessageBlock(); + processMessageBlock(); - while (_messageBlockIndex < 56) - { - _messageBlock[_messageBlockIndex++] = 0; - } + while (_messageBlockIndex < 56) + { + _messageBlock[_messageBlockIndex++] = 0; } - else + } + else + { + _messageBlock[_messageBlockIndex++] = 0x80; + while (_messageBlockIndex < 56) { - _messageBlock[_messageBlockIndex++] = 0x80; - while (_messageBlockIndex < 56) - { - _messageBlock[_messageBlockIndex++] = 0; - } + _messageBlock[_messageBlockIndex++] = 0; } + } - /* + /* * Store the message length as the last 8 octets */ - _messageBlock[56] = (_length_high >> 24) & 0xFF; - _messageBlock[57] = (_length_high >> 16) & 0xFF; - _messageBlock[58] = (_length_high >> 8) & 0xFF; - _messageBlock[59] = (_length_high)&0xFF; - _messageBlock[60] = (_lengthLow >> 24) & 0xFF; - _messageBlock[61] = (_lengthLow >> 16) & 0xFF; - _messageBlock[62] = (_lengthLow >> 8) & 0xFF; - _messageBlock[63] = (_lengthLow)&0xFF; + _messageBlock[56] = (_length_high >> 24) & 0xFF; + _messageBlock[57] = (_length_high >> 16) & 0xFF; + _messageBlock[58] = (_length_high >> 8) & 0xFF; + _messageBlock[59] = (_length_high)&0xFF; + _messageBlock[60] = (_lengthLow >> 24) & 0xFF; + _messageBlock[61] = (_lengthLow >> 16) & 0xFF; + _messageBlock[62] = (_lengthLow >> 8) & 0xFF; + _messageBlock[63] = (_lengthLow)&0xFF; + + processMessageBlock(); +} + +struct sha1hash Sha1::hash() +{ + padmessage(); - processMessageBlock(); - } + struct sha1hash r; + int i = 0; - struct sha1hash Sha1::hash() - { - padmessage(); + r.bytes[i++] = (H[0] >> 24) & 0xFF; + r.bytes[i++] = (H[0] >> 16) & 0xFF; + r.bytes[i++] = (H[0] >> 8) & 0xFF; + r.bytes[i++] = (H[0]) & 0xFF; - struct sha1hash r; - int i = 0; + r.bytes[i++] = (H[1] >> 24) & 0xFF; + r.bytes[i++] = (H[1] >> 16) & 0xFF; + r.bytes[i++] = (H[1] >> 8) & 0xFF; + r.bytes[i++] = (H[1]) & 0xFF; - r.bytes[i++] = (H[0] >> 24) & 0xFF; - r.bytes[i++] = (H[0] >> 16) & 0xFF; - r.bytes[i++] = (H[0] >> 8) & 0xFF; - r.bytes[i++] = (H[0]) & 0xFF; + r.bytes[i++] = (H[2] >> 24) & 0xFF; + r.bytes[i++] = (H[2] >> 16) & 0xFF; + r.bytes[i++] = (H[2] >> 8) & 0xFF; + r.bytes[i++] = (H[2]) & 0xFF; - r.bytes[i++] = (H[1] >> 24) & 0xFF; - r.bytes[i++] = (H[1] >> 16) & 0xFF; - r.bytes[i++] = (H[1] >> 8) & 0xFF; - r.bytes[i++] = (H[1]) & 0xFF; + r.bytes[i++] = (H[3] >> 24) & 0xFF; + r.bytes[i++] = (H[3] >> 16) & 0xFF; + r.bytes[i++] = (H[3] >> 8) & 0xFF; + r.bytes[i++] = (H[3]) & 0xFF; - r.bytes[i++] = (H[2] >> 24) & 0xFF; - r.bytes[i++] = (H[2] >> 16) & 0xFF; - r.bytes[i++] = (H[2] >> 8) & 0xFF; - r.bytes[i++] = (H[2]) & 0xFF; + r.bytes[i++] = (H[4] >> 24) & 0xFF; + r.bytes[i++] = (H[4] >> 16) & 0xFF; + r.bytes[i++] = (H[4] >> 8) & 0xFF; + r.bytes[i++] = (H[4]) & 0xFF; - r.bytes[i++] = (H[3] >> 24) & 0xFF; - r.bytes[i++] = (H[3] >> 16) & 0xFF; - r.bytes[i++] = (H[3] >> 8) & 0xFF; - r.bytes[i++] = (H[3]) & 0xFF; + reset(); - r.bytes[i++] = (H[4] >> 24) & 0xFF; - r.bytes[i++] = (H[4] >> 16) & 0xFF; - r.bytes[i++] = (H[4] >> 8) & 0xFF; - r.bytes[i++] = (H[4]) & 0xFF; + return r; +} - reset(); - - return r; - } +struct sha1hash sha1(const char* text, size_t len) +{ + Sha1 x((const unsigned char*)(text), len); + return x.hash(); +} - struct sha1hash sha1(const char* text, size_t len) +uint32_t swapOrder32(uint32_t n) +{ + if (!isBigEndian) { - Sha1 x((const unsigned char*)(text), len); - return x.hash(); + return ((n >> 24) & 0x000000FF) | ((n >> 8) & 0x0000FF00) | ((n << 8) & 0x00FF0000) | + ((n << 24) & 0xFF000000); } - - uint32_t swapOrder32(uint32_t n) + else { - if (!isBigEndian) - { - return ((n >> 24) & 0x000000FF) | ((n >> 8) & 0x0000FF00) | ((n << 8) & 0x00FF0000) | - ((n << 24) & 0xFF000000); - } - else - { - return n; - } + return n; } +} - uint16_t swapOrder16(uint16_t n) +uint16_t swapOrder16(uint16_t n) +{ + if (!isBigEndian) { - if (!isBigEndian) - { - return ((n >> 8) & 0x00FF) | ((n << 8) & 0xFF00); - } - return n; + return ((n >> 8) & 0x00FF) | ((n << 8) & 0xFF00); } + return n; +} - /* Name string is a fully-qualified domain name */ - uuid_object NameSpace_DNS = {/* 6ba7b810-9dad-11d1-80b4-00c04fd430c8 */ - 0x6ba7b810, 0x9dad, 0x11d1, - 0x80, 0xb4, {0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}}; +/* Name string is a fully-qualified domain name */ +uuid_object NameSpace_DNS = {/* 6ba7b810-9dad-11d1-80b4-00c04fd430c8 */ + 0x6ba7b810, 0x9dad, 0x11d1, + 0x80, 0xb4, {0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}}; - uuid_object create_sha1_guid_from_name(const char* name, size_t namelen) - { - uuid_object uuid; +uuid_object create_sha1_guid_from_name(const char* name, size_t namelen) +{ + uuid_object uuid; - /*put name space ID in network byte order so it hashes the same + /*put name space ID in network byte order so it hashes the same no matter what endian machine we're on */ - // namespace DNS - uuid_object net_nsid = { - /* 6ba7b810-9dad-11d1-80b4-00c04fd430c8 */ - 0x6ba7b810, 0x9dad, 0x11d1, 0x80, 0xb4, {0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}}; - - net_nsid.time_low = swapOrder32(net_nsid.time_low); - net_nsid.time_mid = swapOrder16(net_nsid.time_mid); - net_nsid.time_hi_and_version = swapOrder16(net_nsid.time_hi_and_version); - - Sha1 c; - c.input((const uint8_t*)&net_nsid, sizeof(net_nsid)); - c.input((const uint8_t*)name, namelen); - auto hash = c.hash(); - - /* convert UUID to local byte order */ - memcpy(&uuid, hash.bytes, sizeof(uuid)); - uuid.time_low = swapOrder32(uuid.time_low); - uuid.time_mid = swapOrder16(uuid.time_mid); - uuid.time_hi_and_version = swapOrder16(uuid.time_hi_and_version); - - const auto v = 5; - /* put in the variant and version bits */ - uuid.time_hi_and_version &= 0x0FFF; - uuid.time_hi_and_version |= (v << 12); - uuid.clock_seq_hi_and_reserved &= 0x3F; - uuid.clock_seq_hi_and_reserved |= 0x80; - - return uuid; - } + // namespace DNS + uuid_object net_nsid = {/* 6ba7b810-9dad-11d1-80b4-00c04fd430c8 */ + 0x6ba7b810, 0x9dad, 0x11d1, 0x80, 0xb4, {0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}}; + + net_nsid.time_low = swapOrder32(net_nsid.time_low); + net_nsid.time_mid = swapOrder16(net_nsid.time_mid); + net_nsid.time_hi_and_version = swapOrder16(net_nsid.time_hi_and_version); + + Sha1 c; + c.input((const uint8_t*)&net_nsid, sizeof(net_nsid)); + c.input((const uint8_t*)name, namelen); + auto hash = c.hash(); + + /* convert UUID to local byte order */ + memcpy(&uuid, hash.bytes, sizeof(uuid)); + uuid.time_low = swapOrder32(uuid.time_low); + uuid.time_mid = swapOrder16(uuid.time_mid); + uuid.time_hi_and_version = swapOrder16(uuid.time_hi_and_version); + + const auto v = 5; + /* put in the variant and version bits */ + uuid.time_hi_and_version &= 0x0FFF; + uuid.time_hi_and_version |= (v << 12); + uuid.clock_seq_hi_and_reserved &= 0x3F; + uuid.clock_seq_hi_and_reserved |= 0x80; + + return uuid; +} } // namespace Crypto diff --git a/src/detail/sha1.h b/src/detail/sha1.h index 4f97e668..1d9218e1 100644 --- a/src/detail/sha1.h +++ b/src/detail/sha1.h @@ -6,23 +6,23 @@ namespace Crypto { - struct sha1hash - { - uint8_t bytes[20]; - }; +struct sha1hash +{ + uint8_t bytes[20]; +}; - struct sha1hash sha1(const char* text, size_t len); +struct sha1hash sha1(const char* text, size_t len); - typedef struct uuid_object_ - { - uint32_t time_low; - uint16_t time_mid; - uint16_t time_hi_and_version; - uint8_t clock_seq_hi_and_reserved; - uint8_t clock_seq_low; - uint8_t node[6]; - } uuid_object; +typedef struct uuid_object_ +{ + uint32_t time_low; + uint16_t time_mid; + uint16_t time_hi_and_version; + uint8_t clock_seq_hi_and_reserved; + uint8_t clock_seq_low; + uint8_t node[6]; +} uuid_object; - uuid_object create_sha1_guid_from_name(const char* name, size_t namelen); +uuid_object create_sha1_guid_from_name(const char* name, size_t namelen); } // namespace Crypto diff --git a/src/detail/vst3/categories.cpp b/src/detail/vst3/categories.cpp index 1c2bffc0..0fcf75d7 100644 --- a/src/detail/vst3/categories.cpp +++ b/src/detail/vst3/categories.cpp @@ -105,7 +105,7 @@ static const struct _translate {nullptr, nullptr} }; -// clang-format off +// clang-format on std::string clapCategoriesToVST3(const char* const* clap_categories) { @@ -131,8 +131,8 @@ std::string clapCategoriesToVST3(const char* const* clap_categories) { r2.push_back(i); } - } - + } + std::string result; for (auto& i : r2) { @@ -149,5 +149,4 @@ std::string clapCategoriesToVST3(const char* const* clap_categories) } result.pop_back(); return result; - } \ No newline at end of file diff --git a/src/detail/vst3/os/linux.cpp b/src/detail/vst3/os/linux.cpp index 9bada408..433dcac8 100644 --- a/src/detail/vst3/os/linux.cpp +++ b/src/detail/vst3/os/linux.cpp @@ -17,23 +17,23 @@ namespace os { - void log(const char* text) - { - fprintf(stderr, "%s\n", text); - } +void log(const char* text) +{ + fprintf(stderr, "%s\n", text); +} - class LinuxHelper - { - public: - void init(); - void terminate(); - void attach(IPlugObject* plugobject); - void detach(IPlugObject* plugobject); +class LinuxHelper +{ + public: + void init(); + void terminate(); + void attach(IPlugObject* plugobject); + void detach(IPlugObject* plugobject); - private: - void executeDefered(); - std::vector _plugs; - } gLinuxHelper; + private: + void executeDefered(); + std::vector _plugs; +} gLinuxHelper; #if 0 class WindowsHelper @@ -52,8 +52,8 @@ namespace os } gWindowsHelper; #endif - static Steinberg::ModuleInitializer createMessageWindow([] { gLinuxHelper.init(); }); - static Steinberg::ModuleTerminator dropMessageWindow([] { gLinuxHelper.terminate(); }); +static Steinberg::ModuleInitializer createMessageWindow([] { gLinuxHelper.init(); }); +static Steinberg::ModuleTerminator dropMessageWindow([] { gLinuxHelper.terminate(); }); #if 0 static char* getModuleNameA() @@ -79,40 +79,40 @@ namespace os } #endif - static std::string getModuleName() +static std::string getModuleName() +{ + Dl_info info; + if (dladdr((void*)getModuleName, &info)) { - Dl_info info; - if (dladdr((void*)getModuleName, &info)) - { - return info.dli_fname; - } - return nullptr; + return info.dli_fname; } + return nullptr; +} - std::string getParentFolderName() +std::string getParentFolderName() +{ + std::filesystem::path n = getModuleName(); + if (n.has_parent_path()) { - std::filesystem::path n = getModuleName(); - if (n.has_parent_path()) + auto p = n.parent_path(); + if (p.has_filename()) { - auto p = n.parent_path(); - if (p.has_filename()) - { - return p.filename().u8string(); - } + return p.filename().u8string(); } - - return std::string(); } - std::string getBinaryName() + return std::string(); +} + +std::string getBinaryName() +{ + std::filesystem::path n = getModuleName(); + if (n.has_filename()) { - std::filesystem::path n = getModuleName(); - if (n.has_filename()) - { - return n.stem().u8string(); - } - return std::string(); + return n.stem().u8string(); } + return std::string(); +} #if 0 LRESULT WindowsHelper::Wndproc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) @@ -155,49 +155,49 @@ namespace os } #endif - void LinuxHelper::init() - { - } +void LinuxHelper::init() +{ +} - void LinuxHelper::terminate() - { - } +void LinuxHelper::terminate() +{ +} - void LinuxHelper::executeDefered() - { - for (auto p : _plugs) - { - p->onIdle(); - } - } - void LinuxHelper::attach(IPlugObject* plugobject) +void LinuxHelper::executeDefered() +{ + for (auto p : _plugs) { - _plugs.push_back(plugobject); + p->onIdle(); } +} +void LinuxHelper::attach(IPlugObject* plugobject) +{ + _plugs.push_back(plugobject); +} - void LinuxHelper::detach(IPlugObject* plugobject) - { - _plugs.erase(std::remove(_plugs.begin(), _plugs.end(), plugobject), _plugs.end()); - } +void LinuxHelper::detach(IPlugObject* plugobject) +{ + _plugs.erase(std::remove(_plugs.begin(), _plugs.end(), plugobject), _plugs.end()); +} } // namespace os namespace os { - // [UI Thread] - void attach(IPlugObject* plugobject) - { - gLinuxHelper.attach(plugobject); - } +// [UI Thread] +void attach(IPlugObject* plugobject) +{ + gLinuxHelper.attach(plugobject); +} - // [UI Thread] - void detach(IPlugObject* plugobject) - { - gLinuxHelper.detach(plugobject); - } +// [UI Thread] +void detach(IPlugObject* plugobject) +{ + gLinuxHelper.detach(plugobject); +} - uint64_t getTickInMS() - { - return clock(); - } +uint64_t getTickInMS() +{ + return clock(); +} } // namespace os diff --git a/src/detail/vst3/os/macos.mm b/src/detail/vst3/os/macos.mm index d1a5e203..6b7b1792 100644 --- a/src/detail/vst3/os/macos.mm +++ b/src/detail/vst3/os/macos.mm @@ -25,80 +25,80 @@ namespace os { - void log(const char* text) - { - NSLog(@"%s", text); - } +void log(const char* text) +{ + NSLog(@"%s", text); +} - class MacOSHelper - { - public: - void init(); - void terminate(); - void attach(IPlugObject* plugobject); - void detach(IPlugObject* plugobject); - - private: - static void timerCallback(CFRunLoopTimerRef t, void* info); - void executeDefered(); - CFRunLoopTimerRef _timer = nullptr; - std::vector _plugs; - } gMacOSHelper; - - static Steinberg::ModuleInitializer createMessageWindow([] { gMacOSHelper.init(); }); - static Steinberg::ModuleTerminator dropMessageWindow([] { gMacOSHelper.terminate(); }); - - void MacOSHelper::init() - { - } +class MacOSHelper +{ + public: + void init(); + void terminate(); + void attach(IPlugObject* plugobject); + void detach(IPlugObject* plugobject); + + private: + static void timerCallback(CFRunLoopTimerRef t, void* info); + void executeDefered(); + CFRunLoopTimerRef _timer = nullptr; + std::vector _plugs; +} gMacOSHelper; + +static Steinberg::ModuleInitializer createMessageWindow([] { gMacOSHelper.init(); }); +static Steinberg::ModuleTerminator dropMessageWindow([] { gMacOSHelper.terminate(); }); + +void MacOSHelper::init() +{ +} - void MacOSHelper::terminate() - { - } +void MacOSHelper::terminate() +{ +} - void MacOSHelper::executeDefered() +void MacOSHelper::executeDefered() +{ + for (auto p : _plugs) { - for (auto p : _plugs) - { - p->onIdle(); - } + p->onIdle(); } +} - void MacOSHelper::timerCallback(CFRunLoopTimerRef t, void* info) - { - auto self = static_cast(info); - self->executeDefered(); - } +void MacOSHelper::timerCallback(CFRunLoopTimerRef t, void* info) +{ + auto self = static_cast(info); + self->executeDefered(); +} - static float kIntervall = 10.f; +static float kIntervall = 10.f; - void MacOSHelper::attach(IPlugObject* plugobject) +void MacOSHelper::attach(IPlugObject* plugobject) +{ + if (_plugs.empty()) { - if (_plugs.empty()) - { - CFRunLoopTimerContext context = {}; - context.info = this; - _timer = - CFRunLoopTimerCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent() + (kIntervall * 0.001f), - kIntervall * 0.001f, 0, 0, timerCallback, &context); - if (_timer) CFRunLoopAddTimer(CFRunLoopGetCurrent(), _timer, kCFRunLoopCommonModes); - } - _plugs.push_back(plugobject); + CFRunLoopTimerContext context = {}; + context.info = this; + _timer = + CFRunLoopTimerCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent() + (kIntervall * 0.001f), + kIntervall * 0.001f, 0, 0, timerCallback, &context); + if (_timer) CFRunLoopAddTimer(CFRunLoopGetCurrent(), _timer, kCFRunLoopCommonModes); } + _plugs.push_back(plugobject); +} - void MacOSHelper::detach(IPlugObject* plugobject) +void MacOSHelper::detach(IPlugObject* plugobject) +{ + _plugs.erase(std::remove(_plugs.begin(), _plugs.end(), plugobject), _plugs.end()); + if (_plugs.empty()) { - _plugs.erase(std::remove(_plugs.begin(), _plugs.end(), plugobject), _plugs.end()); - if (_plugs.empty()) + if (_timer) { - if (_timer) - { - CFRunLoopTimerInvalidate(_timer); - CFRelease(_timer); - } - _timer = nullptr; + CFRunLoopTimerInvalidate(_timer); + CFRelease(_timer); } + _timer = nullptr; } +} } @@ -115,49 +115,49 @@ - (void)fun namespace os { - // [UI Thread] - void attach(IPlugObject* plugobject) - { - gMacOSHelper.attach(plugobject); - } +// [UI Thread] +void attach(IPlugObject* plugobject) +{ + gMacOSHelper.attach(plugobject); +} - // [UI Thread] - void detach(IPlugObject* plugobject) - { - gMacOSHelper.detach(plugobject); - } +// [UI Thread] +void detach(IPlugObject* plugobject) +{ + gMacOSHelper.detach(plugobject); +} - uint64_t getTickInMS() - { - return (::clock() * 1000) / CLOCKS_PER_SEC; - } +uint64_t getTickInMS() +{ + return (::clock() * 1000) / CLOCKS_PER_SEC; +} - std::string getParentFolderName() +std::string getParentFolderName() +{ + NSString* identifier = + [[NSBundle bundleForClass:[clapwrapper_dummy_object_to_trick_the_os class]] bundlePath]; + fs::path n = [identifier UTF8String]; + if (n.has_parent_path()) { - NSString* identifier = - [[NSBundle bundleForClass:[clapwrapper_dummy_object_to_trick_the_os class]] bundlePath]; - fs::path n = [identifier UTF8String]; - if (n.has_parent_path()) + auto p = n.parent_path(); + if (p.has_filename()) { - auto p = n.parent_path(); - if (p.has_filename()) - { - return p.filename().u8string(); - } + return p.filename().u8string(); } - - return std::string(); } - std::string getBinaryName() - { - // this is useless - // NSString* identifier = [[NSBundle mainBundle] bundleIdentifier]; - - // this is needed: - NSString* identifier = - [[NSBundle bundleForClass:[clapwrapper_dummy_object_to_trick_the_os class]] bundlePath]; - fs::path k = [identifier UTF8String]; - return k.stem(); - } + return std::string(); +} + +std::string getBinaryName() +{ + // this is useless + // NSString* identifier = [[NSBundle mainBundle] bundleIdentifier]; + + // this is needed: + NSString* identifier = + [[NSBundle bundleForClass:[clapwrapper_dummy_object_to_trick_the_os class]] bundlePath]; + fs::path k = [identifier UTF8String]; + return k.stem(); +} } diff --git a/src/detail/vst3/os/osutil.h b/src/detail/vst3/os/osutil.h index 410457d3..c1d2572b 100644 --- a/src/detail/vst3/os/osutil.h +++ b/src/detail/vst3/os/osutil.h @@ -13,30 +13,30 @@ namespace os { - class IPlugObject +class IPlugObject +{ + public: + virtual void onIdle() = 0; + virtual ~IPlugObject() { - public: - virtual void onIdle() = 0; - virtual ~IPlugObject() - { - } - }; - void attach(IPlugObject* plugobject); - void detach(IPlugObject* plugobject); - uint64_t getTickInMS(); - std::string getParentFolderName(); - std::string getBinaryName(); + } +}; +void attach(IPlugObject* plugobject); +void detach(IPlugObject* plugobject); +uint64_t getTickInMS(); +std::string getParentFolderName(); +std::string getBinaryName(); - void log(const char* text); +void log(const char* text); - template - void log(const char* format_str, Args&&... args) - { - fmt::memory_buffer buf; - fmt::format_to(std::back_inserter(buf), format_str, args...); - buf.push_back(0); - log((const char*)buf.data()); - }; +template +void log(const char* format_str, Args&&... args) +{ + fmt::memory_buffer buf; + fmt::format_to(std::back_inserter(buf), format_str, args...); + buf.push_back(0); + log((const char*)buf.data()); +}; } // namespace os #ifndef CLAP_WRAPPER_LOGLEVEL @@ -61,33 +61,33 @@ namespace os namespace util { - template - class fixedqueue +template +class fixedqueue +{ + public: + inline void push(const T& val) { - public: - inline void push(const T& val) - { - push(&val); - } - inline void push(const T* val) - { - _elements[_head] = *val; - _head = (_head + 1) % Q; - } - inline bool pop(T& out) + push(&val); + } + inline void push(const T* val) + { + _elements[_head] = *val; + _head = (_head + 1) % Q; + } + inline bool pop(T& out) + { + if (_head == _tail) { - if (_head == _tail) - { - return false; - } - out = _elements[_tail]; - _tail = (_tail + 1) % Q; - return true; + return false; } + out = _elements[_tail]; + _tail = (_tail + 1) % Q; + return true; + } - private: - T _elements[Q] = {}; - std::atomic_uint32_t _head = 0u; - std::atomic_uint32_t _tail = 0u; - }; + private: + T _elements[Q] = {}; + std::atomic_uint32_t _head = 0u; + std::atomic_uint32_t _tail = 0u; +}; }; // namespace util \ No newline at end of file diff --git a/src/detail/vst3/os/windows.cpp b/src/detail/vst3/os/windows.cpp index ba29256b..fb196e8e 100644 --- a/src/detail/vst3/os/windows.cpp +++ b/src/detail/vst3/os/windows.cpp @@ -21,146 +21,146 @@ extern HINSTANCE ghInst; namespace os { - void log(const char* text) - { - OutputDebugStringA(text); - OutputDebugStringA("\n"); - } +void log(const char* text) +{ + OutputDebugStringA(text); + OutputDebugStringA("\n"); +} - class WindowsHelper - { - public: - void init(); - void terminate(); - void attach(IPlugObject* plugobject); - void detach(IPlugObject* plugobject); - - private: - void executeDefered(); - static LRESULT Wndproc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); - HWND _msgWin = 0; - UINT_PTR _timer = 0; - std::vector _plugs; - } gWindowsHelper; - - static Steinberg::ModuleInitializer createMessageWindow([] { gWindowsHelper.init(); }); - static Steinberg::ModuleTerminator dropMessageWindow([] { gWindowsHelper.terminate(); }); - - static char* getModuleNameA() +class WindowsHelper +{ + public: + void init(); + void terminate(); + void attach(IPlugObject* plugobject); + void detach(IPlugObject* plugobject); + + private: + void executeDefered(); + static LRESULT Wndproc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + HWND _msgWin = 0; + UINT_PTR _timer = 0; + std::vector _plugs; +} gWindowsHelper; + +static Steinberg::ModuleInitializer createMessageWindow([] { gWindowsHelper.init(); }); +static Steinberg::ModuleTerminator dropMessageWindow([] { gWindowsHelper.terminate(); }); + +static char* getModuleNameA() +{ + static char modulename[2048]; + HMODULE selfmodule; + if (GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)getModuleNameA, &selfmodule)) { - static char modulename[2048]; - HMODULE selfmodule; - if (GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)getModuleNameA, &selfmodule)) - { - auto size = GetModuleFileNameA(selfmodule, modulename, 2048); - } - return modulename; + auto size = GetModuleFileNameA(selfmodule, modulename, 2048); } + return modulename; +} - static TCHAR* getModuleName() +static TCHAR* getModuleName() +{ + static TCHAR modulename[2048]; + HMODULE selfmodule; + if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)getModuleName, &selfmodule)) { - static TCHAR modulename[2048]; - HMODULE selfmodule; - if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)getModuleName, &selfmodule)) - { - auto size = GetModuleFileName(selfmodule, modulename, 2048); - } - return modulename; + auto size = GetModuleFileName(selfmodule, modulename, 2048); } + return modulename; +} - std::string getParentFolderName() +std::string getParentFolderName() +{ + std::filesystem::path n = getModuleNameA(); + if (n.has_parent_path()) { - std::filesystem::path n = getModuleNameA(); - if (n.has_parent_path()) + auto p = n.parent_path(); + if (p.has_filename()) { - auto p = n.parent_path(); - if (p.has_filename()) - { - return p.filename().u8string(); - } + return p.filename().u8string(); } - - return std::string(); } - std::string getBinaryName() - { - std::filesystem::path n = getModuleNameA(); - if (n.has_filename()) - { - return n.stem().u8string(); - } - return std::string(); - } + return std::string(); +} - LRESULT WindowsHelper::Wndproc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +std::string getBinaryName() +{ + std::filesystem::path n = getModuleNameA(); + if (n.has_filename()) { - switch (msg) - { - case WM_USER + 1: - return 1; - break; - case WM_TIMER: - gWindowsHelper.executeDefered(); - return 1; - break; - default: - return ::DefWindowProc(hwnd, msg, wParam, lParam); - } + return n.stem().u8string(); } + return std::string(); +} - void WindowsHelper::init() +LRESULT WindowsHelper::Wndproc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) { - auto modulename = getModuleName(); - WNDCLASSEX wc; - memset(&wc, 0, sizeof(wc)); - wc.cbSize = sizeof(wc); - wc.hInstance = ghInst; - wc.lpfnWndProc = (WNDPROC)&Wndproc; - wc.lpszClassName = modulename; - auto a = RegisterClassEx(&wc); - - _msgWin = ::CreateWindowEx(0, modulename, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, 0, 0); - ::SetWindowLongW(_msgWin, GWLP_WNDPROC, (LONG_PTR)&Wndproc); - _timer = ::SetTimer(_msgWin, 0, 20, NULL); + case WM_USER + 1: + return 1; + break; + case WM_TIMER: + gWindowsHelper.executeDefered(); + return 1; + break; + default: + return ::DefWindowProc(hwnd, msg, wParam, lParam); } +} - void WindowsHelper::terminate() - { - ::KillTimer(_msgWin, _timer); - ::DestroyWindow(_msgWin); - ::UnregisterClass(getModuleName(), ghInst); - } +void WindowsHelper::init() +{ + auto modulename = getModuleName(); + WNDCLASSEX wc; + memset(&wc, 0, sizeof(wc)); + wc.cbSize = sizeof(wc); + wc.hInstance = ghInst; + wc.lpfnWndProc = (WNDPROC)&Wndproc; + wc.lpszClassName = modulename; + auto a = RegisterClassEx(&wc); + + _msgWin = ::CreateWindowEx(0, modulename, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, 0, 0); + ::SetWindowLongW(_msgWin, GWLP_WNDPROC, (LONG_PTR)&Wndproc); + _timer = ::SetTimer(_msgWin, 0, 20, NULL); +} + +void WindowsHelper::terminate() +{ + ::KillTimer(_msgWin, _timer); + ::DestroyWindow(_msgWin); + ::UnregisterClass(getModuleName(), ghInst); +} - void WindowsHelper::executeDefered() - { - for (auto&& p : _plugs) p->onIdle(); - } +void WindowsHelper::executeDefered() +{ + for (auto&& p : _plugs) p->onIdle(); +} - void WindowsHelper::attach(IPlugObject* plugobject) - { - _plugs.push_back(plugobject); - } +void WindowsHelper::attach(IPlugObject* plugobject) +{ + _plugs.push_back(plugobject); +} - void WindowsHelper::detach(IPlugObject* plugobject) - { - _plugs.erase(std::remove(_plugs.begin(), _plugs.end(), plugobject), _plugs.end()); - } +void WindowsHelper::detach(IPlugObject* plugobject) +{ + _plugs.erase(std::remove(_plugs.begin(), _plugs.end(), plugobject), _plugs.end()); +} - // [UI Thread] - void attach(IPlugObject* plugobject) - { - gWindowsHelper.attach(plugobject); - } +// [UI Thread] +void attach(IPlugObject* plugobject) +{ + gWindowsHelper.attach(plugobject); +} - // [UI Thread] - void detach(IPlugObject* plugobject) - { - gWindowsHelper.detach(plugobject); - } +// [UI Thread] +void detach(IPlugObject* plugobject) +{ + gWindowsHelper.detach(plugobject); +} - uint64_t getTickInMS() - { - return GetTickCount64(); - } +uint64_t getTickInMS() +{ + return GetTickCount64(); +} } // namespace os diff --git a/src/detail/vst3/process.cpp b/src/detail/vst3/process.cpp index 03d9f315..532285de 100644 --- a/src/detail/vst3/process.cpp +++ b/src/detail/vst3/process.cpp @@ -12,119 +12,121 @@ namespace Clap { - using namespace Steinberg; - - void ProcessAdapter::setupProcessing( - const clap_plugin_t* plugin, const clap_plugin_params_t* ext_params, Vst::BusList& audioinputs, - Vst::BusList& audiooutputs, uint32_t numSamples, size_t numEventInputs, size_t numEventOutputs, - Steinberg::Vst::ParameterContainer& params, Steinberg::Vst::IComponentHandler* componenthandler, - IAutomation* automation, bool enablePolyPressure, bool supportsTuningNoteExpression) - { - _plugin = plugin; - _ext_params = ext_params; - _audioinputs = &audioinputs; - _audiooutputs = &audiooutputs; +using namespace Steinberg; + +void ProcessAdapter::setupProcessing(const clap_plugin_t* plugin, const clap_plugin_params_t* ext_params, + Vst::BusList& audioinputs, Vst::BusList& audiooutputs, + uint32_t numSamples, size_t numEventInputs, size_t numEventOutputs, + Steinberg::Vst::ParameterContainer& params, + Steinberg::Vst::IComponentHandler* componenthandler, + IAutomation* automation, bool enablePolyPressure, + bool supportsTuningNoteExpression) +{ + _plugin = plugin; + _ext_params = ext_params; + _audioinputs = &audioinputs; + _audiooutputs = &audiooutputs; - parameters = ¶ms; - _componentHandler = componenthandler; - _automation = automation; + parameters = ¶ms; + _componentHandler = componenthandler; + _automation = automation; - if (numSamples > 0) - { - delete[] _silent_input; - _silent_input = new float[numSamples]; + if (numSamples > 0) + { + delete[] _silent_input; + _silent_input = new float[numSamples]; - delete[] _silent_output; - _silent_output = new float[numSamples]; - } + delete[] _silent_output; + _silent_output = new float[numSamples]; + } - auto numInputs = (uint32_t)_audioinputs->size(); - auto numOutputs = (uint32_t)_audiooutputs->size(); + auto numInputs = (uint32_t)_audioinputs->size(); + auto numOutputs = (uint32_t)_audiooutputs->size(); - _processData.audio_inputs_count = numInputs; - delete[] _input_ports; - _input_ports = nullptr; + _processData.audio_inputs_count = numInputs; + delete[] _input_ports; + _input_ports = nullptr; - if (numInputs > 0) + if (numInputs > 0) + { + _input_ports = new clap_audio_buffer_t[numInputs]; + for (auto i = 0U; i < numInputs; ++i) { - _input_ports = new clap_audio_buffer_t[numInputs]; - for (auto i = 0U; i < numInputs; ++i) + clap_audio_buffer_t& bus = _input_ports[i]; + Vst::BusInfo info; + if (_audioinputs->at(i)->getInfo(info)) { - clap_audio_buffer_t& bus = _input_ports[i]; - Vst::BusInfo info; - if (_audioinputs->at(i)->getInfo(info)) - { - bus.channel_count = info.channelCount; - bus.constant_mask = 0; - bus.latency = 0; - bus.data64 = 0; - bus.data32 = 0; - } + bus.channel_count = info.channelCount; + bus.constant_mask = 0; + bus.latency = 0; + bus.data64 = 0; + bus.data32 = 0; } - _processData.audio_inputs = _input_ports; - } - else - { - _processData.audio_inputs = nullptr; } + _processData.audio_inputs = _input_ports; + } + else + { + _processData.audio_inputs = nullptr; + } - _processData.audio_outputs_count = numOutputs; - delete[] _output_ports; - _output_ports = nullptr; + _processData.audio_outputs_count = numOutputs; + delete[] _output_ports; + _output_ports = nullptr; - if (numOutputs > 0) + if (numOutputs > 0) + { + _output_ports = new clap_audio_buffer_t[numOutputs]; + for (auto i = 0U; i < numOutputs; ++i) { - _output_ports = new clap_audio_buffer_t[numOutputs]; - for (auto i = 0U; i < numOutputs; ++i) + clap_audio_buffer_t& bus = _output_ports[i]; + Vst::BusInfo info; + if (_audiooutputs->at(i)->getInfo(info)) { - clap_audio_buffer_t& bus = _output_ports[i]; - Vst::BusInfo info; - if (_audiooutputs->at(i)->getInfo(info)) - { - bus.channel_count = info.channelCount; - bus.constant_mask = 0; - bus.latency = 0; - bus.data64 = 0; - bus.data32 = 0; - } + bus.channel_count = info.channelCount; + bus.constant_mask = 0; + bus.latency = 0; + bus.data64 = 0; + bus.data32 = 0; } - _processData.audio_outputs = _output_ports; - } - else - { - _processData.audio_outputs = nullptr; } + _processData.audio_outputs = _output_ports; + } + else + { + _processData.audio_outputs = nullptr; + } - _processData.in_events = &_in_events; - _processData.out_events = &_out_events; + _processData.in_events = &_in_events; + _processData.out_events = &_out_events; - _processData.transport = &_transport; + _processData.transport = &_transport; - _in_events.ctx = this; - _in_events.size = input_events_size; - _in_events.get = input_events_get; + _in_events.ctx = this; + _in_events.size = input_events_size; + _in_events.get = input_events_get; - _out_events.ctx = this; - _out_events.try_push = output_events_try_push; + _out_events.ctx = this; + _out_events.try_push = output_events_try_push; - _events.clear(); - _events.reserve(256); - _eventindices.clear(); - _eventindices.reserve(_events.capacity()); + _events.clear(); + _events.reserve(256); + _eventindices.clear(); + _eventindices.reserve(_events.capacity()); - _out_events.ctx = this; + _out_events.ctx = this; - _gesturedParameters.reserve(32); + _gesturedParameters.reserve(32); - _activeNotes.reserve(64); + _activeNotes.reserve(64); - _supportsPolyPressure = enablePolyPressure; - _supportsTuningNoteExpression = supportsTuningNoteExpression; - } + _supportsPolyPressure = enablePolyPressure; + _supportsTuningNoteExpression = supportsTuningNoteExpression; +} - void ProcessAdapter::activateAudioBus(Steinberg::Vst::BusDirection dir, int32 index, TBool state) - { - /* +void ProcessAdapter::activateAudioBus(Steinberg::Vst::BusDirection dir, int32 index, TBool state) +{ + /* if (dir == Vst::kInput) { auto& map = _bogus_buffers->_in_channelmap[index]; @@ -142,629 +144,628 @@ namespace Clap _bogus_buffers->_active_mask_out &= ~map._bitmap; } */ - } +} - inline clap_beattime doubleToBeatTime(double t) - { - return std::round(t * CLAP_BEATTIME_FACTOR); - } +inline clap_beattime doubleToBeatTime(double t) +{ + return std::round(t * CLAP_BEATTIME_FACTOR); +} - inline clap_sectime doubleToSecTime(double t) - { - return round(t * CLAP_SECTIME_FACTOR); - } +inline clap_sectime doubleToSecTime(double t) +{ + return round(t * CLAP_SECTIME_FACTOR); +} - void ProcessAdapter::flush() +void ProcessAdapter::flush() +{ + // minimal processing if _ext_params is existent + if (_ext_params) { - // minimal processing if _ext_params is existent - if (_ext_params) - { - _events.clear(); - _eventindices.clear(); + _events.clear(); + _eventindices.clear(); - // sortEventIndices(); call only if there would be any input event - _ext_params->flush(_plugin, _processData.in_events, _processData.out_events); - } + // sortEventIndices(); call only if there would be any input event + _ext_params->flush(_plugin, _processData.in_events, _processData.out_events); } +} - // this converts the ProcessContext data from VST to CLAP - void ProcessAdapter::process(Steinberg::Vst::ProcessData& data) - { - // remember the ProcessData pointer during process - _vstdata = &data; +// this converts the ProcessContext data from VST to CLAP +void ProcessAdapter::process(Steinberg::Vst::ProcessData& data) +{ + // remember the ProcessData pointer during process + _vstdata = &data; - /// convert timing - _transport.header = {sizeof(_transport), 0, CLAP_CORE_EVENT_SPACE_ID, CLAP_EVENT_TRANSPORT, 0}; + /// convert timing + _transport.header = {sizeof(_transport), 0, CLAP_CORE_EVENT_SPACE_ID, CLAP_EVENT_TRANSPORT, 0}; - _transport.flags = 0; - if (_vstdata->processContext) + _transport.flags = 0; + if (_vstdata->processContext) + { + // converting the flags + _transport.flags |= + 0 + // kPlaying = 1 << 1, ///< currently playing + | ((_vstdata->processContext->state & Vst::ProcessContext::kPlaying) ? CLAP_TRANSPORT_IS_PLAYING + : 0) + // kRecording = 1 << 3, ///< currently recording + | ((_vstdata->processContext->state & Vst::ProcessContext::kRecording) + ? CLAP_TRANSPORT_IS_RECORDING + : 0) + // kCycleActive = 1 << 2, ///< cycle is active + | ((_vstdata->processContext->state & Vst::ProcessContext::kCycleActive) + ? CLAP_TRANSPORT_IS_LOOP_ACTIVE + : 0) + // kTempoValid = 1 << 10, ///< tempo contains valid information + | + ((_vstdata->processContext->state & Vst::ProcessContext::kTempoValid) ? CLAP_TRANSPORT_HAS_TEMPO + : 0) | + ((_vstdata->processContext->state & Vst::ProcessContext::kBarPositionValid) + ? CLAP_TRANSPORT_HAS_BEATS_TIMELINE + : 0) | + ((_vstdata->processContext->state & Vst::ProcessContext::kTimeSigValid) + ? CLAP_TRANSPORT_HAS_TIME_SIGNATURE + : 0) + + // the rest of the flags has no meaning to CLAP + // kSystemTimeValid = 1 << 8, ///< systemTime contains valid information + // kContTimeValid = 1 << 17, ///< continousTimeSamples contains valid information + // + // kProjectTimeMusicValid = 1 << 9,///< projectTimeMusic contains valid information + // kBarPositionValid = 1 << 11, ///< barPositionMusic contains valid information + // kCycleValid = 1 << 12, ///< cycleStartMusic and barPositionMusic contain valid information + // + // kClockValid = 1 << 15 ///< samplesToNextClock valid + // kTimeSigValid = 1 << 13, ///< timeSigNumerator and timeSigDenominator contain valid information + // kChordValid = 1 << 18, ///< chord contains valid information + // + // kSmpteValid = 1 << 14, ///< smpteOffset and frameRate contain valid information + + ; + + _transport.song_pos_beats = doubleToBeatTime(_vstdata->processContext->projectTimeMusic); + _transport.song_pos_seconds = 0; + + _transport.tempo = _vstdata->processContext->tempo; + _transport.tempo_inc = 0; + + _transport.loop_start_beats = doubleToBeatTime(_vstdata->processContext->cycleStartMusic); + _transport.loop_end_beats = doubleToBeatTime(_vstdata->processContext->cycleEndMusic); + _transport.loop_start_seconds = 0; + _transport.loop_end_seconds = 0; + + _transport.bar_start = 0; + _transport.bar_number = 0; + + if ((_vstdata->processContext->state & Vst::ProcessContext::kTimeSigValid)) { - // converting the flags - _transport.flags |= 0 - // kPlaying = 1 << 1, ///< currently playing - | ((_vstdata->processContext->state & Vst::ProcessContext::kPlaying) - ? CLAP_TRANSPORT_IS_PLAYING - : 0) - // kRecording = 1 << 3, ///< currently recording - | ((_vstdata->processContext->state & Vst::ProcessContext::kRecording) - ? CLAP_TRANSPORT_IS_RECORDING - : 0) - // kCycleActive = 1 << 2, ///< cycle is active - | ((_vstdata->processContext->state & Vst::ProcessContext::kCycleActive) - ? CLAP_TRANSPORT_IS_LOOP_ACTIVE - : 0) - // kTempoValid = 1 << 10, ///< tempo contains valid information - | ((_vstdata->processContext->state & Vst::ProcessContext::kTempoValid) - ? CLAP_TRANSPORT_HAS_TEMPO - : 0) | - ((_vstdata->processContext->state & Vst::ProcessContext::kBarPositionValid) - ? CLAP_TRANSPORT_HAS_BEATS_TIMELINE - : 0) | - ((_vstdata->processContext->state & Vst::ProcessContext::kTimeSigValid) - ? CLAP_TRANSPORT_HAS_TIME_SIGNATURE - : 0) - - // the rest of the flags has no meaning to CLAP - // kSystemTimeValid = 1 << 8, ///< systemTime contains valid information - // kContTimeValid = 1 << 17, ///< continousTimeSamples contains valid information - // - // kProjectTimeMusicValid = 1 << 9,///< projectTimeMusic contains valid information - // kBarPositionValid = 1 << 11, ///< barPositionMusic contains valid information - // kCycleValid = 1 << 12, ///< cycleStartMusic and barPositionMusic contain valid information - // - // kClockValid = 1 << 15 ///< samplesToNextClock valid - // kTimeSigValid = 1 << 13, ///< timeSigNumerator and timeSigDenominator contain valid information - // kChordValid = 1 << 18, ///< chord contains valid information - // - // kSmpteValid = 1 << 14, ///< smpteOffset and frameRate contain valid information - - ; - - _transport.song_pos_beats = doubleToBeatTime(_vstdata->processContext->projectTimeMusic); - _transport.song_pos_seconds = 0; - - _transport.tempo = _vstdata->processContext->tempo; - _transport.tempo_inc = 0; - - _transport.loop_start_beats = doubleToBeatTime(_vstdata->processContext->cycleStartMusic); - _transport.loop_end_beats = doubleToBeatTime(_vstdata->processContext->cycleEndMusic); - _transport.loop_start_seconds = 0; - _transport.loop_end_seconds = 0; - - _transport.bar_start = 0; - _transport.bar_number = 0; - - if ((_vstdata->processContext->state & Vst::ProcessContext::kTimeSigValid)) - { - _transport.tsig_num = _vstdata->processContext->timeSigNumerator; - _transport.tsig_denom = _vstdata->processContext->timeSigDenominator; - } - else - { - _transport.tsig_num = 4; - _transport.tsig_denom = 4; - } - - _transport.bar_number = _vstdata->processContext->barPositionMusic; - _processData.steady_time = _vstdata->processContext->projectTimeSamples; + _transport.tsig_num = _vstdata->processContext->timeSigNumerator; + _transport.tsig_denom = _vstdata->processContext->timeSigDenominator; + } + else + { + _transport.tsig_num = 4; + _transport.tsig_denom = 4; } - // setting up transport - _processData.frames_count = _vstdata->numSamples; + _transport.bar_number = _vstdata->processContext->barPositionMusic; + _processData.steady_time = _vstdata->processContext->projectTimeSamples; + } - // always clear - _events.clear(); - _eventindices.clear(); + // setting up transport + _processData.frames_count = _vstdata->numSamples; - processInputEvents(_vstdata->inputEvents); + // always clear + _events.clear(); + _eventindices.clear(); - if (_vstdata->inputParameterChanges) + processInputEvents(_vstdata->inputEvents); + + if (_vstdata->inputParameterChanges) + { + auto numPevent = _vstdata->inputParameterChanges->getParameterCount(); + for (decltype(numPevent) i = 0; i < numPevent; ++i) { - auto numPevent = _vstdata->inputParameterChanges->getParameterCount(); - for (decltype(numPevent) i = 0; i < numPevent; ++i) - { - auto k = _vstdata->inputParameterChanges->getParameterData(i); + auto k = _vstdata->inputParameterChanges->getParameterData(i); - // get the Vst3Parameter - auto paramid = k->getParameterId(); + // get the Vst3Parameter + auto paramid = k->getParameterId(); - // if a parameter is currently edited by a user, we are not allowed to send this back to the CLAP. - // this is a fundamental difference between VST3 and CLAP - if (std::find(_gesturedParameters.begin(), _gesturedParameters.end(), paramid) != - _gesturedParameters.end()) - { - continue; - } + // if a parameter is currently edited by a user, we are not allowed to send this back to the CLAP. + // this is a fundamental difference between VST3 and CLAP + if (std::find(_gesturedParameters.begin(), _gesturedParameters.end(), paramid) != + _gesturedParameters.end()) + { + continue; + } - auto param = (Vst3Parameter*)parameters->getParameter(paramid); - if (param) + auto param = (Vst3Parameter*)parameters->getParameter(paramid); + if (param) + { + if (param->isMidi) { - if (param->isMidi) - { - auto nums = k->getPointCount(); + auto nums = k->getPointCount(); - Vst::ParamValue value; - int32 offset; - if (k->getPoint(nums - 1, offset, value) == kResultOk) + Vst::ParamValue value; + int32 offset; + if (k->getPoint(nums - 1, offset, value) == kResultOk) + { + // create MIDI event + clap_multi_event_t n; + n.param.header.type = CLAP_EVENT_MIDI; + n.param.header.flags = 0; + n.param.header.space_id = CLAP_CORE_EVENT_SPACE_ID; + n.param.header.time = offset; + n.param.header.size = sizeof(clap_event_midi_t); + n.midi.port_index = 0; + + switch (param->controller) { - // create MIDI event - clap_multi_event_t n; - n.param.header.type = CLAP_EVENT_MIDI; - n.param.header.flags = 0; - n.param.header.space_id = CLAP_CORE_EVENT_SPACE_ID; - n.param.header.time = offset; - n.param.header.size = sizeof(clap_event_midi_t); - n.midi.port_index = 0; - - switch (param->controller) - { - case Vst::ControllerNumbers::kAfterTouch: - n.midi.data[0] = 0xD0 | param->channel; - n.midi.data[1] = param->asClapValue(value); - n.midi.data[2] = 0; - break; - case Vst::ControllerNumbers::kPitchBend: - { - auto val = (uint16_t)param->asClapValue(value); - n.midi.data[0] = 0xE0 | param->channel; // $Ec - n.midi.data[1] = (val & 0x7F); // LSB - n.midi.data[2] = (val >> 7) & 0x7F; // MSB - } + case Vst::ControllerNumbers::kAfterTouch: + n.midi.data[0] = 0xD0 | param->channel; + n.midi.data[1] = param->asClapValue(value); + n.midi.data[2] = 0; break; - default: - n.midi.data[0] = 0xB0 | param->channel; - n.midi.data[1] = param->controller; - n.midi.data[2] = param->asClapValue(value); - break; + case Vst::ControllerNumbers::kPitchBend: + { + auto val = (uint16_t)param->asClapValue(value); + n.midi.data[0] = 0xE0 | param->channel; // $Ec + n.midi.data[1] = (val & 0x7F); // LSB + n.midi.data[2] = (val >> 7) & 0x7F; // MSB } - - _eventindices.push_back(_events.size()); - _events.push_back(n); + break; + default: + n.midi.data[0] = 0xB0 | param->channel; + n.midi.data[1] = param->controller; + n.midi.data[2] = param->asClapValue(value); + break; } + + _eventindices.push_back(_events.size()); + _events.push_back(n); } - else - { - auto nums = k->getPointCount(); + } + else + { + auto nums = k->getPointCount(); - Vst::ParamValue value; - int32 offset; - if (k->getPoint(nums - 1, offset, value) == kResultOk) - { - clap_multi_event_t n; - n.param.header.type = CLAP_EVENT_PARAM_VALUE; - n.param.header.flags = 0; - n.param.header.space_id = CLAP_CORE_EVENT_SPACE_ID; - n.param.header.time = offset; - n.param.header.size = sizeof(clap_event_param_value); - n.param.param_id = param->id; - n.param.cookie = param->cookie; - - // nothing note specific - n.param.note_id = -1; // always global - n.param.port_index = -1; - n.param.channel = -1; - n.param.key = -1; - - n.param.value = param->asClapValue(value); - _eventindices.push_back(_events.size()); - _events.push_back(n); - } + Vst::ParamValue value; + int32 offset; + if (k->getPoint(nums - 1, offset, value) == kResultOk) + { + clap_multi_event_t n; + n.param.header.type = CLAP_EVENT_PARAM_VALUE; + n.param.header.flags = 0; + n.param.header.space_id = CLAP_CORE_EVENT_SPACE_ID; + n.param.header.time = offset; + n.param.header.size = sizeof(clap_event_param_value); + n.param.param_id = param->id; + n.param.cookie = param->cookie; + + // nothing note specific + n.param.note_id = -1; // always global + n.param.port_index = -1; + n.param.channel = -1; + n.param.key = -1; + + n.param.value = param->asClapValue(value); + _eventindices.push_back(_events.size()); + _events.push_back(n); } } } } + } - sortEventIndices(); + sortEventIndices(); - bool doProcess = true; + bool doProcess = true; - if (_vstdata->numSamples > 0) + if (_vstdata->numSamples > 0) + { + // setting the buffers + auto inbusses = _audioinputs->size(); + for (auto i = 0U; i < inbusses; ++i) { - // setting the buffers - auto inbusses = _audioinputs->size(); - for (auto i = 0U; i < inbusses; ++i) - { - if (_vstdata->inputs[i].numChannels > 0) - _input_ports[i].data32 = _vstdata->inputs[i].channelBuffers32; - else - doProcess = false; - } + if (_vstdata->inputs[i].numChannels > 0) + _input_ports[i].data32 = _vstdata->inputs[i].channelBuffers32; + else + doProcess = false; + } - auto outbusses = _audiooutputs->size(); - for (auto i = 0U; i < outbusses; ++i) - { - if (_vstdata->outputs[i].numChannels > 0) - _output_ports[i].data32 = _vstdata->outputs[i].channelBuffers32; - else - doProcess = false; - } - if (doProcess) - _plugin->process(_plugin, &_processData); + auto outbusses = _audiooutputs->size(); + for (auto i = 0U; i < outbusses; ++i) + { + if (_vstdata->outputs[i].numChannels > 0) + _output_ports[i].data32 = _vstdata->outputs[i].channelBuffers32; else - { - if (_ext_params) - { - _ext_params->flush(_plugin, _processData.in_events, _processData.out_events); - } - } + doProcess = false; } + if (doProcess) + _plugin->process(_plugin, &_processData); else { if (_ext_params) { _ext_params->flush(_plugin, _processData.in_events, _processData.out_events); } - else - { - // something was now very very wrong here.. - } } - - processOutputParams(data); - - _vstdata = nullptr; - } - - void ProcessAdapter::processOutputParams(Steinberg::Vst::ProcessData& data) - { - } - - uint32_t ProcessAdapter::input_events_size(const struct clap_input_events* list) - { - auto self = static_cast(list->ctx); - return (uint32_t)self->_events.size(); - // return self->_vstdata->inputEvents->getEventCount(); } - - // returns the pointer to an event in the list. The index accessed is not the position in the event list itself - // since all events indices were sorted by timestamp - const clap_event_header_t* ProcessAdapter::input_events_get(const struct clap_input_events* list, - uint32_t index) + else { - auto self = static_cast(list->ctx); - if (self->_events.size() > index) + if (_ext_params) { - // we can safely return the note.header also for other event types - // since they are at the same memory address - auto realindex = self->_eventindices[index]; - return &(self->_events[realindex].header); + _ext_params->flush(_plugin, _processData.in_events, _processData.out_events); + } + else + { + // something was now very very wrong here.. } - return nullptr; } - bool ProcessAdapter::output_events_try_push(const struct clap_output_events* list, - const clap_event_header_t* event) - { - auto self = static_cast(list->ctx); - // mainly used for CLAP_EVENT_NOTE_CHOKE and CLAP_EVENT_NOTE_END - // but also for parameter changes - return self->enqueueOutputEvent(event); - } + processOutputParams(data); + + _vstdata = nullptr; +} + +void ProcessAdapter::processOutputParams(Steinberg::Vst::ProcessData& data) +{ +} - void ProcessAdapter::sortEventIndices() +uint32_t ProcessAdapter::input_events_size(const struct clap_input_events* list) +{ + auto self = static_cast(list->ctx); + return (uint32_t)self->_events.size(); + // return self->_vstdata->inputEvents->getEventCount(); +} + +// returns the pointer to an event in the list. The index accessed is not the position in the event list itself +// since all events indices were sorted by timestamp +const clap_event_header_t* ProcessAdapter::input_events_get(const struct clap_input_events* list, + uint32_t index) +{ + auto self = static_cast(list->ctx); + if (self->_events.size() > index) { - // just sorting the index - std::sort(_eventindices.begin(), _eventindices.end(), - [&](size_t const& a, size_t const& b) - { return _events[a].header.time < _events[b].header.time; }); + // we can safely return the note.header also for other event types + // since they are at the same memory address + auto realindex = self->_eventindices[index]; + return &(self->_events[realindex].header); } + return nullptr; +} + +bool ProcessAdapter::output_events_try_push(const struct clap_output_events* list, + const clap_event_header_t* event) +{ + auto self = static_cast(list->ctx); + // mainly used for CLAP_EVENT_NOTE_CHOKE and CLAP_EVENT_NOTE_END + // but also for parameter changes + return self->enqueueOutputEvent(event); +} + +void ProcessAdapter::sortEventIndices() +{ + // just sorting the index + std::sort(_eventindices.begin(), _eventindices.end(), + [&](size_t const& a, size_t const& b) + { return _events[a].header.time < _events[b].header.time; }); +} - void ProcessAdapter::processInputEvents(Steinberg::Vst::IEventList* eventlist) +void ProcessAdapter::processInputEvents(Steinberg::Vst::IEventList* eventlist) +{ + if (eventlist) { - if (eventlist) + Vst::Event vstevent; + auto numev = eventlist->getEventCount(); + for (decltype(numev) i = 0; i < numev; ++i) { - Vst::Event vstevent; - auto numev = eventlist->getEventCount(); - for (decltype(numev) i = 0; i < numev; ++i) + if (eventlist->getEvent(i, vstevent) == kResultOk) { - if (eventlist->getEvent(i, vstevent) == kResultOk) + if (vstevent.type == Vst::Event::kNoteOnEvent) { - if (vstevent.type == Vst::Event::kNoteOnEvent) + clap_multi_event_t n; + n.note.header.type = CLAP_EVENT_NOTE_ON; + n.note.header.flags = (vstevent.flags & Vst::Event::kIsLive) ? CLAP_EVENT_IS_LIVE : 0; + n.note.header.space_id = CLAP_CORE_EVENT_SPACE_ID; + n.note.header.time = vstevent.sampleOffset; + n.note.header.size = sizeof(clap_event_note); + n.note.channel = vstevent.noteOn.channel; + n.note.note_id = vstevent.noteOn.noteId; + n.note.port_index = 0; + n.note.velocity = vstevent.noteOn.velocity; + n.note.key = vstevent.noteOn.pitch; + _eventindices.push_back(_events.size()); + _events.push_back(n); + addToActiveNotes(&n.note); + + // CLAP doesn't support note-on retuning but does support note expressions so + // convert but only if your target clap supports note expressions + if (_supportsTuningNoteExpression && vstevent.noteOn.tuning != 0) { clap_multi_event_t n; - n.note.header.type = CLAP_EVENT_NOTE_ON; - n.note.header.flags = (vstevent.flags & Vst::Event::kIsLive) ? CLAP_EVENT_IS_LIVE : 0; - n.note.header.space_id = CLAP_CORE_EVENT_SPACE_ID; - n.note.header.time = vstevent.sampleOffset; - n.note.header.size = sizeof(clap_event_note); - n.note.channel = vstevent.noteOn.channel; - n.note.note_id = vstevent.noteOn.noteId; - n.note.port_index = 0; - n.note.velocity = vstevent.noteOn.velocity; - n.note.key = vstevent.noteOn.pitch; + n.noteexpression.header.type = CLAP_EVENT_NOTE_EXPRESSION; + n.noteexpression.header.flags = + (vstevent.flags & Vst::Event::kIsLive) ? CLAP_EVENT_IS_LIVE : 0; + n.noteexpression.header.space_id = CLAP_CORE_EVENT_SPACE_ID; + n.noteexpression.header.time = vstevent.sampleOffset; + n.noteexpression.header.size = sizeof(clap_event_note_expression); + n.noteexpression.note_id = vstevent.noteExpressionValue.noteId; + n.noteexpression.port_index = 0; + n.noteexpression.key = vstevent.noteOn.pitch; + n.noteexpression.channel = vstevent.noteOn.channel; + n.noteexpression.note_id = vstevent.noteOn.noteId; + n.noteexpression.value = vstevent.noteExpressionValue.value; + + // VST3 Tuning is float in cents. We are in semitones. So + n.noteexpression.value = vstevent.noteOn.tuning * 0.01; + n.noteexpression.expression_id = CLAP_NOTE_EXPRESSION_TUNING; _eventindices.push_back(_events.size()); _events.push_back(n); - addToActiveNotes(&n.note); - - // CLAP doesn't support note-on retuning but does support note expressions so - // convert but only if your target clap supports note expressions - if (_supportsTuningNoteExpression && vstevent.noteOn.tuning != 0) - { - clap_multi_event_t n; - n.noteexpression.header.type = CLAP_EVENT_NOTE_EXPRESSION; - n.noteexpression.header.flags = - (vstevent.flags & Vst::Event::kIsLive) ? CLAP_EVENT_IS_LIVE : 0; - n.noteexpression.header.space_id = CLAP_CORE_EVENT_SPACE_ID; - n.noteexpression.header.time = vstevent.sampleOffset; - n.noteexpression.header.size = sizeof(clap_event_note_expression); - n.noteexpression.note_id = vstevent.noteExpressionValue.noteId; - n.noteexpression.port_index = 0; - n.noteexpression.key = vstevent.noteOn.pitch; - n.noteexpression.channel = vstevent.noteOn.channel; - n.noteexpression.note_id = vstevent.noteOn.noteId; - n.noteexpression.value = vstevent.noteExpressionValue.value; - - // VST3 Tuning is float in cents. We are in semitones. So - n.noteexpression.value = vstevent.noteOn.tuning * 0.01; - n.noteexpression.expression_id = CLAP_NOTE_EXPRESSION_TUNING; - _eventindices.push_back(_events.size()); - _events.push_back(n); - } } - if (vstevent.type == Vst::Event::kNoteOffEvent) + } + if (vstevent.type == Vst::Event::kNoteOffEvent) + { + clap_multi_event_t n; + n.note.header.type = CLAP_EVENT_NOTE_OFF; + n.note.header.flags = (vstevent.flags & Vst::Event::kIsLive) ? CLAP_EVENT_IS_LIVE : 0; + n.note.header.space_id = CLAP_CORE_EVENT_SPACE_ID; + n.note.header.time = vstevent.sampleOffset; + n.note.header.size = sizeof(clap_event_note); + n.note.channel = vstevent.noteOff.channel; + n.note.note_id = vstevent.noteOff.noteId; + n.note.port_index = 0; + n.note.velocity = vstevent.noteOff.velocity; + n.note.key = vstevent.noteOff.pitch; + _eventindices.push_back(_events.size()); + _events.push_back(n); + } + if (vstevent.type == Vst::Event::kDataEvent) + { + clap_multi_event_t n; + if (vstevent.data.type == Vst::DataEvent::DataTypes::kMidiSysEx) { - clap_multi_event_t n; - n.note.header.type = CLAP_EVENT_NOTE_OFF; - n.note.header.flags = (vstevent.flags & Vst::Event::kIsLive) ? CLAP_EVENT_IS_LIVE : 0; - n.note.header.space_id = CLAP_CORE_EVENT_SPACE_ID; - n.note.header.time = vstevent.sampleOffset; - n.note.header.size = sizeof(clap_event_note); - n.note.channel = vstevent.noteOff.channel; - n.note.note_id = vstevent.noteOff.noteId; - n.note.port_index = 0; - n.note.velocity = vstevent.noteOff.velocity; - n.note.key = vstevent.noteOff.pitch; + n.sysex.buffer = vstevent.data.bytes; + n.sysex.size = vstevent.data.size; + n.sysex.port_index = 0; + n.sysex.header.type = CLAP_EVENT_MIDI_SYSEX; + n.sysex.header.flags = vstevent.flags & Vst::Event::kIsLive ? CLAP_EVENT_IS_LIVE : 0; + n.sysex.header.space_id = CLAP_CORE_EVENT_SPACE_ID; + n.sysex.header.time = vstevent.sampleOffset; + n.sysex.header.size = sizeof(n.sysex); _eventindices.push_back(_events.size()); _events.push_back(n); } - if (vstevent.type == Vst::Event::kDataEvent) + else { - clap_multi_event_t n; - if (vstevent.data.type == Vst::DataEvent::DataTypes::kMidiSysEx) - { - n.sysex.buffer = vstevent.data.bytes; - n.sysex.size = vstevent.data.size; - n.sysex.port_index = 0; - n.sysex.header.type = CLAP_EVENT_MIDI_SYSEX; - n.sysex.header.flags = vstevent.flags & Vst::Event::kIsLive ? CLAP_EVENT_IS_LIVE : 0; - n.sysex.header.space_id = CLAP_CORE_EVENT_SPACE_ID; - n.sysex.header.time = vstevent.sampleOffset; - n.sysex.header.size = sizeof(n.sysex); - _eventindices.push_back(_events.size()); - _events.push_back(n); - } - else - { - // there are no other event types yet - } + // there are no other event types yet } - if (_supportsPolyPressure && vstevent.type == Vst::Event::kPolyPressureEvent) + } + if (_supportsPolyPressure && vstevent.type == Vst::Event::kPolyPressureEvent) + { + clap_multi_event_t n; + n.noteexpression.header.type = CLAP_EVENT_NOTE_EXPRESSION; + n.noteexpression.header.flags = + (vstevent.flags & Vst::Event::kIsLive) ? CLAP_EVENT_IS_LIVE : 0; + n.noteexpression.header.space_id = CLAP_CORE_EVENT_SPACE_ID; + n.noteexpression.header.time = vstevent.sampleOffset; + n.noteexpression.header.size = sizeof(clap_event_note_expression); + n.noteexpression.note_id = vstevent.polyPressure.noteId; + for (auto& i : _activeNotes) { - clap_multi_event_t n; - n.noteexpression.header.type = CLAP_EVENT_NOTE_EXPRESSION; - n.noteexpression.header.flags = - (vstevent.flags & Vst::Event::kIsLive) ? CLAP_EVENT_IS_LIVE : 0; - n.noteexpression.header.space_id = CLAP_CORE_EVENT_SPACE_ID; - n.noteexpression.header.time = vstevent.sampleOffset; - n.noteexpression.header.size = sizeof(clap_event_note_expression); - n.noteexpression.note_id = vstevent.polyPressure.noteId; - for (auto& i : _activeNotes) + if (i.used && i.note_id == vstevent.polyPressure.noteId) { - if (i.used && i.note_id == vstevent.polyPressure.noteId) - { - n.noteexpression.expression_id = CLAP_NOTE_EXPRESSION_PRESSURE; - n.noteexpression.port_index = i.port_index; - n.noteexpression.key = i.key; // should be the same as vstevent.polyPressure.pitch - n.noteexpression.channel = i.channel; - n.noteexpression.value = vstevent.polyPressure.pressure; - } + n.noteexpression.expression_id = CLAP_NOTE_EXPRESSION_PRESSURE; + n.noteexpression.port_index = i.port_index; + n.noteexpression.key = i.key; // should be the same as vstevent.polyPressure.pitch + n.noteexpression.channel = i.channel; + n.noteexpression.value = vstevent.polyPressure.pressure; } - _eventindices.push_back(_events.size()); - _events.push_back(n); } - if (vstevent.type == Vst::Event::kNoteExpressionValueEvent) + _eventindices.push_back(_events.size()); + _events.push_back(n); + } + if (vstevent.type == Vst::Event::kNoteExpressionValueEvent) + { + clap_multi_event_t n; + n.noteexpression.header.type = CLAP_EVENT_NOTE_EXPRESSION; + n.noteexpression.header.flags = + (vstevent.flags & Vst::Event::kIsLive) ? CLAP_EVENT_IS_LIVE : 0; + n.noteexpression.header.space_id = CLAP_CORE_EVENT_SPACE_ID; + n.noteexpression.header.time = vstevent.sampleOffset; + n.noteexpression.header.size = sizeof(clap_event_note_expression); + n.noteexpression.note_id = vstevent.noteExpressionValue.noteId; + for (auto& i : _activeNotes) { - clap_multi_event_t n; - n.noteexpression.header.type = CLAP_EVENT_NOTE_EXPRESSION; - n.noteexpression.header.flags = - (vstevent.flags & Vst::Event::kIsLive) ? CLAP_EVENT_IS_LIVE : 0; - n.noteexpression.header.space_id = CLAP_CORE_EVENT_SPACE_ID; - n.noteexpression.header.time = vstevent.sampleOffset; - n.noteexpression.header.size = sizeof(clap_event_note_expression); - n.noteexpression.note_id = vstevent.noteExpressionValue.noteId; - for (auto& i : _activeNotes) + if (i.used && i.note_id == vstevent.noteExpressionValue.noteId) { - if (i.used && i.note_id == vstevent.noteExpressionValue.noteId) + n.noteexpression.port_index = i.port_index; + n.noteexpression.key = i.key; + n.noteexpression.channel = i.channel; + n.noteexpression.value = vstevent.noteExpressionValue.value; + switch (vstevent.noteExpressionValue.typeId) { - n.noteexpression.port_index = i.port_index; - n.noteexpression.key = i.key; - n.noteexpression.channel = i.channel; - n.noteexpression.value = vstevent.noteExpressionValue.value; - switch (vstevent.noteExpressionValue.typeId) - { - case Vst::NoteExpressionTypeIDs::kVolumeTypeID: - n.noteexpression.expression_id = CLAP_NOTE_EXPRESSION_VOLUME; - break; - case Vst::NoteExpressionTypeIDs::kPanTypeID: - n.noteexpression.expression_id = CLAP_NOTE_EXPRESSION_PAN; - break; - case Vst::NoteExpressionTypeIDs::kTuningTypeID: - // VST3 has a 0...1 range; clap has a -120 ... 120 range - n.noteexpression.value = (n.noteexpression.value - 0.5) * 2 * 120; - n.noteexpression.expression_id = CLAP_NOTE_EXPRESSION_TUNING; - break; - case Vst::NoteExpressionTypeIDs::kVibratoTypeID: - n.noteexpression.expression_id = CLAP_NOTE_EXPRESSION_VIBRATO; - break; - case Vst::NoteExpressionTypeIDs::kExpressionTypeID: - n.noteexpression.expression_id = CLAP_NOTE_EXPRESSION_EXPRESSION; - break; - case Vst::NoteExpressionTypeIDs::kBrightnessTypeID: - n.noteexpression.expression_id = CLAP_NOTE_EXPRESSION_BRIGHTNESS; - break; - default: - continue; - } - _eventindices.push_back(_events.size()); - _events.push_back(n); + case Vst::NoteExpressionTypeIDs::kVolumeTypeID: + n.noteexpression.expression_id = CLAP_NOTE_EXPRESSION_VOLUME; + break; + case Vst::NoteExpressionTypeIDs::kPanTypeID: + n.noteexpression.expression_id = CLAP_NOTE_EXPRESSION_PAN; + break; + case Vst::NoteExpressionTypeIDs::kTuningTypeID: + // VST3 has a 0...1 range; clap has a -120 ... 120 range + n.noteexpression.value = (n.noteexpression.value - 0.5) * 2 * 120; + n.noteexpression.expression_id = CLAP_NOTE_EXPRESSION_TUNING; + break; + case Vst::NoteExpressionTypeIDs::kVibratoTypeID: + n.noteexpression.expression_id = CLAP_NOTE_EXPRESSION_VIBRATO; + break; + case Vst::NoteExpressionTypeIDs::kExpressionTypeID: + n.noteexpression.expression_id = CLAP_NOTE_EXPRESSION_EXPRESSION; + break; + case Vst::NoteExpressionTypeIDs::kBrightnessTypeID: + n.noteexpression.expression_id = CLAP_NOTE_EXPRESSION_BRIGHTNESS; + break; + default: + continue; } + _eventindices.push_back(_events.size()); + _events.push_back(n); } } } } } } +} - bool ProcessAdapter::enqueueOutputEvent(const clap_event_header_t* event) +bool ProcessAdapter::enqueueOutputEvent(const clap_event_header_t* event) +{ + switch (event->type) { - switch (event->type) + case CLAP_EVENT_NOTE_ON: { - case CLAP_EVENT_NOTE_ON: - { - auto nevt = reinterpret_cast(event); - - Steinberg::Vst::Event oe{}; - oe.type = Steinberg::Vst::Event::kNoteOnEvent; - oe.noteOn.channel = nevt->channel; - oe.noteOn.pitch = nevt->key; - oe.noteOn.velocity = nevt->velocity; - oe.noteOn.length = 0; - oe.noteOn.tuning = 0.0f; - oe.noteOn.noteId = nevt->note_id; - oe.busIndex = 0; // FIXME - multi-out midi still needs work - oe.sampleOffset = nevt->header.time; - - if (_vstdata && _vstdata->outputEvents) _vstdata->outputEvents->addEvent(oe); - } - return true; - case CLAP_EVENT_NOTE_OFF: - { - auto nevt = reinterpret_cast(event); - - Steinberg::Vst::Event oe{}; - oe.type = Steinberg::Vst::Event::kNoteOffEvent; - oe.noteOff.channel = nevt->channel; - oe.noteOff.pitch = nevt->key; - oe.noteOff.velocity = nevt->velocity; - oe.noteOn.length = 0; - oe.noteOff.tuning = 0.0f; - oe.noteOff.noteId = nevt->note_id; - oe.busIndex = 0; // FIXME - multi-out midi still needs work - oe.sampleOffset = nevt->header.time; - - if (_vstdata && _vstdata->outputEvents) _vstdata->outputEvents->addEvent(oe); - } - return true; - case CLAP_EVENT_NOTE_END: - case CLAP_EVENT_NOTE_CHOKE: - removeFromActiveNotes((const clap_event_note*)(event)); - return true; - break; - case CLAP_EVENT_NOTE_EXPRESSION: - return true; - break; - case CLAP_EVENT_PARAM_VALUE: + auto nevt = reinterpret_cast(event); + + Steinberg::Vst::Event oe{}; + oe.type = Steinberg::Vst::Event::kNoteOnEvent; + oe.noteOn.channel = nevt->channel; + oe.noteOn.pitch = nevt->key; + oe.noteOn.velocity = nevt->velocity; + oe.noteOn.length = 0; + oe.noteOn.tuning = 0.0f; + oe.noteOn.noteId = nevt->note_id; + oe.busIndex = 0; // FIXME - multi-out midi still needs work + oe.sampleOffset = nevt->header.time; + + if (_vstdata && _vstdata->outputEvents) _vstdata->outputEvents->addEvent(oe); + } + return true; + case CLAP_EVENT_NOTE_OFF: + { + auto nevt = reinterpret_cast(event); + + Steinberg::Vst::Event oe{}; + oe.type = Steinberg::Vst::Event::kNoteOffEvent; + oe.noteOff.channel = nevt->channel; + oe.noteOff.pitch = nevt->key; + oe.noteOff.velocity = nevt->velocity; + oe.noteOn.length = 0; + oe.noteOff.tuning = 0.0f; + oe.noteOff.noteId = nevt->note_id; + oe.busIndex = 0; // FIXME - multi-out midi still needs work + oe.sampleOffset = nevt->header.time; + + if (_vstdata && _vstdata->outputEvents) _vstdata->outputEvents->addEvent(oe); + } + return true; + case CLAP_EVENT_NOTE_END: + case CLAP_EVENT_NOTE_CHOKE: + removeFromActiveNotes((const clap_event_note*)(event)); + return true; + break; + case CLAP_EVENT_NOTE_EXPRESSION: + return true; + break; + case CLAP_EVENT_PARAM_VALUE: + { + auto ev = (clap_event_param_value*)event; + auto param = (Vst3Parameter*)this->parameters->getParameter(ev->param_id & 0x7FFFFFFF); + if (param) { - auto ev = (clap_event_param_value*)event; - auto param = (Vst3Parameter*)this->parameters->getParameter(ev->param_id & 0x7FFFFFFF); - if (param) - { - auto param_id = param->getInfo().id; + auto param_id = param->getInfo().id; - // if the parameter is marked as being edited in the UI, pass the value - // to the queue so it can be given to the IComponentHandler - if (std::find(_gesturedParameters.begin(), _gesturedParameters.end(), param_id) != - _gesturedParameters.end()) - { - _automation->onPerformEdit(ev); - } + // if the parameter is marked as being edited in the UI, pass the value + // to the queue so it can be given to the IComponentHandler + if (std::find(_gesturedParameters.begin(), _gesturedParameters.end(), param_id) != + _gesturedParameters.end()) + { + _automation->onPerformEdit(ev); + } - // it also needs to be communicated to the audio thread,otherwise the parameter jumps back to the original value - Steinberg::int32 index = 0; - // addParameterData() does check if there is already a queue and returns it, - // actually, it should be called getParameterQueue() - auto list = _vstdata->outputParameterChanges->addParameterData(param_id, index); + // it also needs to be communicated to the audio thread,otherwise the parameter jumps back to the original value + Steinberg::int32 index = 0; + // addParameterData() does check if there is already a queue and returns it, + // actually, it should be called getParameterQueue() + auto list = _vstdata->outputParameterChanges->addParameterData(param_id, index); - // the implementation of addParameterData() in the SDK always returns a queue, but Cubase 12 (perhaps others, too) - // sometimes don't return a queue object during the first bunch of process calls. I (df) haven't figured out, why. - // therefore we have to check if there is an output queue at all - if (list) - { - Steinberg::int32 index2 = 0; - list->addPoint(ev->header.time, param->asVst3Value(ev->value), index2); - } + // the implementation of addParameterData() in the SDK always returns a queue, but Cubase 12 (perhaps others, too) + // sometimes don't return a queue object during the first bunch of process calls. I (df) haven't figured out, why. + // therefore we have to check if there is an output queue at all + if (list) + { + Steinberg::int32 index2 = 0; + list->addPoint(ev->header.time, param->asVst3Value(ev->value), index2); } } + } - return true; - break; - case CLAP_EVENT_PARAM_MOD: - return true; - break; - case CLAP_EVENT_PARAM_GESTURE_BEGIN: - { - auto ev = (clap_event_param_gesture*)event; - auto param = (Vst3Parameter*)this->parameters->getParameter(ev->param_id & 0x7FFFFFFF); - _gesturedParameters.push_back(param->getInfo().id); - _automation->onBeginEdit(param->getInfo().id); - } - return true; + return true; + break; + case CLAP_EVENT_PARAM_MOD: + return true; + break; + case CLAP_EVENT_PARAM_GESTURE_BEGIN: + { + auto ev = (clap_event_param_gesture*)event; + auto param = (Vst3Parameter*)this->parameters->getParameter(ev->param_id & 0x7FFFFFFF); + _gesturedParameters.push_back(param->getInfo().id); + _automation->onBeginEdit(param->getInfo().id); + } + return true; - break; - case CLAP_EVENT_PARAM_GESTURE_END: - { - auto ev = (clap_event_param_gesture*)event; - auto param = (Vst3Parameter*)this->parameters->getParameter(ev->param_id & 0x7FFFFFFF); + break; + case CLAP_EVENT_PARAM_GESTURE_END: + { + auto ev = (clap_event_param_gesture*)event; + auto param = (Vst3Parameter*)this->parameters->getParameter(ev->param_id & 0x7FFFFFFF); - auto n = - std::remove(_gesturedParameters.begin(), _gesturedParameters.end(), param->getInfo().id); - if (n != _gesturedParameters.end()) - { - _gesturedParameters.erase(n, _gesturedParameters.end()); - _automation->onEndEdit(param->getInfo().id); - } + auto n = std::remove(_gesturedParameters.begin(), _gesturedParameters.end(), param->getInfo().id); + if (n != _gesturedParameters.end()) + { + _gesturedParameters.erase(n, _gesturedParameters.end()); + _automation->onEndEdit(param->getInfo().id); } - return true; - break; - - case CLAP_EVENT_MIDI: - case CLAP_EVENT_MIDI_SYSEX: - case CLAP_EVENT_MIDI2: - return true; - break; - default: - break; } - return false; + return true; + break; + + case CLAP_EVENT_MIDI: + case CLAP_EVENT_MIDI_SYSEX: + case CLAP_EVENT_MIDI2: + return true; + break; + default: + break; } + return false; +} - void ProcessAdapter::addToActiveNotes(const clap_event_note* note) +void ProcessAdapter::addToActiveNotes(const clap_event_note* note) +{ + for (auto& i : _activeNotes) { - for (auto& i : _activeNotes) + if (!i.used) { - if (!i.used) - { - i.note_id = note->note_id; - i.port_index = note->port_index; - i.channel = note->channel; - i.key = note->key; - i.used = true; - return; - } + i.note_id = note->note_id; + i.port_index = note->port_index; + i.channel = note->channel; + i.key = note->key; + i.used = true; + return; } - _activeNotes.push_back({true, note->note_id, note->port_index, note->channel, note->key}); } + _activeNotes.push_back({true, note->note_id, note->port_index, note->channel, note->key}); +} - void ProcessAdapter::removeFromActiveNotes(const clap_event_note* note) +void ProcessAdapter::removeFromActiveNotes(const clap_event_note* note) +{ + for (auto& i : _activeNotes) { - for (auto& i : _activeNotes) + if (i.used && i.port_index == note->port_index && i.channel == note->channel && + i.note_id == note->note_id) { - if (i.used && i.port_index == note->port_index && i.channel == note->channel && - i.note_id == note->note_id) - { - i.used = false; - } + i.used = false; } } +} } // namespace Clap diff --git a/src/detail/vst3/process.h b/src/detail/vst3/process.h index 0a00b532..ab1ff457 100644 --- a/src/detail/vst3/process.h +++ b/src/detail/vst3/process.h @@ -35,18 +35,18 @@ namespace Clap { - class ProcessAdapter +class ProcessAdapter +{ + public: + typedef union clap_multi_event { - public: - typedef union clap_multi_event - { - clap_event_header_t header; - clap_event_note_t note; - clap_event_midi_t midi; - clap_event_midi_sysex_t sysex; - clap_event_param_value_t param; - clap_event_note_expression_t noteexpression; - } clap_multi_event_t; + clap_event_header_t header; + clap_event_note_t note; + clap_event_midi_t midi; + clap_event_midi_sysex_t sysex; + clap_event_param_value_t param; + clap_event_note_expression_t noteexpression; + } clap_multi_event_t; #if 0 // the bitly helpers. These names conflict with macOS params.h but are @@ -63,77 +63,76 @@ namespace Clap } #endif - void setupProcessing(const clap_plugin_t* plugin, const clap_plugin_params_t* ext_params, - Steinberg::Vst::BusList& numInputs, Steinberg::Vst::BusList& numOutputs, - uint32_t numSamples, size_t numEventInputs, size_t numEventOutputs, - Steinberg::Vst::ParameterContainer& params, - Steinberg::Vst::IComponentHandler* componenthandler, IAutomation* automation, - bool enablePolyPressure, bool supportsTuningNoteExpression); - void process(Steinberg::Vst::ProcessData& data); - void flush(); - void processOutputParams(Steinberg::Vst::ProcessData& data); - void activateAudioBus(Steinberg::Vst::BusDirection dir, Steinberg::int32 index, - Steinberg::TBool state); - - // C callbacks - static uint32_t input_events_size(const struct clap_input_events* list); - static const clap_event_header_t* input_events_get(const struct clap_input_events* list, - uint32_t index); - - static bool output_events_try_push(const struct clap_output_events* list, - const clap_event_header_t* event); - - private: - void sortEventIndices(); - void processInputEvents(Steinberg::Vst::IEventList* eventlist); - - bool enqueueOutputEvent(const clap_event_header_t* event); - void addToActiveNotes(const clap_event_note* note); - void removeFromActiveNotes(const clap_event_note* note); - - // the plugin - const clap_plugin_t* _plugin = nullptr; - const clap_plugin_params_t* _ext_params = nullptr; - - Steinberg::Vst::ParameterContainer* parameters = nullptr; - Steinberg::Vst::IComponentHandler* _componentHandler = nullptr; - IAutomation* _automation = nullptr; - Steinberg::Vst::BusList* _audioinputs = nullptr; - Steinberg::Vst::BusList* _audiooutputs = nullptr; - - // for automation gestures - std::vector _gesturedParameters; - - // for INoteExpression - struct ActiveNote - { - bool used = false; - int32_t note_id; // -1 if unspecified, otherwise >=0 - int16_t port_index; - int16_t channel; // 0..15 - int16_t key; // 0..127 - }; - std::vector _activeNotes; - - clap_audio_buffer_t* _input_ports = nullptr; - clap_audio_buffer_t* _output_ports = nullptr; - clap_event_transport_t _transport = {}; - clap_input_events_t _in_events = {}; - clap_output_events_t _out_events = {}; - - float* _silent_input = nullptr; - float* _silent_output = nullptr; - - clap_process_t _processData = {-1, 0, &_transport, nullptr, nullptr, - 0, 0, &_in_events, &_out_events}; - - Steinberg::Vst::ProcessData* _vstdata = nullptr; - - std::vector _events; - std::vector _eventindices; - - bool _supportsPolyPressure = false; - bool _supportsTuningNoteExpression = false; + void setupProcessing(const clap_plugin_t* plugin, const clap_plugin_params_t* ext_params, + Steinberg::Vst::BusList& numInputs, Steinberg::Vst::BusList& numOutputs, + uint32_t numSamples, size_t numEventInputs, size_t numEventOutputs, + Steinberg::Vst::ParameterContainer& params, + Steinberg::Vst::IComponentHandler* componenthandler, IAutomation* automation, + bool enablePolyPressure, bool supportsTuningNoteExpression); + void process(Steinberg::Vst::ProcessData& data); + void flush(); + void processOutputParams(Steinberg::Vst::ProcessData& data); + void activateAudioBus(Steinberg::Vst::BusDirection dir, Steinberg::int32 index, + Steinberg::TBool state); + + // C callbacks + static uint32_t input_events_size(const struct clap_input_events* list); + static const clap_event_header_t* input_events_get(const struct clap_input_events* list, + uint32_t index); + + static bool output_events_try_push(const struct clap_output_events* list, + const clap_event_header_t* event); + + private: + void sortEventIndices(); + void processInputEvents(Steinberg::Vst::IEventList* eventlist); + + bool enqueueOutputEvent(const clap_event_header_t* event); + void addToActiveNotes(const clap_event_note* note); + void removeFromActiveNotes(const clap_event_note* note); + + // the plugin + const clap_plugin_t* _plugin = nullptr; + const clap_plugin_params_t* _ext_params = nullptr; + + Steinberg::Vst::ParameterContainer* parameters = nullptr; + Steinberg::Vst::IComponentHandler* _componentHandler = nullptr; + IAutomation* _automation = nullptr; + Steinberg::Vst::BusList* _audioinputs = nullptr; + Steinberg::Vst::BusList* _audiooutputs = nullptr; + + // for automation gestures + std::vector _gesturedParameters; + + // for INoteExpression + struct ActiveNote + { + bool used = false; + int32_t note_id; // -1 if unspecified, otherwise >=0 + int16_t port_index; + int16_t channel; // 0..15 + int16_t key; // 0..127 }; + std::vector _activeNotes; + + clap_audio_buffer_t* _input_ports = nullptr; + clap_audio_buffer_t* _output_ports = nullptr; + clap_event_transport_t _transport = {}; + clap_input_events_t _in_events = {}; + clap_output_events_t _out_events = {}; + + float* _silent_input = nullptr; + float* _silent_output = nullptr; + + clap_process_t _processData = {-1, 0, &_transport, nullptr, nullptr, 0, 0, &_in_events, &_out_events}; + + Steinberg::Vst::ProcessData* _vstdata = nullptr; + + std::vector _events; + std::vector _eventindices; + + bool _supportsPolyPressure = false; + bool _supportsTuningNoteExpression = false; +}; } // namespace Clap \ No newline at end of file diff --git a/src/wrapasvst3.h b/src/wrapasvst3.h index 87214b14..579bbf33 100644 --- a/src/wrapasvst3.h +++ b/src/wrapasvst3.h @@ -39,7 +39,7 @@ using namespace Steinberg; struct ClapHostExtensions; namespace Clap { - class ProcessAdapter; +class ProcessAdapter; } class queueEvent