git subrepo clone (merge) https://github.com/free-audio/clap-helpers.git deps/clap-juce-extensions/clap-libs/clap-helpers
subrepo: subdir: "deps/clap-juce-extensions/clap-libs/clap-helpers" merged: "2bb43c187" upstream: origin: "https://github.com/free-audio/clap-helpers.git" branch: "main" commit: "2bb43c187" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596"
This commit is contained in:
parent
8bbddf66e9
commit
7fe70ed89b
@ -1 +0,0 @@
|
||||
Subproject commit 2bb43c18788c689708ead6f127a2d75e772ab389
|
136
deps/clap-juce-extensions/clap-libs/clap-helpers/.clang-format
vendored
Normal file
136
deps/clap-juce-extensions/clap-libs/clap-helpers/.clang-format
vendored
Normal file
@ -0,0 +1,136 @@
|
||||
---
|
||||
Language: Cpp
|
||||
AccessModifierOffset: -3
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveMacros: true
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlines: Right
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: true
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
AllowAllConstructorInitializersOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: true
|
||||
AfterControlStatement: true
|
||||
AfterEnum: true
|
||||
AfterFunction: true
|
||||
AfterNamespace: true
|
||||
AfterObjCDeclaration: true
|
||||
AfterStruct: true
|
||||
AfterUnion: true
|
||||
AfterExternBlock: true
|
||||
BeforeCatch: true
|
||||
BeforeElse: true
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Attach
|
||||
BreakBeforeInheritanceComma: false
|
||||
BreakInheritanceList: BeforeColon
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 100
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
CompactNamespaces: true
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 3
|
||||
ContinuationIndentWidth: 3
|
||||
Cpp11BracedListStyle: true
|
||||
DeriveLineEnding: false
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
FixNamespaceComments: true
|
||||
ForEachMacros:
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IncludeBlocks: Preserve
|
||||
IncludeCategories:
|
||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||
Priority: 2
|
||||
SortPriority: 0
|
||||
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||
Priority: 3
|
||||
SortPriority: 0
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
SortPriority: 0
|
||||
IncludeIsMainRegex: '(Test)?$'
|
||||
IncludeIsMainSourceRegex: ''
|
||||
IndentCaseLabels: false
|
||||
IndentGotoLabels: true
|
||||
IndentPPDirectives: AfterHash
|
||||
IndentWidth: 3
|
||||
IndentWrappedFunctionNames: false
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: All
|
||||
ObjCBinPackProtocolList: Auto
|
||||
ObjCBlockIndentWidth: 3
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakAssignment: 2
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PointerAlignment: Right
|
||||
ReflowComments: true
|
||||
SortIncludes: true
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceInEmptyBlock: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInConditionalStatement: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
SpaceBeforeSquareBrackets: false
|
||||
Standard: Latest
|
||||
StatementMacros:
|
||||
- Q_UNUSED
|
||||
- QT_REQUIRE_VERSION
|
||||
TabWidth: 8
|
||||
UseCRLF: false
|
||||
UseTab: Never
|
||||
...
|
||||
|
12
deps/clap-juce-extensions/clap-libs/clap-helpers/.gitrepo
vendored
Normal file
12
deps/clap-juce-extensions/clap-libs/clap-helpers/.gitrepo
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
; DO NOT EDIT (unless you know what you are doing)
|
||||
;
|
||||
; This subdirectory is a git "subrepo", and this file is maintained by the
|
||||
; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
|
||||
;
|
||||
[subrepo]
|
||||
remote = https://github.com/free-audio/clap-helpers.git
|
||||
branch = main
|
||||
commit = 2bb43c18788c689708ead6f127a2d75e772ab389
|
||||
parent = 8bbddf66e9d6b4b8e0a4fb98122ace8d70a5c14d
|
||||
method = merge
|
||||
cmdver = 0.4.3
|
25
deps/clap-juce-extensions/clap-libs/clap-helpers/CMakeLists.txt
vendored
Normal file
25
deps/clap-juce-extensions/clap-libs/clap-helpers/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
cmake_minimum_required(VERSION 3.17)
|
||||
cmake_policy(SET CMP0100 NEW) # handle .hh files
|
||||
project(CLAP_HELPERS C CXX)
|
||||
enable_testing()
|
||||
find_package(Catch2 QUIET)
|
||||
|
||||
add_library(clap-helpers INTERFACE)
|
||||
set_target_properties(clap-helpers PROPERTIES
|
||||
POSITION_INDEPENDENT_CODE ON
|
||||
CXX_STANDARD 11)
|
||||
target_include_directories(clap-helpers INTERFACE include)
|
||||
target_link_libraries(clap-helpers INTERFACE clap-core)
|
||||
|
||||
if (Catch2_FOUND)
|
||||
add_executable(clap-helpers-tests
|
||||
tests/plugin.cc
|
||||
tests/main.cc)
|
||||
set_target_properties(clap-helpers-tests PROPERTIES CXX_STANDARD 11)
|
||||
target_link_libraries(clap-helpers-tests clap-helpers clap-core Catch2::Catch2)
|
||||
target_compile_definitions(clap-helpers-tests PUBLIC -DCATCH_CONFIG_PREFIX_ALL)
|
||||
add_test(NAME test-clap-helpers COMMAND clap-helpers-tests)
|
||||
add_dependencies(clap-tests clap-helpers-tests)
|
||||
endif()
|
||||
|
||||
install(DIRECTORY include DESTINATION ".")
|
21
deps/clap-juce-extensions/clap-libs/clap-helpers/LICENSE
vendored
Normal file
21
deps/clap-juce-extensions/clap-libs/clap-helpers/LICENSE
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Alexandre BIQUE
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
9
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/checking-level.hh
vendored
Normal file
9
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/checking-level.hh
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
namespace clap { namespace helpers {
|
||||
enum class CheckingLevel {
|
||||
None,
|
||||
Minimal,
|
||||
Maximal,
|
||||
};
|
||||
}} // namespace clap::helpers
|
148
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/event-list.hh
vendored
Normal file
148
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/event-list.hh
vendored
Normal file
@ -0,0 +1,148 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
#include <clap/events.h>
|
||||
|
||||
#include "heap.hh"
|
||||
|
||||
namespace clap { namespace helpers {
|
||||
|
||||
class EventList {
|
||||
public:
|
||||
explicit EventList(uint32_t initialHeapSize = 4096,
|
||||
uint32_t initialEventsCapacity = 128,
|
||||
uint32_t maxEventSize = 1024)
|
||||
: _maxEventSize(maxEventSize), _heap(initialHeapSize) {
|
||||
_events.reserve(initialEventsCapacity);
|
||||
}
|
||||
|
||||
EventList(const EventList &) = delete;
|
||||
EventList(EventList &&) = delete;
|
||||
EventList &operator=(const EventList &) = delete;
|
||||
EventList &operator=(EventList &&) = delete;
|
||||
|
||||
static const constexpr size_t SAFE_ALIGN = 8;
|
||||
|
||||
void reserveEvents(size_t capacity) { _events.reserve(capacity); }
|
||||
|
||||
void reserveHeap(size_t size) { _heap.reserve(size); }
|
||||
|
||||
clap_event_header *allocate(size_t align, size_t size) {
|
||||
assert(size >= sizeof(clap_event_header));
|
||||
if (size > _maxEventSize)
|
||||
return nullptr;
|
||||
|
||||
// ensure we have space to store into the vector
|
||||
if (_events.capacity() == _events.size())
|
||||
_events.reserve(_events.capacity() * 2);
|
||||
|
||||
auto ptr = _heap.allocate(align, size);
|
||||
_events.push_back(_heap.offsetFromBase(ptr));
|
||||
auto hdr = static_cast<clap_event_header *>(ptr);
|
||||
hdr->size = size;
|
||||
return hdr;
|
||||
}
|
||||
|
||||
clap_event_header *tryAllocate(size_t align, size_t size) {
|
||||
assert(size >= sizeof(clap_event_header));
|
||||
if (size > _maxEventSize)
|
||||
return nullptr;
|
||||
|
||||
// ensure we have space to store into the vector
|
||||
if (_events.capacity() == _events.size())
|
||||
return nullptr;
|
||||
|
||||
auto ptr = _heap.tryAllocate(align, size);
|
||||
if (!ptr)
|
||||
return nullptr;
|
||||
|
||||
_events.push_back(_heap.offsetFromBase(ptr));
|
||||
auto hdr = static_cast<clap_event_header *>(ptr);
|
||||
hdr->size = size;
|
||||
return hdr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T *allocate() {
|
||||
return allocate(alignof(T), sizeof(T));
|
||||
}
|
||||
|
||||
void push(const clap_event_header *h) {
|
||||
auto ptr = allocate(SAFE_ALIGN, h->size);
|
||||
if (!ptr)
|
||||
return;
|
||||
|
||||
std::memcpy(ptr, h, h->size);
|
||||
}
|
||||
|
||||
bool tryPush(const clap_event_header *h) {
|
||||
auto ptr = tryAllocate(SAFE_ALIGN, h->size);
|
||||
if (!ptr)
|
||||
return false;
|
||||
|
||||
std::memcpy(ptr, h, h->size);
|
||||
return true;
|
||||
}
|
||||
|
||||
clap_event_header *get(uint32_t index) const {
|
||||
const auto offset = _events.at(index);
|
||||
auto const ptr = _heap.ptrFromBase(offset);
|
||||
return static_cast<clap_event_header *>(ptr);
|
||||
}
|
||||
|
||||
size_t size() const { return _events.size(); }
|
||||
|
||||
bool empty() const { return _events.empty(); }
|
||||
|
||||
void clear() {
|
||||
_heap.clear();
|
||||
_events.clear();
|
||||
}
|
||||
|
||||
const clap_input_events *clapInputEvents() const noexcept { return &_inputEvents; }
|
||||
|
||||
const clap_output_events *clapOutputEvents() const noexcept { return &_outputEvents; }
|
||||
|
||||
const clap_output_events *clapBoundedOutputEvents() const noexcept {
|
||||
return &_boundedOutputEvents;
|
||||
}
|
||||
|
||||
private:
|
||||
static uint32_t clapSize(const struct clap_input_events *list) {
|
||||
auto *self = static_cast<const EventList *>(list->ctx);
|
||||
return self->size();
|
||||
}
|
||||
|
||||
static const clap_event_header_t *clapGet(const struct clap_input_events *list,
|
||||
uint32_t index) {
|
||||
auto *self = static_cast<const EventList *>(list->ctx);
|
||||
return self->get(index);
|
||||
}
|
||||
|
||||
static bool clapPushBack(const struct clap_output_events *list,
|
||||
const clap_event_header *event) {
|
||||
auto *self = static_cast<EventList *>(list->ctx);
|
||||
self->push(event);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool clapBoundedPushBack(const struct clap_output_events *list,
|
||||
const clap_event_header_t *event) {
|
||||
auto *self = static_cast<EventList *>(list->ctx);
|
||||
return self->tryPush(event);
|
||||
}
|
||||
|
||||
const clap_input_events _inputEvents = {this, &clapSize, &clapGet};
|
||||
const clap_output_events _outputEvents = {this, &clapPushBack};
|
||||
const clap_output_events _boundedOutputEvents = {this, &clapBoundedPushBack};
|
||||
|
||||
const uint32_t _maxEventSize;
|
||||
|
||||
Heap _heap;
|
||||
std::vector<uint32_t> _events;
|
||||
};
|
||||
|
||||
}} // namespace clap::helpers
|
84
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/heap.hh
vendored
Normal file
84
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/heap.hh
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
namespace clap { namespace helpers {
|
||||
|
||||
/** Simple heap allocator which ensures alignment. */
|
||||
class Heap {
|
||||
public:
|
||||
explicit Heap(uint32_t initialSize = 4096) { reserve(initialSize); }
|
||||
~Heap() { std::free(_base); }
|
||||
|
||||
Heap(const Heap &) = delete;
|
||||
Heap(Heap &&) = delete;
|
||||
Heap &operator=(const Heap &) = delete;
|
||||
Heap &operator=(Heap &&) = delete;
|
||||
|
||||
void reserve(const size_t heapSize) {
|
||||
if (heapSize <= _size)
|
||||
return;
|
||||
|
||||
auto *const ptr = static_cast<uint8_t *>(std::realloc(_base, heapSize));
|
||||
if (!ptr)
|
||||
throw std::bad_alloc();
|
||||
|
||||
_base = ptr;
|
||||
_size = heapSize;
|
||||
}
|
||||
|
||||
void clear() { _brk = 0; }
|
||||
|
||||
void *tryAllocate(uint32_t align, uint32_t size) {
|
||||
assert(_brk <= _size);
|
||||
void *ptr = _base + _brk;
|
||||
size_t space = _size - _brk;
|
||||
|
||||
if (!std::align(align, size, ptr, space))
|
||||
return nullptr;
|
||||
|
||||
auto offset = static_cast<uint8_t *>(ptr) - _base;
|
||||
_brk = offset + size;
|
||||
std::memset(ptr, 0, size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *allocate(uint32_t align, uint32_t size) {
|
||||
assert(_brk <= _size);
|
||||
if (size + _brk > _size)
|
||||
reserve(_size * 2);
|
||||
|
||||
auto ptr = tryAllocate(align, size);
|
||||
assert(ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *ptrFromBase(size_t offset) const {
|
||||
assert(offset <= _brk && "out of range");
|
||||
|
||||
return static_cast<uint8_t *>(_base) + offset;
|
||||
}
|
||||
|
||||
size_t offsetFromBase(const void *ptr) const {
|
||||
assert(ptr >= _base && "ptr before heap's base");
|
||||
size_t offset = static_cast<const uint8_t *>(ptr) - _base;
|
||||
assert(offset < _size && "ptr after heap's end");
|
||||
return offset;
|
||||
}
|
||||
|
||||
size_t size() const { return _size; }
|
||||
|
||||
bool empty() const { return _brk == 0; }
|
||||
|
||||
private:
|
||||
size_t _size = 0;
|
||||
size_t _brk = 0;
|
||||
uint8_t *_base = nullptr;
|
||||
};
|
||||
|
||||
}} // namespace clap::helpers
|
170
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/host-proxy.hh
vendored
Normal file
170
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/host-proxy.hh
vendored
Normal file
@ -0,0 +1,170 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <clap/clap.h>
|
||||
|
||||
#include "checking-level.hh"
|
||||
#include "misbehaviour-handler.hh"
|
||||
|
||||
namespace clap { namespace helpers {
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
class HostProxy {
|
||||
public:
|
||||
HostProxy(const clap_host *host);
|
||||
|
||||
void init();
|
||||
|
||||
///////////////
|
||||
// clap_host //
|
||||
///////////////
|
||||
template <typename T>
|
||||
void getExtension(const T *&ptr, const char *id) noexcept;
|
||||
void requestCallback() noexcept;
|
||||
void requestRestart() noexcept;
|
||||
void requestProcess() noexcept;
|
||||
|
||||
///////////////////
|
||||
// clap_host_log //
|
||||
///////////////////
|
||||
bool canUseHostLog() const noexcept;
|
||||
void log(clap_log_severity severity, const char *msg) const noexcept;
|
||||
void hostMisbehaving(const char *msg) const noexcept;
|
||||
void hostMisbehaving(const std::string &msg) const noexcept { hostMisbehaving(msg.c_str()); }
|
||||
void pluginMisbehaving(const char *msg) const noexcept;
|
||||
void pluginMisbehaving(const std::string &msg) const noexcept {
|
||||
pluginMisbehaving(msg.c_str());
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
// clap_host_thread_check //
|
||||
////////////////////////////
|
||||
bool canUseThreadCheck() const noexcept;
|
||||
bool isMainThread() const noexcept;
|
||||
bool isAudioThread() const noexcept;
|
||||
|
||||
//////////////////////////////////
|
||||
// clap_host_audio_ports_config //
|
||||
//////////////////////////////////
|
||||
bool canUseAudioPortsConfig() const noexcept;
|
||||
void audioPortsConfigRescan() const noexcept;
|
||||
|
||||
///////////////////////////
|
||||
// clap_host_audio_ports //
|
||||
///////////////////////////
|
||||
bool canUseAudioPorts() const noexcept;
|
||||
void audioPortsRescan(uint32_t flags) const noexcept;
|
||||
|
||||
//////////////////////////
|
||||
// clap_host_note_ports //
|
||||
//////////////////////////
|
||||
bool canUseNotePorts() const noexcept;
|
||||
void notePortsRescan(uint32_t flags) const noexcept;
|
||||
|
||||
/////////////////////
|
||||
// clap_host_state //
|
||||
/////////////////////
|
||||
bool canUseState() const noexcept;
|
||||
void stateMarkDirty() const noexcept;
|
||||
|
||||
///////////////////////
|
||||
// clap_host_latency //
|
||||
///////////////////////
|
||||
bool canUseLatency() const noexcept;
|
||||
void latencyChanged() const noexcept;
|
||||
|
||||
////////////////////
|
||||
// clap_host_tail //
|
||||
////////////////////
|
||||
bool canUseTail() const noexcept;
|
||||
void tailChanged() const noexcept;
|
||||
|
||||
/////////////////////////
|
||||
// clap_host_note_name //
|
||||
/////////////////////////
|
||||
bool canUseNoteName() const noexcept;
|
||||
void noteNameChanged() const noexcept;
|
||||
|
||||
//////////////////////
|
||||
// clap_host_params //
|
||||
//////////////////////
|
||||
bool canUseParams() const noexcept;
|
||||
void paramsRescan(clap_param_rescan_flags flags) const noexcept;
|
||||
void paramsClear(clap_id param_id, clap_param_clear_flags flags) const noexcept;
|
||||
void paramsRequestFlush() const noexcept;
|
||||
|
||||
//////////////////////////
|
||||
// clap_host_track_info //
|
||||
//////////////////////////
|
||||
bool canUseTrackInfo() const noexcept;
|
||||
bool trackInfoGet(clap_track_info *info) const noexcept;
|
||||
|
||||
///////////////////
|
||||
// clap_host_gui //
|
||||
///////////////////
|
||||
bool canUseGui() const noexcept;
|
||||
bool guiRequestResize(uint32_t width, uint32_t height) const noexcept;
|
||||
bool guiRequestShow() const noexcept;
|
||||
bool guiRequestHide() const noexcept;
|
||||
void guiClosed(bool wasDestroyed) const noexcept;
|
||||
|
||||
/////////////////////////////
|
||||
// clap_host_timer_support //
|
||||
/////////////////////////////
|
||||
bool canUseTimerSupport() const noexcept;
|
||||
bool timerSupportRegister(uint32_t period_ms, clap_id *timer_id) const noexcept;
|
||||
bool timerSupportUnregister(clap_id timer_id) const noexcept;
|
||||
|
||||
//////////////////////////
|
||||
// clap_host_fd_support //
|
||||
//////////////////////////
|
||||
bool canUsePosixFdSupport() const noexcept;
|
||||
bool posixFdSupportRegister(int fd, int flags) const noexcept;
|
||||
bool posixFdSupportModify(int fd, int flags) const noexcept;
|
||||
bool posixFdSupportUnregister(int fd) const noexcept;
|
||||
|
||||
//////////////////////////////
|
||||
// clap_host_quick_controls //
|
||||
//////////////////////////////
|
||||
bool canUseQuickControls() const noexcept;
|
||||
void quickControlsChanged() const noexcept;
|
||||
void quickControlsSuggestPage(clap_id page_id) const noexcept;
|
||||
|
||||
///////////////////////////
|
||||
// clap_host_thread_pool //
|
||||
///////////////////////////
|
||||
bool canUseThreadPool() const noexcept;
|
||||
bool threadPoolRequestExec(uint32_t numTasks) const noexcept;
|
||||
|
||||
//////////////////////////
|
||||
// clap_host_voice_info //
|
||||
//////////////////////////
|
||||
bool canUseVoiceInfo() const noexcept;
|
||||
void voiceInfoChanged() const noexcept;
|
||||
|
||||
protected:
|
||||
void ensureMainThread(const char *method) const noexcept;
|
||||
void ensureAudioThread(const char *method) const noexcept;
|
||||
|
||||
const clap_host *const _host;
|
||||
|
||||
const clap_host_log *_hostLog = nullptr;
|
||||
const clap_host_thread_check *_hostThreadCheck = nullptr;
|
||||
const clap_host_thread_pool *_hostThreadPool = nullptr;
|
||||
const clap_host_audio_ports *_hostAudioPorts = nullptr;
|
||||
const clap_host_audio_ports_config *_hostAudioPortsConfig = nullptr;
|
||||
const clap_host_note_ports *_hostNotePorts = nullptr;
|
||||
const clap_host_file_reference *_hostFileReference = nullptr;
|
||||
const clap_host_latency *_hostLatency = nullptr;
|
||||
const clap_host_gui *_hostGui = nullptr;
|
||||
const clap_host_timer_support *_hostTimerSupport = nullptr;
|
||||
const clap_host_posix_fd_support *_hostPosixFdSupport = nullptr;
|
||||
const clap_host_params *_hostParams = nullptr;
|
||||
const clap_host_track_info *_hostTrackInfo = nullptr;
|
||||
const clap_host_state *_hostState = nullptr;
|
||||
const clap_host_note_name *_hostNoteName = nullptr;
|
||||
const clap_host_quick_controls *_hostQuickControls = nullptr;
|
||||
const clap_host_voice_info *_hostVoiceInfo = nullptr;
|
||||
const clap_host_tail *_hostTail = nullptr;
|
||||
};
|
||||
}} // namespace clap::helpers
|
546
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/host-proxy.hxx
vendored
Normal file
546
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/host-proxy.hxx
vendored
Normal file
@ -0,0 +1,546 @@
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "host-proxy.hh"
|
||||
|
||||
namespace clap { namespace helpers {
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
HostProxy<h, l>::HostProxy(const ::clap_host *host) : _host(host) {}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
void HostProxy<h, l>::init() {
|
||||
getExtension(_hostLog, CLAP_EXT_LOG);
|
||||
getExtension(_hostThreadCheck, CLAP_EXT_THREAD_CHECK);
|
||||
getExtension(_hostThreadPool, CLAP_EXT_THREAD_POOL);
|
||||
getExtension(_hostAudioPorts, CLAP_EXT_AUDIO_PORTS);
|
||||
getExtension(_hostAudioPortsConfig, CLAP_EXT_AUDIO_PORTS_CONFIG);
|
||||
getExtension(_hostNotePorts, CLAP_EXT_NOTE_PORTS);
|
||||
getExtension(_hostTimerSupport, CLAP_EXT_TIMER_SUPPORT);
|
||||
getExtension(_hostPosixFdSupport, CLAP_EXT_POSIX_FD_SUPPORT);
|
||||
getExtension(_hostFileReference, CLAP_EXT_FILE_REFERENCE);
|
||||
getExtension(_hostLatency, CLAP_EXT_LATENCY);
|
||||
getExtension(_hostGui, CLAP_EXT_GUI);
|
||||
getExtension(_hostParams, CLAP_EXT_PARAMS);
|
||||
getExtension(_hostTrackInfo, CLAP_EXT_TRACK_INFO);
|
||||
getExtension(_hostState, CLAP_EXT_STATE);
|
||||
getExtension(_hostNoteName, CLAP_EXT_NOTE_NAME);
|
||||
getExtension(_hostQuickControls, CLAP_EXT_QUICK_CONTROLS);
|
||||
getExtension(_hostVoiceInfo, CLAP_EXT_VOICE_INFO);
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
template <typename T>
|
||||
void HostProxy<h, l>::getExtension(const T *&ptr, const char *id) noexcept {
|
||||
assert(!ptr);
|
||||
assert(id);
|
||||
|
||||
if (_host->get_extension)
|
||||
ptr = static_cast<const T *>(_host->get_extension(_host, id));
|
||||
}
|
||||
|
||||
///////////////
|
||||
// clap_host //
|
||||
///////////////
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
void HostProxy<h, l>::requestCallback() noexcept {
|
||||
_host->request_callback(_host);
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
void HostProxy<h, l>::requestRestart() noexcept {
|
||||
_host->request_restart(_host);
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
void HostProxy<h, l>::requestProcess() noexcept {
|
||||
_host->request_process(_host);
|
||||
}
|
||||
|
||||
/////////////
|
||||
// Logging //
|
||||
/////////////
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
bool HostProxy<h, l>::canUseHostLog() const noexcept {
|
||||
return _hostLog && _hostLog->log;
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
void HostProxy<h, l>::log(clap_log_severity severity, const char *msg) const noexcept {
|
||||
if (canUseHostLog()) {
|
||||
_hostLog->log(_host, severity, msg);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (severity) {
|
||||
case CLAP_LOG_ERROR:
|
||||
case CLAP_LOG_HOST_MISBEHAVING:
|
||||
std::cerr << msg << std::endl;
|
||||
break;
|
||||
|
||||
default:
|
||||
std::clog << msg << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
void HostProxy<h, l>::hostMisbehaving(const char *msg) const noexcept {
|
||||
log(CLAP_LOG_HOST_MISBEHAVING, msg);
|
||||
|
||||
if (h == MisbehaviourHandler::Terminate)
|
||||
std::terminate();
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
void HostProxy<h, l>::pluginMisbehaving(const char *msg) const noexcept {
|
||||
log(CLAP_LOG_PLUGIN_MISBEHAVING, msg);
|
||||
|
||||
if (h == MisbehaviourHandler::Terminate)
|
||||
std::terminate();
|
||||
}
|
||||
|
||||
//////////////////
|
||||
// Thread Check //
|
||||
//////////////////
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
bool HostProxy<h, l>::canUseThreadCheck() const noexcept {
|
||||
return _hostThreadCheck && _hostThreadCheck->is_audio_thread &&
|
||||
_hostThreadCheck->is_main_thread;
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
bool HostProxy<h, l>::isMainThread() const noexcept {
|
||||
assert(canUseThreadCheck());
|
||||
return _hostThreadCheck->is_main_thread(_host);
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
bool HostProxy<h, l>::isAudioThread() const noexcept {
|
||||
assert(canUseThreadCheck());
|
||||
return _hostThreadCheck->is_audio_thread(_host);
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
void HostProxy<h, l>::ensureMainThread(const char *method) const noexcept {
|
||||
if (l == CheckingLevel::None)
|
||||
return;
|
||||
|
||||
if (!canUseThreadCheck() || isMainThread())
|
||||
return;
|
||||
|
||||
std::ostringstream msg;
|
||||
msg << "Plugin called the method clap_host_" << method
|
||||
<< "() on wrong thread! It must be called on main thread!";
|
||||
pluginMisbehaving(msg.str());
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
void HostProxy<h, l>::ensureAudioThread(const char *method) const noexcept {
|
||||
if (l == CheckingLevel::None)
|
||||
return;
|
||||
|
||||
if (!canUseThreadCheck() || isAudioThread())
|
||||
return;
|
||||
|
||||
std::ostringstream msg;
|
||||
msg << "Plugin called the method clap_host_" << method
|
||||
<< "() on wrong thread! It must be called on audio thread!";
|
||||
pluginMisbehaving(msg.str());
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
// clap_host_audio_ports_config //
|
||||
//////////////////////////////////
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
bool HostProxy<h, l>::canUseAudioPortsConfig() const noexcept {
|
||||
if (!_hostAudioPortsConfig)
|
||||
return false;
|
||||
|
||||
if (_hostAudioPortsConfig->rescan)
|
||||
return true;
|
||||
|
||||
hostMisbehaving("clap_host_audio_ports_config is partially implemented");
|
||||
return false;
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
void HostProxy<h, l>::audioPortsConfigRescan() const noexcept {
|
||||
assert(canUseAudioPortsConfig());
|
||||
ensureMainThread("audio_ports_config.rescan");
|
||||
_hostAudioPortsConfig->rescan(_host);
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
// clap_host_audio_ports //
|
||||
///////////////////////////
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
bool HostProxy<h, l>::canUseAudioPorts() const noexcept {
|
||||
if (!_hostAudioPorts)
|
||||
return false;
|
||||
|
||||
if (_hostAudioPorts->rescan)
|
||||
return true;
|
||||
|
||||
hostMisbehaving("clap_host_audio_ports is partially implemented");
|
||||
return false;
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
void HostProxy<h, l>::audioPortsRescan(uint32_t flags) const noexcept {
|
||||
assert(canUseAudioPorts());
|
||||
ensureMainThread("audio_ports.rescan");
|
||||
_hostAudioPorts->rescan(_host, flags);
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
// clap_host_note_ports //
|
||||
//////////////////////////
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
bool HostProxy<h, l>::canUseNotePorts() const noexcept {
|
||||
if (!_hostNotePorts)
|
||||
return false;
|
||||
|
||||
if (_hostNotePorts->rescan)
|
||||
return true;
|
||||
|
||||
hostMisbehaving("clap_host_note_ports is partially implemented");
|
||||
return false;
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
void HostProxy<h, l>::notePortsRescan(uint32_t flags) const noexcept {
|
||||
assert(canUseNotePorts());
|
||||
ensureMainThread("note_ports.rescan");
|
||||
_hostNotePorts->rescan(_host, flags);
|
||||
}
|
||||
|
||||
/////////////////////
|
||||
// clap_host_state //
|
||||
/////////////////////
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
bool HostProxy<h, l>::canUseState() const noexcept {
|
||||
if (!_hostState)
|
||||
return false;
|
||||
|
||||
if (_hostState->mark_dirty)
|
||||
return true;
|
||||
|
||||
hostMisbehaving("clap_host_state is partially implemented");
|
||||
return false;
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
void HostProxy<h, l>::stateMarkDirty() const noexcept {
|
||||
assert(canUseState());
|
||||
ensureMainThread("state.mark_dirty");
|
||||
_hostState->mark_dirty(_host);
|
||||
}
|
||||
|
||||
///////////////////////
|
||||
// clap_host_latency //
|
||||
///////////////////////
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
bool HostProxy<h, l>::canUseLatency() const noexcept {
|
||||
if (!_hostLatency)
|
||||
return false;
|
||||
|
||||
if (_hostLatency->changed)
|
||||
return true;
|
||||
|
||||
hostMisbehaving("clap_host_latency is partially implemented");
|
||||
return false;
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
void HostProxy<h, l>::latencyChanged() const noexcept {
|
||||
assert(canUseLatency());
|
||||
ensureMainThread("latency.changed");
|
||||
_hostLatency->changed(_host);
|
||||
}
|
||||
|
||||
////////////////////
|
||||
// clap_host_tail //
|
||||
////////////////////
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
bool HostProxy<h, l>::canUseTail() const noexcept {
|
||||
if (!_hostTail)
|
||||
return false;
|
||||
|
||||
if (_hostLatency->changed)
|
||||
return true;
|
||||
|
||||
hostMisbehaving("clap_host_tail is partially implemented");
|
||||
return false;
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
void HostProxy<h, l>::tailChanged() const noexcept {
|
||||
assert(canUseTail());
|
||||
ensureAudioThread("tail.changed");
|
||||
_hostTail->changed(_host);
|
||||
}
|
||||
|
||||
/////////////////////////
|
||||
// clap_host_note_name //
|
||||
/////////////////////////
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
bool HostProxy<h, l>::canUseNoteName() const noexcept {
|
||||
if (!_hostNoteName)
|
||||
return false;
|
||||
|
||||
if (_hostNoteName->changed)
|
||||
return true;
|
||||
|
||||
hostMisbehaving("clap_host_note_name is partially implemented");
|
||||
return false;
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
void HostProxy<h, l>::noteNameChanged() const noexcept {
|
||||
assert(canUseNoteName());
|
||||
ensureMainThread("note_name.changed");
|
||||
_hostNoteName->changed(_host);
|
||||
}
|
||||
|
||||
//////////////////////
|
||||
// clap_host_params //
|
||||
//////////////////////
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
bool HostProxy<h, l>::canUseParams() const noexcept {
|
||||
if (!_hostParams)
|
||||
return false;
|
||||
|
||||
if (_hostParams->rescan && _hostParams->clear && _hostParams->request_flush)
|
||||
return true;
|
||||
|
||||
hostMisbehaving("clap_host_params is partially implemented");
|
||||
return false;
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
void HostProxy<h, l>::paramsRescan(clap_param_rescan_flags flags) const noexcept {
|
||||
assert(canUseParams());
|
||||
ensureMainThread("params.rescan");
|
||||
_hostParams->rescan(_host, flags);
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
void HostProxy<h, l>::paramsClear(clap_id param_id,
|
||||
clap_param_clear_flags flags) const noexcept {
|
||||
assert(canUseParams());
|
||||
ensureMainThread("params.clear");
|
||||
_hostParams->clear(_host, param_id, flags);
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
void HostProxy<h, l>::paramsRequestFlush() const noexcept {
|
||||
assert(canUseParams());
|
||||
_hostParams->request_flush(_host);
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
// clap_host_track_info //
|
||||
//////////////////////////
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
bool HostProxy<h, l>::canUseTrackInfo() const noexcept {
|
||||
if (!_hostTrackInfo)
|
||||
return false;
|
||||
|
||||
if (_hostTrackInfo->get)
|
||||
return true;
|
||||
|
||||
hostMisbehaving("clap_host_track_info is partially implemented");
|
||||
return false;
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
bool HostProxy<h, l>::trackInfoGet(clap_track_info *info) const noexcept {
|
||||
assert(canUseTrackInfo());
|
||||
ensureMainThread("track_info.get");
|
||||
return _hostTrackInfo->get(_host, info);
|
||||
}
|
||||
|
||||
///////////////////
|
||||
// clap_host_gui //
|
||||
///////////////////
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
bool HostProxy<h, l>::canUseGui() const noexcept {
|
||||
if (!_hostGui)
|
||||
return false;
|
||||
|
||||
if (_hostGui->resize_hints_changed && _hostGui->request_resize && _hostGui->request_hide &&
|
||||
_hostGui->request_show && _hostGui->closed)
|
||||
return true;
|
||||
|
||||
hostMisbehaving("clap_host_gui is partially implemented");
|
||||
return false;
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
bool HostProxy<h, l>::guiRequestResize(uint32_t width, uint32_t height) const noexcept {
|
||||
assert(canUseGui());
|
||||
return _hostGui->request_resize(_host, width, height);
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
bool HostProxy<h, l>::guiRequestShow() const noexcept {
|
||||
assert(canUseGui());
|
||||
return _hostGui->request_show(_host);
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
bool HostProxy<h, l>::guiRequestHide() const noexcept {
|
||||
assert(canUseGui());
|
||||
return _hostGui->request_hide(_host);
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
void HostProxy<h, l>::guiClosed(bool wasDestroyed) const noexcept {
|
||||
assert(canUseGui());
|
||||
_hostGui->closed(_host, wasDestroyed);
|
||||
}
|
||||
|
||||
///////////////////
|
||||
// Timer Support //
|
||||
///////////////////
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
bool HostProxy<h, l>::canUseTimerSupport() const noexcept {
|
||||
if (!_hostTimerSupport)
|
||||
return false;
|
||||
|
||||
auto &x = *_hostTimerSupport;
|
||||
if (x.register_timer && x.unregister_timer)
|
||||
return true;
|
||||
|
||||
hostMisbehaving("clap_timer_support is partially implemented");
|
||||
return false;
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
bool HostProxy<h, l>::timerSupportRegister(uint32_t period_ms,
|
||||
clap_id *timer_id) const noexcept {
|
||||
assert(canUseTimerSupport());
|
||||
ensureMainThread("timer_support.register_timer");
|
||||
return _hostTimerSupport->register_timer(_host, period_ms, timer_id);
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
bool HostProxy<h, l>::timerSupportUnregister(clap_id timer_id) const noexcept {
|
||||
assert(canUseTimerSupport());
|
||||
ensureMainThread("timer_support.unregister_timer");
|
||||
return _hostTimerSupport->unregister_timer(_host, timer_id);
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
// clap_host_fd_support //
|
||||
//////////////////////////
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
bool HostProxy<h, l>::canUsePosixFdSupport() const noexcept {
|
||||
if (!_hostPosixFdSupport)
|
||||
return false;
|
||||
|
||||
auto &x = *_hostPosixFdSupport;
|
||||
if (x.modify_fd && x.register_fd && x.unregister_fd)
|
||||
return true;
|
||||
|
||||
hostMisbehaving("clap_posix_fd_support is partially implemented");
|
||||
return false;
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
bool HostProxy<h, l>::posixFdSupportRegister(int fd, int flags) const noexcept {
|
||||
assert(canUsePosixFdSupport());
|
||||
ensureMainThread("posix_fd_support.register");
|
||||
return _hostPosixFdSupport->register_fd(_host, fd, flags);
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
bool HostProxy<h, l>::posixFdSupportModify(int fd, int flags) const noexcept {
|
||||
assert(canUsePosixFdSupport());
|
||||
ensureMainThread("posix_fd_support.modify");
|
||||
return _hostPosixFdSupport->modify_fd(_host, fd, flags);
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
bool HostProxy<h, l>::posixFdSupportUnregister(int fd) const noexcept {
|
||||
assert(canUsePosixFdSupport());
|
||||
ensureMainThread("posix_fd_support.unregister");
|
||||
return _hostPosixFdSupport->unregister_fd(_host, fd);
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
// clap_host_thread_pool //
|
||||
///////////////////////////
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
bool HostProxy<h, l>::canUseThreadPool() const noexcept {
|
||||
if (!_hostThreadPool)
|
||||
return false;
|
||||
|
||||
if (_hostThreadPool->request_exec)
|
||||
return true;
|
||||
|
||||
hostMisbehaving("clap_host_thread_pool is partially implemented");
|
||||
return false;
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
bool HostProxy<h, l>::threadPoolRequestExec(uint32_t numTasks) const noexcept {
|
||||
assert(canUseThreadPool());
|
||||
ensureAudioThread("thread_pool.request_exec");
|
||||
return _hostThreadPool->request_exec(_host, numTasks);
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
// clap_host_voice_info //
|
||||
//////////////////////////
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
bool HostProxy<h, l>::canUseVoiceInfo() const noexcept {
|
||||
if (!_hostVoiceInfo)
|
||||
return false;
|
||||
|
||||
if (_hostVoiceInfo->changed)
|
||||
return true;
|
||||
|
||||
hostMisbehaving("clap_host_voice_info is partially implemented");
|
||||
return false;
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
void HostProxy<h, l>::voiceInfoChanged() const noexcept {
|
||||
assert(canUseVoiceInfo());
|
||||
ensureMainThread("voice_info.changed");
|
||||
return _hostVoiceInfo->changed(_host);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// clap_host_quick_controls //
|
||||
//////////////////////////////
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
bool HostProxy<h, l>::canUseQuickControls() const noexcept {
|
||||
if (!_hostQuickControls)
|
||||
return false;
|
||||
|
||||
if (_hostQuickControls->changed && _hostQuickControls->suggest_page)
|
||||
return true;
|
||||
|
||||
hostMisbehaving("clap_host_quick_controls is partially implemented");
|
||||
return false;
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
void HostProxy<h, l>::quickControlsChanged() const noexcept {
|
||||
assert(canUseQuickControls());
|
||||
ensureMainThread("quick_controls.changed");
|
||||
_hostQuickControls->changed(_host);
|
||||
}
|
||||
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
void HostProxy<h, l>::quickControlsSuggestPage(clap_id page_id) const noexcept {
|
||||
assert(canUseQuickControls());
|
||||
ensureMainThread("quick_controls.suggest_page");
|
||||
_hostQuickControls->suggest_page(_host, page_id);
|
||||
}
|
||||
}} // namespace clap::helpers
|
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
namespace clap { namespace helpers {
|
||||
enum class MisbehaviourHandler {
|
||||
Ignore,
|
||||
Terminate,
|
||||
};
|
||||
}} // namespace clap::helpers
|
75
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/note-end-queue.hh
vendored
Normal file
75
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/note-end-queue.hh
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <unordered_set>
|
||||
|
||||
#include <clap/clap.h>
|
||||
|
||||
namespace clap { namespace helpers {
|
||||
class NoteEndQueue {
|
||||
public:
|
||||
explicit NoteEndQueue(std::size_t initialBucketSize = 19)
|
||||
: _voicesToKill(initialBucketSize) {}
|
||||
|
||||
void onNoteOn(int32_t noteId, int16_t port, int16_t channel, int16_t key) {
|
||||
assert(checkValidEntry(noteId, port, channel, key));
|
||||
_voicesToKill.erase(Entry(noteId, port, channel, key));
|
||||
}
|
||||
|
||||
void onNoteEnd(int32_t noteId, int16_t port, int16_t channel, int16_t key) {
|
||||
assert(checkValidEntry(noteId, port, channel, key));
|
||||
_voicesToKill.insert(Entry(noteId, port, channel, key));
|
||||
}
|
||||
|
||||
void flush(const clap_output_events *out) {
|
||||
clap_event_note ev;
|
||||
ev.velocity = 0;
|
||||
ev.header.flags = 0;
|
||||
ev.header.size = sizeof(ev);
|
||||
ev.header.space_id = CLAP_CORE_EVENT_SPACE_ID;
|
||||
ev.header.time = 0; // time is irrelevant here
|
||||
ev.header.type = CLAP_EVENT_NOTE_END;
|
||||
|
||||
for (auto &e : _voicesToKill) {
|
||||
ev.port_index = e._port;
|
||||
ev.channel = e._channel;
|
||||
ev.key = e._key;
|
||||
ev.note_id = e._noteId;
|
||||
out->try_push(out, &ev.header);
|
||||
}
|
||||
|
||||
_voicesToKill.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
bool checkValidEntry(int32_t noteId, int16_t port, int16_t channel, int16_t key) {
|
||||
assert(noteId >= -1);
|
||||
assert(port >= 0);
|
||||
assert(channel >= 0 && channel < 16);
|
||||
assert(key >= 0 && key < 127);
|
||||
return true;
|
||||
}
|
||||
|
||||
struct Entry {
|
||||
constexpr Entry(int32_t noteId, int16_t port, int16_t channel, int16_t key)
|
||||
: _noteId(noteId), _port(port), _channel(channel), _key(key) {}
|
||||
|
||||
constexpr bool operator==(const Entry &o) const noexcept {
|
||||
return _port == o._port && _channel == o._channel && _key == o._key;
|
||||
}
|
||||
|
||||
const int32_t _noteId;
|
||||
const int16_t _port;
|
||||
const int16_t _channel;
|
||||
const int16_t _key;
|
||||
};
|
||||
|
||||
struct EntryHash {
|
||||
std::size_t operator()(const Entry &e) const noexcept {
|
||||
return e._key ^ (e._channel << 8) ^ (e._port << 16) ^ (int64_t(e._noteId) << 32LL);
|
||||
}
|
||||
};
|
||||
|
||||
std::unordered_set<Entry, EntryHash> _voicesToKill;
|
||||
};
|
||||
}} // namespace clap::helpers
|
71
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/param-queue.hh
vendored
Normal file
71
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/param-queue.hh
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
|
||||
namespace clap { namespace helpers {
|
||||
template <typename T, size_t CAPACITY>
|
||||
class ParamQueue {
|
||||
public:
|
||||
using value_type = T;
|
||||
|
||||
ParamQueue() = default;
|
||||
|
||||
void push(const T &value) {
|
||||
while (!tryPush(value))
|
||||
;
|
||||
}
|
||||
|
||||
bool tryPush(const T &value) {
|
||||
int w = _writeOffset; // write element
|
||||
int wn = (w + 1) % CAPACITY; // next write element
|
||||
|
||||
if (wn == _readOffset)
|
||||
return false;
|
||||
|
||||
_data[w] = value;
|
||||
_writeOffset = wn;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tryPeek(T &value) {
|
||||
int r = _readOffset;
|
||||
if (r == _writeOffset)
|
||||
return false; // empty
|
||||
|
||||
value = _data[r];
|
||||
return true;
|
||||
}
|
||||
|
||||
void consume() {
|
||||
int r = _readOffset;
|
||||
if (r == _writeOffset) {
|
||||
assert(false && "consume should not have been called");
|
||||
return; // empty
|
||||
}
|
||||
|
||||
int rn = (r + 1) % CAPACITY;
|
||||
_readOffset = rn;
|
||||
}
|
||||
|
||||
bool tryPop(T &value) {
|
||||
if (!tryPeek(value))
|
||||
return false;
|
||||
|
||||
consume();
|
||||
return true;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
_writeOffset = 0;
|
||||
_readOffset = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
std::array<T, CAPACITY> _data;
|
||||
std::atomic<int> _writeOffset = {0};
|
||||
std::atomic<int> _readOffset = {0};
|
||||
};
|
||||
}} // namespace clap::helpers
|
37
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/plugin-proxy.hh
vendored
Normal file
37
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/plugin-proxy.hh
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include "host-proxy.hh"
|
||||
|
||||
namespace clap { namespace helpers {
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
class PluginProxy {
|
||||
public:
|
||||
PluginProxy(const clap_host *host, const clap_plugin *plugin);
|
||||
|
||||
void init();
|
||||
|
||||
template <typename T>
|
||||
void getExtension(const T *&ptr, const char *id) noexcept;
|
||||
|
||||
protected:
|
||||
void ensureMainThread(const char *method) const noexcept;
|
||||
void ensureAudioThread(const char *method) const noexcept;
|
||||
|
||||
HostProxy<h, l> _host;
|
||||
const clap_plugin *const _plugin;
|
||||
|
||||
const clap_plugin_params *_pluginParams = nullptr;
|
||||
const clap_plugin_quick_controls *_pluginQuickControls = nullptr;
|
||||
const clap_plugin_audio_ports *_pluginAudioPorts = nullptr;
|
||||
const clap_plugin_gui *_pluginGui = nullptr;
|
||||
const clap_plugin_gui_x11 *_pluginGuiX11 = nullptr;
|
||||
const clap_plugin_gui_win32 *_pluginGuiWin32 = nullptr;
|
||||
const clap_plugin_gui_cocoa *_pluginGuiCocoa = nullptr;
|
||||
const clap_plugin_gui_free_standing *_pluginGuiFreeStanding = nullptr;
|
||||
const clap_plugin_timer_support *_pluginTimerSupport = nullptr;
|
||||
const clap_plugin_fd_support *_pluginFdSupport = nullptr;
|
||||
const clap_plugin_thread_pool *_pluginThreadPool = nullptr;
|
||||
const clap_plugin_preset_load *_pluginPresetLoad = nullptr;
|
||||
const clap_plugin_state *_pluginState = nullptr;
|
||||
};
|
||||
}} // namespace clap::helpers
|
434
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/plugin.hh
vendored
Normal file
434
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/plugin.hh
vendored
Normal file
@ -0,0 +1,434 @@
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include <clap/clap.h>
|
||||
|
||||
#include "checking-level.hh"
|
||||
#include "host-proxy.hh"
|
||||
#include "misbehaviour-handler.hh"
|
||||
|
||||
namespace clap { namespace helpers {
|
||||
|
||||
/// @brief C++ glue and checks
|
||||
///
|
||||
/// @note for an higher level implementation, see @ref PluginHelper
|
||||
template <MisbehaviourHandler h, CheckingLevel l>
|
||||
class Plugin {
|
||||
public:
|
||||
const clap_plugin *clapPlugin() noexcept { return &_plugin; }
|
||||
|
||||
protected:
|
||||
Plugin(const clap_plugin_descriptor *desc, const clap_host *host);
|
||||
virtual ~Plugin() = default;
|
||||
|
||||
// not copyable, not moveable
|
||||
Plugin(const Plugin &) = delete;
|
||||
Plugin(Plugin &&) = delete;
|
||||
Plugin &operator=(const Plugin &) = delete;
|
||||
Plugin &operator=(Plugin &&) = delete;
|
||||
|
||||
/////////////////////////
|
||||
// Methods to override //
|
||||
/////////////////////////
|
||||
|
||||
//-------------//
|
||||
// clap_plugin //
|
||||
//-------------//
|
||||
virtual bool init() noexcept { return true; }
|
||||
virtual bool
|
||||
activate(double sampleRate, uint32_t minFrameCount, uint32_t maxFrameCount) noexcept {
|
||||
return true;
|
||||
}
|
||||
virtual void deactivate() noexcept {}
|
||||
virtual bool startProcessing() noexcept { return true; }
|
||||
virtual void stopProcessing() noexcept {}
|
||||
virtual clap_process_status process(const clap_process *process) noexcept {
|
||||
return CLAP_PROCESS_SLEEP;
|
||||
}
|
||||
virtual void reset() noexcept {}
|
||||
virtual void onMainThread() noexcept {}
|
||||
virtual const void *extension(const char *id) noexcept { return nullptr; }
|
||||
|
||||
//---------------------//
|
||||
// clap_plugin_latency //
|
||||
//---------------------//
|
||||
virtual bool implementsLatency() const noexcept { return false; }
|
||||
virtual uint32_t latencyGet() const noexcept { return 0; }
|
||||
|
||||
//------------------//
|
||||
// clap_plugin_tail //
|
||||
//------------------//
|
||||
virtual bool implementsTail() const noexcept { return false; }
|
||||
virtual uint32_t tailGet(const clap_plugin_t *plugin) const noexcept { return 0; }
|
||||
|
||||
//--------------------//
|
||||
// clap_plugin_render //
|
||||
//--------------------//
|
||||
virtual bool implementsRender() const noexcept { return false; }
|
||||
virtual bool renderHasHardRealtimeRequirement() noexcept { return false; }
|
||||
virtual bool renderSetMode(clap_plugin_render_mode mode) noexcept { return false; }
|
||||
|
||||
//-------------------------//
|
||||
// clap_plugin_thread_pool //
|
||||
//-------------------------//
|
||||
virtual bool implementsThreadPool() const noexcept { return false; }
|
||||
virtual void threadPoolExec(uint32_t taskIndex) noexcept {}
|
||||
|
||||
//-------------------//
|
||||
// clap_plugin_state //
|
||||
//-------------------//
|
||||
virtual bool implementsState() const noexcept { return false; }
|
||||
virtual bool stateSave(const clap_ostream *stream) noexcept { return false; }
|
||||
virtual bool stateLoad(const clap_istream *stream) noexcept { return false; }
|
||||
|
||||
//-------------------------//
|
||||
// clap_plugin_preset_load //
|
||||
//-------------------------//
|
||||
virtual bool implementsPresetLoad() const noexcept { return false; }
|
||||
virtual bool presetLoadFromFile(const char *path) noexcept { return false; }
|
||||
|
||||
//------------------------//
|
||||
// clap_plugin_track_info //
|
||||
//------------------------//
|
||||
virtual bool implementsTrackInfo() const noexcept { return false; }
|
||||
virtual void trackInfoChanged() noexcept {}
|
||||
|
||||
//-------------------------//
|
||||
// clap_plugin_audio_ports //
|
||||
//-------------------------//
|
||||
virtual bool implementsAudioPorts() const noexcept { return false; }
|
||||
virtual uint32_t audioPortsCount(bool isInput) const noexcept { return 0; }
|
||||
virtual bool
|
||||
audioPortsInfo(uint32_t index, bool isInput, clap_audio_port_info *info) const noexcept {
|
||||
return false;
|
||||
}
|
||||
virtual uint32_t audioPortsConfigCount() const noexcept { return 0; }
|
||||
virtual bool audioPortsGetConfig(uint32_t index,
|
||||
clap_audio_ports_config *config) const noexcept {
|
||||
return false;
|
||||
}
|
||||
virtual bool audioPortsSetConfig(clap_id configId) noexcept { return false; }
|
||||
|
||||
//--------------------//
|
||||
// clap_plugin_params //
|
||||
//--------------------//
|
||||
virtual bool implementsParams() const noexcept { return false; }
|
||||
virtual uint32_t paramsCount() const noexcept { return 0; }
|
||||
virtual bool paramsInfo(uint32_t paramIndex, clap_param_info *info) const noexcept {
|
||||
return false;
|
||||
}
|
||||
virtual bool paramsValue(clap_id paramId, double *value) noexcept { return false; }
|
||||
virtual bool
|
||||
paramsValueToText(clap_id paramId, double value, char *display, uint32_t size) noexcept {
|
||||
return false;
|
||||
}
|
||||
virtual bool paramsTextToValue(clap_id paramId, const char *display, double *value) noexcept {
|
||||
return false;
|
||||
}
|
||||
virtual void paramsFlush(const clap_input_events *in,
|
||||
const clap_output_events *out) noexcept {}
|
||||
virtual bool isValidParamId(clap_id paramId) const noexcept;
|
||||
|
||||
//----------------------------//
|
||||
// clap_plugin_quick_controls //
|
||||
//----------------------------//
|
||||
virtual bool implementQuickControls() const noexcept { return false; }
|
||||
virtual uint32_t quickControlsPageCount() noexcept { return 0; }
|
||||
virtual bool quickControlsPageGet(uint32_t pageIndex,
|
||||
clap_quick_controls_page *page) noexcept {
|
||||
return false;
|
||||
}
|
||||
virtual void quickControlsSelectPage(clap_id pageId) noexcept {}
|
||||
virtual clap_id quickControlsSelectedPage() noexcept { return CLAP_INVALID_ID; }
|
||||
|
||||
//------------------------//
|
||||
// clap_plugin_note_ports //
|
||||
//------------------------//
|
||||
virtual bool implementsNotePorts() const noexcept { return false; }
|
||||
virtual uint32_t notePortsCount(bool isInput) const noexcept { return 0; }
|
||||
virtual bool
|
||||
notePortsInfo(uint32_t index, bool isInput, clap_note_port_info *info) const noexcept {
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------//
|
||||
// clap_plugin_note_name //
|
||||
//-----------------------//
|
||||
virtual bool implementsNoteName() const noexcept { return false; }
|
||||
virtual int noteNameCount() noexcept { return 0; }
|
||||
virtual bool noteNameGet(int index, clap_note_name *noteName) noexcept { return false; }
|
||||
|
||||
//---------------------------//
|
||||
// clap_plugin_timer_support //
|
||||
//---------------------------//
|
||||
virtual bool implementsTimerSupport() const noexcept { return false; }
|
||||
virtual void onTimer(clap_id timerId) noexcept {}
|
||||
|
||||
//------------------------------//
|
||||
// clap_plugin_posix_fd_support //
|
||||
//------------------------------//
|
||||
virtual bool implementsPosixFdSupport() const noexcept { return false; }
|
||||
virtual void onPosixFd(int fd, int flags) noexcept {}
|
||||
|
||||
//-----------------//
|
||||
// clap_plugin_gui //
|
||||
//-----------------//
|
||||
virtual bool implementsGui() const noexcept { return false; }
|
||||
virtual bool guiIsApiSupported(const char *api, bool isFloating) noexcept { return false; }
|
||||
virtual bool guiGetPreferredApi(const char **api, bool *is_floating) noexcept {
|
||||
return false;
|
||||
}
|
||||
virtual bool guiCreate(const char *api, bool isFloating) noexcept { return false; }
|
||||
virtual void guiDestroy() noexcept {}
|
||||
virtual bool guiSetScale(double scale) noexcept { return false; }
|
||||
virtual bool guiShow() noexcept { return false; }
|
||||
virtual bool guiHide() noexcept { return false; }
|
||||
virtual bool guiGetSize(uint32_t *width, uint32_t *height) noexcept { return false; }
|
||||
virtual bool guiCanResize() const noexcept { return false; }
|
||||
virtual bool guiGetResizeHints(clap_gui_resize_hints_t *hints) noexcept { return false; }
|
||||
virtual bool guiAdjustSize(uint32_t *width, uint32_t *height) noexcept {
|
||||
return guiGetSize(width, height);
|
||||
}
|
||||
virtual bool guiSetSize(uint32_t width, uint32_t height) noexcept { return false; }
|
||||
virtual void guiSuggestTitle(const char *title) noexcept {}
|
||||
virtual bool guiSetParent(const clap_window *window) noexcept { return false; }
|
||||
virtual bool guiSetTransient(const clap_window *window) noexcept { return false; }
|
||||
|
||||
//------------------------//
|
||||
// clap_plugin_voice_info //
|
||||
//------------------------//
|
||||
virtual bool implementsVoiceInfo() const noexcept { return false; }
|
||||
virtual bool voiceInfoGet(clap_voice_info *info) noexcept { return false; }
|
||||
|
||||
/////////////
|
||||
// Logging //
|
||||
/////////////
|
||||
void log(clap_log_severity severity, const char *msg) const noexcept;
|
||||
void hostMisbehaving(const char *msg) const noexcept;
|
||||
void hostMisbehaving(const std::string &msg) const noexcept { hostMisbehaving(msg.c_str()); }
|
||||
|
||||
// Receives a copy of all the logging messages sent to the host.
|
||||
// This is useful to have the messages in both the host's logs and the plugin's logs.
|
||||
virtual void logTee(clap_log_severity severity, const char *msg) const noexcept {}
|
||||
|
||||
/////////////////////
|
||||
// Thread Checking //
|
||||
/////////////////////
|
||||
void checkMainThread() const noexcept;
|
||||
void checkAudioThread() const noexcept;
|
||||
void checkParamThread() const noexcept;
|
||||
void ensureMainThread(const char *method) const noexcept;
|
||||
void ensureAudioThread(const char *method) const noexcept;
|
||||
void ensureParamThread(const char *method) const noexcept;
|
||||
|
||||
///////////////
|
||||
// Utilities //
|
||||
///////////////
|
||||
static Plugin &from(const clap_plugin *plugin, bool requireInitialized = true) noexcept;
|
||||
|
||||
// runs the callback immediately if on the main thread, otherwise queue it.
|
||||
// be aware that the callback may be ran during the plugin destruction phase,
|
||||
// so check isBeingDestroyed() and ajust your code.
|
||||
void runOnMainThread(std::function<void()> callback);
|
||||
|
||||
// This actually runs callbacks on the main thread, you should not need to call it
|
||||
void runCallbacksOnMainThread();
|
||||
|
||||
template <typename T>
|
||||
void initInterface(const T *&ptr, const char *id) noexcept;
|
||||
void initInterfaces() noexcept;
|
||||
|
||||
static uint32_t compareAudioPortsInfo(const clap_audio_port_info &a,
|
||||
const clap_audio_port_info &b) noexcept;
|
||||
|
||||
//////////////////////
|
||||
// Processing State //
|
||||
//////////////////////
|
||||
bool isActive() const noexcept { return _isActive; }
|
||||
bool isProcessing() const noexcept { return _isProcessing; }
|
||||
int sampleRate() const noexcept {
|
||||
assert(_isActive && "sample rate is only known if the plugin is active");
|
||||
assert(_sampleRate > 0);
|
||||
return _sampleRate;
|
||||
}
|
||||
|
||||
bool isBeingDestroyed() const noexcept { return _isBeingDestroyed; }
|
||||
|
||||
protected:
|
||||
HostProxy<h, l> _host;
|
||||
|
||||
private:
|
||||
/////////////////////
|
||||
// CLAP Interfaces //
|
||||
/////////////////////
|
||||
|
||||
clap_plugin _plugin;
|
||||
// clap_plugin
|
||||
static bool clapInit(const clap_plugin *plugin) noexcept;
|
||||
static void clapDestroy(const clap_plugin *plugin) noexcept;
|
||||
static bool clapActivate(const clap_plugin *plugin,
|
||||
double sample_rate,
|
||||
uint32_t minFrameCount,
|
||||
uint32_t maxFrameCount) noexcept;
|
||||
static void clapDeactivate(const clap_plugin *plugin) noexcept;
|
||||
static bool clapStartProcessing(const clap_plugin *plugin) noexcept;
|
||||
static void clapStopProcessing(const clap_plugin *plugin) noexcept;
|
||||
static void clapReset(const clap_plugin *plugin) noexcept;
|
||||
static clap_process_status clapProcess(const clap_plugin *plugin,
|
||||
const clap_process *process) noexcept;
|
||||
static void clapOnMainThread(const clap_plugin *plugin) noexcept;
|
||||
static const void *clapExtension(const clap_plugin *plugin, const char *id) noexcept;
|
||||
|
||||
// latency
|
||||
static uint32_t clapLatencyGet(const clap_plugin *plugin) noexcept;
|
||||
|
||||
// clap_plugin_tail
|
||||
static uint32_t clapTailGet(const clap_plugin_t *plugin) noexcept;
|
||||
|
||||
// clap_plugin_render
|
||||
static bool clapRenderHasHardRealtimeRequirement(const clap_plugin_t *plugin) noexcept;
|
||||
static bool clapRenderSetMode(const clap_plugin *plugin,
|
||||
clap_plugin_render_mode mode) noexcept;
|
||||
|
||||
// clap_plugin_thread_pool
|
||||
static void clapThreadPoolExec(const clap_plugin *plugin, uint32_t task_index) noexcept;
|
||||
|
||||
// clap_plugin_state
|
||||
static bool clapStateSave(const clap_plugin *plugin, const clap_ostream *stream) noexcept;
|
||||
static bool clapStateLoad(const clap_plugin *plugin, const clap_istream *stream) noexcept;
|
||||
|
||||
// clap_plugin_preset
|
||||
static bool clapPresetLoadFromFile(const clap_plugin *plugin, const char *path) noexcept;
|
||||
|
||||
// clap_plugin_track_info
|
||||
static void clapTrackInfoChanged(const clap_plugin *plugin) noexcept;
|
||||
|
||||
// clap_plugin_audio_ports
|
||||
static uint32_t clapAudioPortsCount(const clap_plugin *plugin, bool is_input) noexcept;
|
||||
static bool clapAudioPortsInfo(const clap_plugin *plugin,
|
||||
uint32_t index,
|
||||
bool is_input,
|
||||
clap_audio_port_info *info) noexcept;
|
||||
static uint32_t clapAudioPortsConfigCount(const clap_plugin *plugin) noexcept;
|
||||
static bool clapAudioPortsGetConfig(const clap_plugin *plugin,
|
||||
uint32_t index,
|
||||
clap_audio_ports_config *config) noexcept;
|
||||
static bool clapAudioPortsSetConfig(const clap_plugin *plugin, clap_id config_id) noexcept;
|
||||
|
||||
// clap_plugin_params
|
||||
static uint32_t clapParamsCount(const clap_plugin *plugin) noexcept;
|
||||
static bool clapParamsInfo(const clap_plugin *plugin,
|
||||
uint32_t param_index,
|
||||
clap_param_info *param_info) noexcept;
|
||||
static bool
|
||||
clapParamsValue(const clap_plugin *plugin, clap_id param_id, double *value) noexcept;
|
||||
static bool clapParamsValueToText(const clap_plugin *plugin,
|
||||
clap_id param_id,
|
||||
double value,
|
||||
char *display,
|
||||
uint32_t size) noexcept;
|
||||
static bool clapParamsTextToValue(const clap_plugin *plugin,
|
||||
clap_id param_id,
|
||||
const char *display,
|
||||
double *value) noexcept;
|
||||
static void clapParamsFlush(const clap_plugin *plugin,
|
||||
const clap_input_events *in,
|
||||
const clap_output_events *out) noexcept;
|
||||
|
||||
// clap_plugin_quick_controls
|
||||
static uint32_t clapQuickControlsPageCount(const clap_plugin *plugin) noexcept;
|
||||
static bool clapQuickControlsPageGet(const clap_plugin *plugin,
|
||||
uint32_t page_index,
|
||||
clap_quick_controls_page *page) noexcept;
|
||||
|
||||
// clap_plugin_note_port
|
||||
static uint32_t clapNotePortsCount(const clap_plugin *plugin, bool is_input) noexcept;
|
||||
static bool clapNotePortsInfo(const clap_plugin *plugin,
|
||||
uint32_t index,
|
||||
bool is_input,
|
||||
clap_note_port_info *info) noexcept;
|
||||
|
||||
// clap_plugin_note_name
|
||||
static uint32_t clapNoteNameCount(const clap_plugin *plugin) noexcept;
|
||||
static bool clapNoteNameGet(const clap_plugin *plugin,
|
||||
uint32_t index,
|
||||
clap_note_name *note_name) noexcept;
|
||||
|
||||
// clap_plugin_timer_support
|
||||
static void clapOnTimer(const clap_plugin *plugin, clap_id timer_id) noexcept;
|
||||
|
||||
// clap_plugin_fd_support
|
||||
static void
|
||||
clapOnPosixFd(const clap_plugin *plugin, int fd, clap_posix_fd_flags_t flags) noexcept;
|
||||
|
||||
// clap_plugin_gui
|
||||
static bool
|
||||
clapGuiIsApiSupported(const clap_plugin *plugin, const char *api, bool isFloating) noexcept;
|
||||
static bool clapGuiGetPreferredApi(const clap_plugin_t *plugin,
|
||||
const char **api,
|
||||
bool *is_floating) noexcept;
|
||||
static bool
|
||||
clapGuiCreate(const clap_plugin *plugin, const char *api, bool isFloating) noexcept;
|
||||
static void clapGuiDestroy(const clap_plugin *plugin) noexcept;
|
||||
static bool clapGuiSetScale(const clap_plugin *plugin, double scale) noexcept;
|
||||
static bool
|
||||
clapGuiGetSize(const clap_plugin *plugin, uint32_t *width, uint32_t *height) noexcept;
|
||||
static bool
|
||||
clapGuiSetSize(const clap_plugin *plugin, uint32_t width, uint32_t height) noexcept;
|
||||
static bool clapGuiCanResize(const clap_plugin *plugin) noexcept;
|
||||
static bool clapGuiGetResizeHints(const clap_plugin_t *plugin,
|
||||
clap_gui_resize_hints_t *hints) noexcept;
|
||||
static bool
|
||||
clapGuiAdjustSize(const clap_plugin *plugin, uint32_t *width, uint32_t *height) noexcept;
|
||||
static bool clapGuiShow(const clap_plugin *plugin) noexcept;
|
||||
static bool clapGuiHide(const clap_plugin *plugin) noexcept;
|
||||
static bool clapGuiSetParent(const clap_plugin *plugin, const clap_window *window) noexcept;
|
||||
static bool clapGuiSetTransient(const clap_plugin *plugin,
|
||||
const clap_window *window) noexcept;
|
||||
|
||||
static void clapGuiSuggestTitle(const clap_plugin *plugin, const char *title) noexcept;
|
||||
|
||||
static bool clapVoiceInfoGet(const clap_plugin *plugin, clap_voice_info *info) noexcept;
|
||||
|
||||
// interfaces
|
||||
static const clap_plugin_render _pluginRender;
|
||||
static const clap_plugin_thread_pool _pluginThreadPool;
|
||||
static const clap_plugin_state _pluginState;
|
||||
static const clap_plugin_preset_load _pluginPresetLoad;
|
||||
static const clap_plugin_track_info _pluginTrackInfo;
|
||||
static const clap_plugin_audio_ports _pluginAudioPorts;
|
||||
static const clap_plugin_audio_ports_config _pluginAudioPortsConfig;
|
||||
static const clap_plugin_params _pluginParams;
|
||||
static const clap_plugin_quick_controls _pluginQuickControls;
|
||||
static const clap_plugin_latency _pluginLatency;
|
||||
static const clap_plugin_note_ports _pluginNotePorts;
|
||||
static const clap_plugin_note_name _pluginNoteName;
|
||||
static const clap_plugin_timer_support _pluginTimerSupport;
|
||||
static const clap_plugin_posix_fd_support _pluginPosixFdSupport;
|
||||
static const clap_plugin_gui _pluginGui;
|
||||
static const clap_plugin_voice_info _pluginVoiceInfo;
|
||||
static const clap_plugin_tail _pluginTail;
|
||||
|
||||
// state
|
||||
bool _wasInitialized = false;
|
||||
bool _isActive = false;
|
||||
bool _isProcessing = false;
|
||||
bool _isBeingDestroyed = false;
|
||||
double _sampleRate = 0;
|
||||
|
||||
std::string _guiApi;
|
||||
bool _isGuiCreated = false;
|
||||
bool _isGuiFloating = false;
|
||||
bool _isGuiEmbedded = false;
|
||||
|
||||
std::mutex _mainThredCallbacksLock;
|
||||
std::queue<std::function<void()>> _mainThredCallbacks;
|
||||
};
|
||||
}} // namespace clap::helpers
|
1409
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/plugin.hxx
vendored
Normal file
1409
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/plugin.hxx
vendored
Normal file
File diff suppressed because it is too large
Load Diff
48
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/reducing-param-queue.hh
vendored
Normal file
48
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/reducing-param-queue.hh
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <clap/private/macros.h>
|
||||
|
||||
namespace clap { namespace helpers {
|
||||
|
||||
#ifdef CLAP_HAS_CXX20
|
||||
template <typename T>
|
||||
concept UpdatableValue = requires(T &a, const T &b) {
|
||||
// update a with b, b being newer than a
|
||||
{ a.update(b) };
|
||||
};
|
||||
#endif
|
||||
|
||||
// TODO: when switching to C++20
|
||||
// template <typename K, UpdatableValue V>
|
||||
template <typename K, typename V>
|
||||
class ReducingParamQueue {
|
||||
public:
|
||||
using key_type = K;
|
||||
using value_type = V;
|
||||
using queue_type = std::unordered_map<key_type, value_type>;
|
||||
using consumer_type = const std::function<void(const key_type &key, const value_type &value)>;
|
||||
|
||||
ReducingParamQueue();
|
||||
|
||||
void setCapacity(size_t capacity);
|
||||
|
||||
void set(const key_type &key, const value_type &value);
|
||||
void setOrUpdate(const key_type &key, const value_type &value);
|
||||
void producerDone();
|
||||
|
||||
void consume(const consumer_type &consumer);
|
||||
|
||||
void reset();
|
||||
|
||||
private:
|
||||
queue_type _queues[2];
|
||||
std::atomic<queue_type *> _free = nullptr;
|
||||
std::atomic<queue_type *> _producer = nullptr;
|
||||
std::atomic<queue_type *> _consumer = nullptr;
|
||||
};
|
||||
}} // namespace clap::helpers
|
72
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/reducing-param-queue.hxx
vendored
Normal file
72
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/reducing-param-queue.hxx
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "reducing-param-queue.hh"
|
||||
|
||||
namespace clap { namespace helpers {
|
||||
template <typename K, typename V>
|
||||
ReducingParamQueue<K, V>::ReducingParamQueue() {
|
||||
reset();
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
void ReducingParamQueue<K, V>::reset() {
|
||||
for (auto &q : _queues)
|
||||
q.clear();
|
||||
|
||||
_free = &_queues[0];
|
||||
_producer = &_queues[1];
|
||||
_consumer = nullptr;
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
void ReducingParamQueue<K, V>::setCapacity(size_t capacity) {
|
||||
for (auto &q : _queues)
|
||||
q.reserve(2 * capacity);
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
void ReducingParamQueue<K, V>::set(const key_type &key, const value_type &value) {
|
||||
_producer.load()->insert_or_assign(key, value);
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
void ReducingParamQueue<K, V>::setOrUpdate(const key_type &key, const value_type &value) {
|
||||
auto prod = _producer.load();
|
||||
auto res = prod->insert({key, value});
|
||||
if (!res.second && res.first != prod->end())
|
||||
res.first->second.update(value);
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
void ReducingParamQueue<K, V>::producerDone() {
|
||||
if (_consumer)
|
||||
return;
|
||||
|
||||
auto tmp = _producer.load();
|
||||
_producer = _free.load();
|
||||
_free = nullptr;
|
||||
_consumer = tmp;
|
||||
|
||||
assert(_producer);
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
void ReducingParamQueue<K, V>::consume(const consumer_type &consumer) {
|
||||
assert(consumer);
|
||||
|
||||
if (!_consumer)
|
||||
return;
|
||||
|
||||
for (auto &x : *_consumer)
|
||||
consumer(x.first, x.second);
|
||||
|
||||
_consumer.load()->clear();
|
||||
if (_free)
|
||||
return;
|
||||
|
||||
_free = _consumer.load();
|
||||
_consumer = nullptr;
|
||||
}
|
||||
}} // namespace clap::helpers
|
2
deps/clap-juce-extensions/clap-libs/clap-helpers/tests/main.cc
vendored
Normal file
2
deps/clap-juce-extensions/clap-libs/clap-helpers/tests/main.cc
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include <catch2/catch.hpp>
|
18
deps/clap-juce-extensions/clap-libs/clap-helpers/tests/plugin.cc
vendored
Normal file
18
deps/clap-juce-extensions/clap-libs/clap-helpers/tests/plugin.cc
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
#include <clap/helpers/param-queue.hh>
|
||||
#include <clap/helpers/plugin.hh>
|
||||
#include <clap/helpers/plugin.hxx>
|
||||
#include <clap/helpers/reducing-param-queue.hh>
|
||||
#include <clap/helpers/reducing-param-queue.hxx>
|
||||
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
CATCH_TEST_CASE("Plugin - Link") {
|
||||
clap::helpers::Plugin<clap::helpers::MisbehaviourHandler::Terminate,
|
||||
clap::helpers::CheckingLevel::Maximal> *p0 = nullptr;
|
||||
clap::helpers::Plugin<clap::helpers::MisbehaviourHandler::Terminate,
|
||||
clap::helpers::CheckingLevel::Minimal> *p1 = nullptr;
|
||||
clap::helpers::Plugin<clap::helpers::MisbehaviourHandler::Terminate,
|
||||
clap::helpers::CheckingLevel::None> *p2 = nullptr;
|
||||
clap::helpers::Plugin<clap::helpers::MisbehaviourHandler::Ignore,
|
||||
clap::helpers::CheckingLevel::Maximal> *p3 = nullptr;
|
||||
}
|
Loading…
Reference in New Issue
Block a user