migrating to the latest JUCE version
@ -1,19 +1,19 @@
|
||||
---
|
||||
Language: Cpp
|
||||
AccessModifierOffset: -3
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveMacros: true
|
||||
AlignConsecutiveMacros: false
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlines: Right
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: true
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
AllowAllArgumentsOnNextLine: false
|
||||
AllowAllConstructorInitializersOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
@ -24,7 +24,7 @@ AlwaysBreakTemplateDeclarations: Yes
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterCaseLabel: true
|
||||
AfterClass: true
|
||||
AfterControlStatement: true
|
||||
AfterEnum: true
|
||||
@ -32,7 +32,7 @@ BraceWrapping:
|
||||
AfterNamespace: true
|
||||
AfterObjCDeclaration: true
|
||||
AfterStruct: true
|
||||
AfterUnion: true
|
||||
AfterUnion: false
|
||||
AfterExternBlock: true
|
||||
BeforeCatch: true
|
||||
BeforeElse: true
|
||||
@ -41,7 +41,7 @@ BraceWrapping:
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Attach
|
||||
BreakBeforeBraces: Custom
|
||||
BreakBeforeInheritanceComma: false
|
||||
BreakInheritanceList: BeforeColon
|
||||
BreakBeforeTernaryOperators: true
|
||||
@ -49,14 +49,14 @@ BreakConstructorInitializersBeforeComma: false
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 100
|
||||
ColumnLimit: 120
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
CompactNamespaces: true
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 3
|
||||
ContinuationIndentWidth: 3
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DeriveLineEnding: false
|
||||
DeriveLineEnding: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
@ -80,18 +80,18 @@ IncludeIsMainRegex: '(Test)?$'
|
||||
IncludeIsMainSourceRegex: ''
|
||||
IndentCaseLabels: false
|
||||
IndentGotoLabels: true
|
||||
IndentPPDirectives: AfterHash
|
||||
IndentWidth: 3
|
||||
IndentPPDirectives: None
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: All
|
||||
MaxEmptyLinesToKeep: 2
|
||||
NamespaceIndentation: None
|
||||
ObjCBinPackProtocolList: Auto
|
||||
ObjCBlockIndentWidth: 3
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakAssignment: 2
|
||||
@ -101,9 +101,9 @@ PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PenaltyReturnTypeOnItsOwnLine: 1000
|
||||
PointerAlignment: Right
|
||||
ReflowComments: true
|
||||
ReflowComments: false
|
||||
SortIncludes: true
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: false
|
||||
@ -129,8 +129,7 @@ Standard: Latest
|
||||
StatementMacros:
|
||||
- Q_UNUSED
|
||||
- QT_REQUIRE_VERSION
|
||||
TabWidth: 8
|
||||
TabWidth: 4
|
||||
UseCRLF: false
|
||||
UseTab: Never
|
||||
...
|
||||
|
18
.clang-tidy
Normal file
@ -0,0 +1,18 @@
|
||||
---
|
||||
Checks: '
|
||||
bugprone-*,
|
||||
clang-analyzer-*,
|
||||
clang-cppcoreguidelines-*,
|
||||
clang-modernize-*,
|
||||
performance-*,
|
||||
-cppcoreguidelines-avoid-magic-numbers,
|
||||
-cppcoreguidelines-macro-usage,
|
||||
-cppcoreguidelines-owning-memory,
|
||||
-bugprone-exception-escape,
|
||||
-bugprone-branch-clone
|
||||
'
|
||||
WarningsAsErrors: '*'
|
||||
HeaderFilterRegex: '.*'
|
||||
AnalyzeTemporaryDtors: false
|
||||
FormatStyle: none
|
||||
...
|
17
.editorconfig
Normal file
@ -0,0 +1,17 @@
|
||||
# EditorConfig is awesome: http://EditorConfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
end_of_line = lf
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
trim_trailing_whitespace = false
|
12
.gitattributes
vendored
@ -1,3 +1,11 @@
|
||||
* text=auto
|
||||
# Set the default behavior for all files.
|
||||
* text=auto eol=lf
|
||||
|
||||
*.sh text eol=lf
|
||||
# Normalized and converts to native line endings on checkout.
|
||||
*.c text
|
||||
*.cc text
|
||||
*.cxx
|
||||
*.cpp text
|
||||
*.h text
|
||||
*.hxx text
|
||||
*.hpp text
|
||||
|
147
.gitignore
vendored
Normal file
@ -0,0 +1,147 @@
|
||||
################################
|
||||
########### FILES ############
|
||||
################################
|
||||
TODO*.*
|
||||
*.pptx
|
||||
*.pdf
|
||||
|
||||
################################
|
||||
########### FOLDERS ############
|
||||
################################
|
||||
build/
|
||||
html/
|
||||
lectures/
|
||||
|
||||
################################
|
||||
############ C/C++ #############
|
||||
################################
|
||||
# Prerequisites
|
||||
*.d
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
*.ko
|
||||
*.elf
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
# Executables
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
*.app
|
||||
*.stackdump
|
||||
*.exe
|
||||
*.out
|
||||
# Linker output
|
||||
*.ilk
|
||||
*.map
|
||||
*.exp
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
*.idb
|
||||
*.pdb
|
||||
|
||||
################################
|
||||
########### VS CODE ############
|
||||
################################
|
||||
.vscode
|
||||
*.code-workspace
|
||||
.history
|
||||
|
||||
################################
|
||||
########### VS ############
|
||||
################################
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Ww][Ii][Nn]32/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.meta
|
||||
*.iobj
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.tlog
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
6
.gitmodules
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
[submodule "deps/clap-juce-extensions"]
|
||||
path = deps/clap-juce-extensions
|
||||
url = https://github.com/free-audio/clap-juce-extensions.git
|
||||
[submodule "deps/juce"]
|
||||
path = deps/juce
|
||||
url = https://github.com/juce-framework/JUCE.git
|
2
Dockerfile.arch
Normal file
@ -0,0 +1,2 @@
|
||||
FROM archlinux
|
||||
RUN pacman -Syu base-devel alsa-lib cmake fftw freetype2 jack libx11 libxcursor libxinerama libxrandr vst3-host clap-host --noconfirm
|
@ -208,7 +208,7 @@ Rectangle<int> CustomLookAndFeel::getTabButtonExtraComponentBounds (const TabBar
|
||||
default: jassertfalse; break;
|
||||
}
|
||||
}
|
||||
else if (button.getExtraComponentPlacement() == TabBarButton::aboveText)
|
||||
else if (button.getExtraComponentPlacement() == TabBarButton::beforeText)
|
||||
{
|
||||
switch (orientation)
|
||||
{
|
||||
@ -224,7 +224,7 @@ Rectangle<int> CustomLookAndFeel::getTabButtonExtraComponentBounds (const TabBar
|
||||
//DBG("After Extra comp bounds: " << extraComp.toString())
|
||||
|
||||
}
|
||||
else if (button.getExtraComponentPlacement() == TabBarButton::belowText)
|
||||
else if (button.getExtraComponentPlacement() == TabBarButton::afterText)
|
||||
{
|
||||
switch (orientation)
|
||||
{
|
||||
@ -1182,9 +1182,9 @@ void CustomLookAndFeel::drawDrawableButton (Graphics& g, DrawableButton& button,
|
||||
// imageratio = sonobutt->getForegroundImageRatio();
|
||||
//}
|
||||
|
||||
if (button.getStyle() == DrawableButton::ImageAboveTextLabel || button.getStyle() == DrawableButton::ImageBelowTextLabel) {
|
||||
if (button.getStyle() == DrawableButton::ImageAboveTextLabel || button.getStyle() == DrawableButton::ImageAboveTextLabel) {
|
||||
textH = jmin (14, button.proportionOfHeight (0.2f));
|
||||
} else if (button.getStyle() == DrawableButton::ImageLeftOfTextLabel || button.getStyle() == DrawableButton::ImageRightOfTextLabel) {
|
||||
} else if (button.getStyle() == DrawableButton::ImageAboveTextLabel || button.getStyle() == DrawableButton::ImageAboveTextLabel) {
|
||||
textH = jmin (14, button.proportionOfHeight (0.8f));
|
||||
textW = jmax (20, button.proportionOfWidth (1.0f - imageratio));
|
||||
}
|
||||
@ -1205,19 +1205,19 @@ void CustomLookAndFeel::drawDrawableButton (Graphics& g, DrawableButton& button,
|
||||
button.getWidth() - 4, textH,
|
||||
Justification::centred, 1);
|
||||
}
|
||||
else if (button.getStyle() == DrawableButton::ImageBelowTextLabel) {
|
||||
else if (button.getStyle() == DrawableButton::ImageAboveTextLabel) {
|
||||
g.drawFittedText (button.getButtonText(),
|
||||
2, 1,
|
||||
button.getWidth() - 4, textH,
|
||||
Justification::centred, 1);
|
||||
}
|
||||
else if (button.getStyle() == DrawableButton::ImageRightOfTextLabel) {
|
||||
else if (button.getStyle() == DrawableButton::ImageAboveTextLabel) {
|
||||
g.drawFittedText (button.getButtonText(),
|
||||
2, 1,
|
||||
textW , button.getHeight() - 2,
|
||||
Justification::centred, 2, 0.6f);
|
||||
}
|
||||
else if (button.getStyle() == DrawableButton::ImageLeftOfTextLabel) {
|
||||
else if (button.getStyle() == DrawableButton::ImageAboveTextLabel) {
|
||||
g.drawFittedText (button.getButtonText(),
|
||||
button.getWidth() - textW - 4 , 1,
|
||||
textW , button.getHeight() - 2,
|
||||
|
@ -7,7 +7,6 @@
|
||||
|
||||
#include "juce_audio_plugin_client/utility/juce_IncludeSystemHeaders.h"
|
||||
#include "juce_audio_plugin_client/utility/juce_IncludeModuleHeaders.h"
|
||||
#include "juce_audio_plugin_client/utility/juce_FakeMouseMoveGenerator.h"
|
||||
#include "juce_audio_plugin_client/utility/juce_WindowsHooks.h"
|
||||
|
||||
#include <juce_audio_devices/juce_audio_devices.h>
|
||||
@ -63,7 +62,7 @@ public:
|
||||
|
||||
}
|
||||
|
||||
void urlOpened(const URL& url) override {
|
||||
void urlOpened(const URL& url) {
|
||||
|
||||
DBG("URL opened: " << url.toString(false));
|
||||
if (mainWindow.get() != nullptr)
|
||||
|
@ -98,7 +98,6 @@ GenericItemChooser::GenericItemChooser(const Array<GenericItemChooserItem> & ite
|
||||
table.getViewport()->setScrollBarsShown(true, false);
|
||||
table.getViewport()->setScrollOnDragEnabled(true);
|
||||
table.setRowSelectedOnMouseDown(true);
|
||||
table.setRowClickedOnMouseDown(false);
|
||||
table.setMultipleSelectionEnabled (false);
|
||||
table.setRowHeight(rowHeight);
|
||||
|
||||
|
@ -573,7 +573,7 @@ void PaulstretchpluginAudioProcessorEditor::showRenderDialog()
|
||||
int prefh = jmin(contentraw->getPreferredHeight(), getHeight() - 10);
|
||||
contentraw->setSize(prefw, prefh);
|
||||
std::unique_ptr<Component> content(contentraw);
|
||||
auto & cb = CallOutBox::launchAsynchronously(std::move(content), m_render_button.getBounds(), this, false);
|
||||
auto & cb = CallOutBox::launchAsynchronously(std::move(content), m_render_button.getBounds(), this);
|
||||
cb.setDismissalMouseClicksAreAlwaysConsumed(true);
|
||||
}
|
||||
|
||||
@ -635,7 +635,7 @@ void PaulstretchpluginAudioProcessorEditor::showSettings(bool flag)
|
||||
|
||||
Rectangle<int> bounds = dw->getLocalArea(nullptr, m_settings_button.getScreenBounds().reduced(10));
|
||||
DBG("callout bounds: " << bounds.toString());
|
||||
settingsCalloutBox = & CallOutBox::launchAsynchronously (std::move(wrap), bounds , dw, false);
|
||||
settingsCalloutBox = & CallOutBox::launchAsynchronously(std::move(wrap), bounds , dw);
|
||||
if (CallOutBox * box = dynamic_cast<CallOutBox*>(settingsCalloutBox.get())) {
|
||||
box->setDismissalMouseClicksAreAlwaysConsumed(true);
|
||||
}
|
||||
|
4
build_docker.sh
Normal file
@ -0,0 +1,4 @@
|
||||
# docker build -t paulxstretch_builder -f Dockerfile.arch .
|
||||
mkdir -p ./build
|
||||
docker run -v $PWD:/src -v $PWD/build:/build paulxstretch_builder cmake -B build -S /src -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -Wno-dev
|
||||
docker run -v $PWD:/src -v $PWD/build:/build paulxstretch_builder cmake --build build
|
70
deps/clap-juce-extensions/.github/workflows/build-cmake.yml
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
name: CI-CMake
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build_and_test:
|
||||
name: Build example plugins with CMake and JUCE ${{ matrix.juce_version }} on ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false # show all errors for each platform (vs. cancel jobs on error)
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-2019, macOS-latest]
|
||||
juce_version: ["6.0.7", "6.1.5", "6.1.6", "7.0.0"]
|
||||
|
||||
steps:
|
||||
- name: Install Linux Deps
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt install libasound2-dev libx11-dev libxcomposite-dev libxcursor-dev libxext-dev libxinerama-dev libxrandr-dev libxrender-dev libfreetype6-dev libglu1-mesa-dev libjack-jackd2-dev
|
||||
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 9
|
||||
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-9 9
|
||||
|
||||
- name: Get latest CMake
|
||||
uses: lukka/get-cmake@latest
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Configure
|
||||
shell: bash
|
||||
run: cmake -Bbuild -DCMAKE_BUILD_TYPE=Release -DCLAP_JUCE_VERSION=$JUCE_VERSION -DCLAP_EXAMPLES_TREAT_WARNINGS_AS_ERRORS=ON
|
||||
env:
|
||||
JUCE_VERSION: ${{ matrix.juce_version }}
|
||||
|
||||
- name: Build
|
||||
shell: bash
|
||||
run: cmake --build build --config Release --parallel 4 --target GainPlugin_CLAP
|
||||
|
||||
- name: Set up clap-info
|
||||
shell: bash
|
||||
run: |
|
||||
git clone --recurse-submodules https://github.com/surge-synthesizer/clap-info
|
||||
cd clap-info
|
||||
cmake -Bbuild -DCMAKE_BUILD_TYPE=Release
|
||||
cmake --build build --config Release --parallel 4
|
||||
|
||||
- name: Run clap-info (Max/Linux)
|
||||
if: runner.os == 'Linux' || runner.os == 'MacOS'
|
||||
shell: bash
|
||||
run: |
|
||||
clap-info/build/clap-info --version
|
||||
clap-info/build/clap-info build/examples/GainPlugin/GainPlugin_artefacts/Release/CLAP/GainPlugin.clap
|
||||
|
||||
- name: Run clap-info (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
shell: bash
|
||||
run: |
|
||||
clap-info/build/Release/clap-info --version
|
||||
clap-info/build/Release/clap-info build/examples/GainPlugin/GainPlugin_artefacts/Release/CLAP/GainPlugin.clap
|
132
deps/clap-juce-extensions/.github/workflows/build-projucer.yml
vendored
Normal file
@ -0,0 +1,132 @@
|
||||
name: CI-Projucer
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build_and_test:
|
||||
name: Build example plugins with Projucer on ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false # show all errors for each platform (vs. cancel jobs on error)
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
jucer: build/_deps/juce-src/extras/Projucer/Builds/LinuxMakefile/build/Projucer
|
||||
clap_gen: "Unix Makefiles"
|
||||
- os: macos-latest
|
||||
jucer: build/_deps/juce-src/extras/Projucer/Builds/MacOSX/build/Debug/Projucer.app/Contents/MacOS/Projucer
|
||||
clap_gen: "Xcode"
|
||||
- os: windows-2019
|
||||
jucer: build/_deps/juce-src/extras/Projucer/Builds/VisualStudio2019/x64/Debug/App/Projucer.exe
|
||||
clap_gen: "Visual Studio 16 2019"
|
||||
|
||||
steps:
|
||||
- name: Install Linux Deps
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt install libasound2-dev libcurl4-openssl-dev libx11-dev libxinerama-dev libxext-dev libfreetype6-dev libwebkit2gtk-4.0-dev libglu1-mesa-dev libjack-jackd2-dev
|
||||
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 9
|
||||
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-9 9
|
||||
|
||||
- name: Add msbuild to PATH
|
||||
if: runner.os == 'Windows'
|
||||
uses: microsoft/setup-msbuild@v1.0.3
|
||||
|
||||
- name: Set up Xcode
|
||||
if: runner.os == 'MacOS'
|
||||
uses: maxim-lobanov/setup-xcode@v1
|
||||
with:
|
||||
xcode-version: latest-stable
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Install JUCE
|
||||
shell: bash
|
||||
run: git clone --depth 1 --branch 6.1.5 https://github.com/juce-framework/JUCE build/_deps/juce-src
|
||||
|
||||
- name: Build Projucer (MacOS)
|
||||
if: runner.os == 'MacOS'
|
||||
shell: bash
|
||||
run: xcodebuild -project Projucer.xcodeproj -jobs 4 | xcpretty
|
||||
working-directory: build/_deps/juce-src/extras/Projucer/Builds/MacOSX
|
||||
|
||||
- name: Build Projucer (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
shell: bash
|
||||
run: msbuild.exe -v:normal -m:4 Projucer.sln
|
||||
working-directory: build/_deps/juce-src/extras/Projucer/Builds/VisualStudio2019
|
||||
|
||||
- name: Build Projucer (Linux)
|
||||
if: runner.os == 'Linux'
|
||||
shell: bash
|
||||
run: make -j4
|
||||
working-directory: build/_deps/juce-src/extras/Projucer/Builds/LinuxMakefile
|
||||
|
||||
- name: Resave jucer
|
||||
shell: bash
|
||||
run: $PROJUCER --resave examples/GainPlugin/GainPlugin.jucer
|
||||
env:
|
||||
PROJUCER: ${{ matrix.jucer }}
|
||||
|
||||
- name: Build Plugin (MacOS)
|
||||
if: runner.os == 'MacOS'
|
||||
shell: bash
|
||||
run: xcodebuild -project GainPlugin.xcodeproj -jobs 4 | xcpretty
|
||||
working-directory: examples/GainPlugin/Builds/MacOSX
|
||||
|
||||
- name: Build Plugin (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
shell: bash
|
||||
run: msbuild.exe -v:normal -m:4 GainPlugin.sln
|
||||
working-directory: examples/GainPlugin/Builds/VisualStudio2019
|
||||
|
||||
- name: Build Plugin (Linux)
|
||||
if: runner.os == 'Linux'
|
||||
shell: bash
|
||||
run: make -j4
|
||||
working-directory: examples/GainPlugin/Builds/LinuxMakefile
|
||||
|
||||
- name: Get latest CMake
|
||||
uses: lukka/get-cmake@latest
|
||||
|
||||
- name: Build CLAP
|
||||
shell: bash
|
||||
run: |
|
||||
cmake -Bbuild-clap -G"$CLAP_GEN" -DCMAKE_BUILD_TYPE=Debug -DCLAP_WRAP_PROJUCER_PLUGIN=ON
|
||||
cmake --build build-clap --config Debug --target GainPlugin_CLAP
|
||||
env:
|
||||
CLAP_GEN: ${{ matrix.clap_gen }}
|
||||
|
||||
- name: Set up clap-info
|
||||
shell: bash
|
||||
run: |
|
||||
git clone --recurse-submodules https://github.com/surge-synthesizer/clap-info
|
||||
cd clap-info
|
||||
cmake -Bbuild -DCMAKE_BUILD_TYPE=Release
|
||||
cmake --build build --config Release --parallel 4
|
||||
|
||||
- name: Run clap-info (Max/Linux)
|
||||
if: runner.os == 'MacOS' || runner.os == 'Linux'
|
||||
shell: bash
|
||||
run: |
|
||||
clap-info/build/clap-info --version
|
||||
clap-info/build/clap-info build-clap/examples/GainPlugin/GainPlugin_artefacts/Debug/MyGreatGainPlugin.clap
|
||||
|
||||
- name: Run clap-info (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
shell: bash
|
||||
run: |
|
||||
clap-info/build/Release/clap-info --version
|
||||
clap-info/build/Release/clap-info build-clap/examples/GainPlugin/GainPlugin_artefacts/Debug/MyGreatGainPlugin.clap
|
8
deps/clap-juce-extensions/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
build*/
|
||||
Builds/
|
||||
JuceLibraryCode/
|
||||
|
||||
.vscode/
|
||||
.idea/
|
||||
|
||||
.DS_Store
|
12
deps/clap-juce-extensions/.gitrepo
vendored
@ -1,12 +0,0 @@
|
||||
; 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-juce-extensions
|
||||
branch = main
|
||||
commit = 6489846d05a3bc0b743c5c0f301ad1858b4dc919
|
||||
parent = 345d5a1d9f1c12303202574c23520c8d1780dd6f
|
||||
method = merge
|
||||
cmdver = 0.4.3
|
139
deps/clap-juce-extensions/CMakeLists.txt
vendored
@ -8,19 +8,47 @@
|
||||
# CLAP_ID "com.my-cool-plugs.my-target")
|
||||
# 4. Reload your CMAKe file and my-target_CLAP will be a buildable target
|
||||
|
||||
cmake_minimum_required (VERSION 3.15 FATAL_ERROR)
|
||||
# The INTERFACE targets to transmit CXX_STANDARD and POSITION INDEPENDENT
|
||||
# require at least CMAKE 3.21
|
||||
cmake_minimum_required (VERSION 3.21 FATAL_ERROR)
|
||||
|
||||
project(clap-juce-extensions VERSION 0.1 LANGUAGES C CXX)
|
||||
get_directory_property(parent_dir PARENT_DIRECTORY)
|
||||
if ("${parent_dir}" STREQUAL "")
|
||||
# OSX deployment target needs to be set before the `project()` call
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "Minimum OS X deployment target")
|
||||
set(is_toplevel 1)
|
||||
else ()
|
||||
set(is_toplevel 0)
|
||||
endif ()
|
||||
|
||||
project(clap-juce-extensions VERSION 0.1.0 LANGUAGES C CXX)
|
||||
|
||||
if (CMAKE_CXX_STANDARD)
|
||||
set(CLAP_CXX_STANDARD ${CMAKE_CXX_STANDARD})
|
||||
else()
|
||||
set(CLAP_CXX_STANDARD 14)
|
||||
endif()
|
||||
if (${CLAP_CXX_STANDARD} LESS 14)
|
||||
set(CLAP_CXX_STANDARD 14)
|
||||
endif()
|
||||
|
||||
message( STATUS "Building CLAP with CLAP_CXX_STANDARD=${CLAP_CXX_STANDARD}")
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
|
||||
option(CLAP_JUCE_EXTENSIONS_BUILD_EXAMPLES "Add targets for building and running clap-juce-extensions examples" ${is_toplevel})
|
||||
if(CLAP_JUCE_EXTENSIONS_BUILD_EXAMPLES)
|
||||
# The examples need JUCE to be imported before the CLAP helper targets
|
||||
set(CLAP_JUCE_VERSION "6.1.5" CACHE STRING "Version of JUCE to use for building example plugins")
|
||||
message(STATUS "Building examples with JUCE version: ${CLAP_JUCE_VERSION}")
|
||||
include(examples/cmake/CPM.cmake)
|
||||
CPMAddPackage("gh:juce-framework/JUCE#${CLAP_JUCE_VERSION}")
|
||||
endif()
|
||||
|
||||
add_subdirectory(clap-libs/clap clapjuceext_clap EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(clap-libs/clap-helpers clapjuceext_claphelpers EXCLUDE_FROM_ALL)
|
||||
|
||||
add_library(clap_juce_extensions STATIC src/extensions/clap-juce-extensions.cpp)
|
||||
set_property(TARGET clap_juce_extensions PROPERTY CXX_STANDARD 14)
|
||||
set_property(TARGET clap_juce_extensions PROPERTY CXX_STANDARD ${CLAP_CXX_STANDARD})
|
||||
target_include_directories(clap_juce_extensions PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
target_compile_definitions(clap_juce_extensions PUBLIC
|
||||
HAS_CLAP_JUCE_EXTENSIONS=1)
|
||||
@ -34,105 +62,16 @@ set_target_properties(clap_juce_extensions PROPERTIES
|
||||
)
|
||||
|
||||
add_library(clap_juce_sources INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/src/wrapper/clap-juce-wrapper.cpp)
|
||||
set_property(TARGET clap_juce_sources PROPERTY CXX_STANDARD 14)
|
||||
set_property(TARGET clap_juce_sources PROPERTY CXX_STANDARD ${CLAP_CXX_STANDARD})
|
||||
set_property(TARGET clap_juce_sources PROPERTY CLAP_JUCE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
if (APPLE)
|
||||
target_sources(clap_juce_sources INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/src/wrapper/clap-juce-mac.mm)
|
||||
endif()
|
||||
target_include_directories(clap_juce_sources INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
|
||||
function(clap_juce_extensions_plugin)
|
||||
set(oneValueArgs TARGET)
|
||||
set(multiValueArgs CLAP_ID CLAP_FEATURES CLAP_MANUAL_URL CLAP_SUPPORT_URL)
|
||||
include(cmake/ClapTargetHelpers.cmake)
|
||||
|
||||
cmake_parse_arguments(CJA "" "${oneValueArgs}"
|
||||
"${multiValueArgs}" ${ARGN} )
|
||||
set(target ${CJA_TARGET})
|
||||
set(claptarget ${target}_CLAP)
|
||||
|
||||
message(STATUS "Creating CLAP ${claptarget} from ${target}")
|
||||
|
||||
if ("${CJA_CLAP_ID}" STREQUAL "")
|
||||
message(FATAL_ERROR "You must specify CLAP_ID to add a clap" )
|
||||
endif()
|
||||
|
||||
if ("${CJA_CLAP_FEATURES}" STREQUAL "")
|
||||
message(WARNING "No CLAP_FEATURES were specified! Using \"instrument\" by default.")
|
||||
set(CJA_CLAP_FEATURES instrument)
|
||||
endif()
|
||||
|
||||
# we need the list of features as comma separated quoted strings
|
||||
foreach(feature IN LISTS CJA_CLAP_FEATURES)
|
||||
list (APPEND CJA_CLAP_FEATURES_PARSED "\"${feature}\"")
|
||||
endforeach()
|
||||
list (JOIN CJA_CLAP_FEATURES_PARSED ", " CJA_CLAP_FEATURES_PARSED)
|
||||
|
||||
get_property(SRC TARGET clap_juce_sources PROPERTY SOURCES)
|
||||
add_library(${claptarget} MODULE ${SRC})
|
||||
|
||||
set_target_properties(${claptarget} PROPERTIES
|
||||
CXX_STANDARD 14
|
||||
ARCHIVE_OUTPUT_DIRECTORY "$<GENEX_EVAL:$<TARGET_PROPERTY:${target},ARCHIVE_OUTPUT_DIRECTORY>>/CLAP"
|
||||
LIBRARY_OUTPUT_DIRECTORY "$<GENEX_EVAL:$<TARGET_PROPERTY:${target},LIBRARY_OUTPUT_DIRECTORY>>/CLAP"
|
||||
RUNTIME_OUTPUT_DIRECTORY "$<GENEX_EVAL:$<TARGET_PROPERTY:${target},RUNTIME_OUTPUT_DIRECTORY>>/CLAP")
|
||||
|
||||
get_target_property(products_folder ${claptarget} LIBRARY_OUTPUT_DIRECTORY)
|
||||
set(product_name $<TARGET_PROPERTY:${target},JUCE_PRODUCT_NAME>)
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
|
||||
set_target_properties(${claptarget} PROPERTIES
|
||||
BUNDLE True
|
||||
BUNDLE_EXTENSION clap
|
||||
PREFIX ""
|
||||
OUTPUT_NAME "${product_name}"
|
||||
MACOSX_BUNDLE TRUE
|
||||
)
|
||||
else()
|
||||
set_target_properties(${claptarget} PROPERTIES
|
||||
PREFIX ""
|
||||
SUFFIX ".clap"
|
||||
OUTPUT_NAME "${product_name}"
|
||||
)
|
||||
endif()
|
||||
|
||||
target_include_directories(${claptarget} PRIVATE
|
||||
$<TARGET_PROPERTY:${target},INCLUDE_DIRECTORIES>)
|
||||
|
||||
target_compile_definitions(${claptarget} PRIVATE
|
||||
CLAP_ID="${CJA_CLAP_ID}"
|
||||
CLAP_FEATURES=${CJA_CLAP_FEATURES_PARSED}
|
||||
CLAP_MANUAL_URL="${CJA_CLAP_MANUAL_URL}"
|
||||
CLAP_SUPPORT_URL="${CJA_CLAP_SUPPORT_URL}")
|
||||
|
||||
target_link_libraries(${target} PUBLIC clap_juce_extensions)
|
||||
|
||||
target_link_libraries(${claptarget} PUBLIC clap-core clap-helpers clap_juce_sources ${target})
|
||||
set_property(TARGET ${claptarget} PROPERTY C_VISIBILITY_PRESET hidden)
|
||||
set_property(TARGET ${claptarget} PROPERTY VISIBILITY_INLINES_HIDDEN ON)
|
||||
|
||||
set_target_properties(${claptarget} PROPERTIES
|
||||
POSITION_INDEPENDENT_CODE TRUE
|
||||
VISIBILITY_INLINES_HIDDEN TRUE
|
||||
C_VISBILITY_PRESET hidden
|
||||
CXX_VISIBILITY_PRESET hidden
|
||||
)
|
||||
|
||||
get_target_property(docopy "${target}" JUCE_COPY_PLUGIN_AFTER_BUILD)
|
||||
|
||||
if(docopy)
|
||||
message(STATUS "Copy After Build" )
|
||||
if (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
|
||||
add_custom_command(TARGET ${claptarget} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "Installing ${products_folder}/${product_name}.clap to ~/Library/Audio/Plug-Ins/CLAP/"
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "~/Library/Audio/Plug-Ins/CLAP"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory "${products_folder}/${product_name}.clap" "~/Library/Audio/Plug-Ins/CLAP/${product_name}.clap"
|
||||
)
|
||||
endif()
|
||||
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
add_custom_command(TARGET ${claptarget} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "Installing ${products_folder}/${product_name}.clap"
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "~/.clap"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy "${products_folder}/${product_name}.clap" "~/.clap/"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
if(CLAP_JUCE_EXTENSIONS_BUILD_EXAMPLES)
|
||||
message(STATUS "Configuring clap-juce-extensions examples")
|
||||
add_subdirectory(examples)
|
||||
endif()
|
||||
|
112
deps/clap-juce-extensions/README.md
vendored
@ -1,6 +1,6 @@
|
||||
# JUCE6 and 7 Unofficial CMake Clap Plugin Support
|
||||
# JUCE6 and 7 Unofficial CLAP Plugin Support
|
||||
|
||||
This is a set of code which, combined with a JUCE6 or JUCE 7 CMake plugin project, allows you to build a CLAP plugin. It
|
||||
This is a set of code which, combined with a JUCE 6 or JUCE 7 plugin project, allows you to build a CLAP plugin. It
|
||||
is licensed under the MIT license, and can be used for both open and closed source projects.
|
||||
|
||||
We are labeling it 'unofficial' for four reasons
|
||||
@ -24,6 +24,8 @@ other CLAP 1.0 DAWs such as MultitrackStudio.
|
||||
|
||||
## Basics: Using these extensions to build a CLAP
|
||||
|
||||
### CMake
|
||||
|
||||
Given a starting point of a JUCE plugin using CMake which can build a VST3, AU, Standalone and so forth with
|
||||
`juce_plugin`, building a CLAP is a simple exercise of checking out this CLAP extension code
|
||||
somewhere in your dev environment, setting a few CMake variables, and adding a couple of lines to your CMake file.
|
||||
@ -53,6 +55,97 @@ add_subdirectory(libs/clap-juce-extensions EXCLUDE_FROM_ALL)
|
||||
5. Reload your CMake file and you will have a new target `my-target_CLAP` which will build a CLAP and leave
|
||||
it side-by-side with your AU, Standalone, VST3, and so forth. Load that CLAP into a DAW and give it a whirl!
|
||||
|
||||
### Projucer
|
||||
|
||||
Given a starting point of a JUCE plugin using the Projucer, it is possible to build a CLAP plugin by adding
|
||||
a small CMake configuration alongside the Projucer build setup.
|
||||
|
||||
1. Build your Projucer-based plugin.
|
||||
2. Create `CMakeLists.txt` file in the same directory as your `.jucer` file. Here's an example CMakeLists.txt:
|
||||
|
||||
```cmake
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
# Make sure to set the same MacOS deployment target as you have set in the Projucer
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.12" CACHE STRING "Minimum OS X deployment target")
|
||||
|
||||
# If the Projucer is using "static runtime" for Visual Studio:
|
||||
# set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>" CACHE STRING "Runtime")
|
||||
# set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Release>:Release>" CACHE STRING "Runtime")
|
||||
|
||||
# If running into issues when Xcode tries to codesign the CLAP plugin, you may want to add these lines:
|
||||
# set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
|
||||
# set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO")
|
||||
|
||||
project(MyPlugin VERSION 1.0.0)
|
||||
|
||||
set(PATH_TO_JUCE path/to/JUCE)
|
||||
set(PATH_TO_CLAP_EXTENSIONS path/to/clap-juce-extensions)
|
||||
|
||||
# define the exporter types used in your Projucer configuration
|
||||
if (APPLE)
|
||||
set(JUCER_GENERATOR "Xcode")
|
||||
elseif (WIN32)
|
||||
set(JUCER_GENERATOR "VisualStudio2019")
|
||||
else () # Linux
|
||||
set(JUCER_GENERATOR "LinuxMakefile")
|
||||
endif ()
|
||||
|
||||
include(${PATH_TO_CLAP_EXTENSIONS}/cmake/JucerClap.cmake)
|
||||
create_jucer_clap_target(
|
||||
TARGET MyPlugin # "Binary Name" in the Projucer
|
||||
PLUGIN_NAME "My Plugin"
|
||||
BINARY_NAME "MyPlugin" # Name of the resulting plugin binary
|
||||
MANUFACTURER_NAME "My Company"
|
||||
MANUFACTURER_CODE Manu
|
||||
PLUGIN_CODE Plg1
|
||||
VERSION_STRING "1.0.0"
|
||||
CLAP_ID "org.mycompany.myplugin"
|
||||
CLAP_FEATURES instrument synthesizer
|
||||
CLAP_MANUAL_URL "https://www.mycompany.com"
|
||||
CLAP_SUPPORT_URL "https://www.mycompany.com"
|
||||
EDITOR_NEEDS_KEYBOARD_FOCUS FALSE
|
||||
)
|
||||
```
|
||||
|
||||
3. Build the CLAP plugin using CMake. This step can be done manually,
|
||||
as part of an automated build script, or potentially even as a
|
||||
post-build step triggered from the Projucer:
|
||||
|
||||
```bash
|
||||
cmake -Bbuild-clap -G<generator> -DCMAKE_BUILD_TYPE=<Debug|Release>
|
||||
cmake --build build-clap --config <Debug|Release>
|
||||
```
|
||||
|
||||
The resulting builds will be located in `build-clap/MyPlugin_artefacts`.
|
||||
|
||||
If you would like to use the [CLAP extensions API](#the-extensions-api), the necessary source
|
||||
files must be added to the plugin's Projucer configuration.
|
||||
|
||||
### Arguments to CLAP CMake functions
|
||||
|
||||
In addition to `CLAP_ID` and `CLAP_FEATURES` described above the following arguments
|
||||
are available
|
||||
|
||||
* `CLAP_MANUAL_URL` and `CLAP_SUPPORT_URL` generate the urls in your description
|
||||
* `CLAP_MISBHEAVIOUR_HANDLER_LEVEL` can be set to `Terminate` or `Ignore` (default
|
||||
is `Ignore`) to choose your behaviour for a misbehaving host.
|
||||
* `CLAP_CHECKING_LEVEL` can be set to `None`, `Minimal`, or `Maximal` (default is
|
||||
`Minimal`) to choose the level of sanity checks enabled for the plugin.
|
||||
* `CLAP_PROCESS_EVENTS_RESOLUTION_SAMPLES` can be set to any integer value to choose the
|
||||
resolution (in samples) used by the wrapper for doing sample-accurate event processing.
|
||||
Setting the value to `0` (the default value) will turn off sample-accurate event processing.
|
||||
* `CLAP_ALWAYS_SPLIT_BLOCK` can be set to `1` (on), or `0` (off, default), to tell the
|
||||
wrapper to _always_ attempt to split incoming audio buffers into chunks of size
|
||||
`CLAP_PROCESS_EVENTS_RESOLUTION_SAMPLES`, regardless of any input events being
|
||||
sent from the host. Note that if the block size provided by the host is not an
|
||||
even multiple of `CLAP_PROCESS_EVENTS_RESOLUTION_SAMPLES`, the plugin may be
|
||||
required to process a chunk smaller than the chosen resolution.
|
||||
* `CLAP_USE_JUCE_PARAMETER_RANGES` can be set to `ALL`, `DISCRETE` or `OFF` (default) to
|
||||
tell the wrapper to use JUCE's parameter ranges for all parameters, discrete parameters only,
|
||||
or no parameters. When not using JUCE's parameter ranges, the plugin will communicate with
|
||||
the host using 0-1 parameter ranges for the given parameter,
|
||||
|
||||
## Risks of using this library
|
||||
|
||||
Using this library is, of course, not without risks. There could easily be bugs we haven't found and there are
|
||||
@ -66,7 +159,8 @@ generated by this library would.
|
||||
|
||||
There are a couple of mitigants to that risk.
|
||||
|
||||
Most importantly, in the three critical places a DAW interacts with a plugin - CLAP ID, parameter IDs, and state streaming -
|
||||
Most importantly, in the three critical places a DAW interacts with a plugin - CLAP ID, parameter IDs, and state
|
||||
streaming -
|
||||
we have endeavoured to write in as JUCE-natural a way as possible.
|
||||
|
||||
1. The CLAP ID is just a CMake parameter, as we expect it would be in an official build.
|
||||
@ -98,10 +192,11 @@ example today) relying on these wrappers still.
|
||||
in our adapter (although they are supported in the CLAP API of course). We would love a test plugin to help us
|
||||
resolve this.
|
||||
|
||||
## The Extensions API
|
||||
## The `clap_juce_extensions` API for extended CLAP capabilities in JUCE
|
||||
|
||||
There are a set of things which JUCE doesn't support which CLAP does. Rather than not support them in our
|
||||
plugins, we've decided to create an extensions API. These are a set of classes which your AudioProcessor can
|
||||
plugins, we've decided to create an specific extensions API which allow you to decorate JUCE
|
||||
classes with extended capabilities. These are a set of classes which your AudioProcessor can
|
||||
implement and, if it does, then the CLAP JUCE wrapper will call the associated functions.
|
||||
|
||||
The extension are in "include/clap-juce-extensions.h" and are documented there, but currently have
|
||||
@ -111,14 +206,15 @@ three classes
|
||||
- if you subclass this your AudioProcessor will have a collection of members which give you extra CLAP info
|
||||
- Most usefully, you get an `is_clap` member which is false if not a CLAP and true if it is, which works around
|
||||
the fact that our 'forkless' approach doesn't let us add a `AudioProcessor::WrapperType` to the JUCE API
|
||||
- `clap_juce_extensions::clap_extensions`
|
||||
- `clap_juce_extensions::clap_juce_audio_processor_capabilities`
|
||||
- these are a set of advanced extensions which let you optionally interact more directly with the CLAP API
|
||||
and are mostly useful for advanced features like non-destructive modulation and note expression support
|
||||
- `clap_juce_extensions::clap_param_extensions`
|
||||
- `clap_juce_extensions::clap_juce_parameter_capabilities`
|
||||
- If your AudioProcessorParameter subclass implements this API, you can share extended CLAP information on
|
||||
a parameter by parameter basis
|
||||
|
||||
As an example, here's how to use `clap_properties` to work around `AudioProcessor::WrapperType` being `Undefined` in the forkless
|
||||
As an example, here's how to use `clap_properties` to work around `AudioProcessor::WrapperType` being `Undefined` in the
|
||||
forkless
|
||||
CLAP approach
|
||||
|
||||
- `#include "clap-juce-extensions/clap-juce-extensions.h"`
|
||||
|
@ -1,12 +0,0 @@
|
||||
; 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
|
@ -1,25 +0,0 @@
|
||||
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 ".")
|
@ -1,21 +0,0 @@
|
||||
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.
|
@ -1,9 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace clap { namespace helpers {
|
||||
enum class CheckingLevel {
|
||||
None,
|
||||
Minimal,
|
||||
Maximal,
|
||||
};
|
||||
}} // namespace clap::helpers
|
@ -1,148 +0,0 @@
|
||||
#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
|
@ -1,84 +0,0 @@
|
||||
#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
|
@ -1,170 +0,0 @@
|
||||
#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
|
@ -1,546 +0,0 @@
|
||||
#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
|
@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace clap { namespace helpers {
|
||||
enum class MisbehaviourHandler {
|
||||
Ignore,
|
||||
Terminate,
|
||||
};
|
||||
}} // namespace clap::helpers
|
@ -1,75 +0,0 @@
|
||||
#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
|
@ -1,71 +0,0 @@
|
||||
#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
|
@ -1,37 +0,0 @@
|
||||
#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
|
@ -1,434 +0,0 @@
|
||||
#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
|
@ -1,48 +0,0 @@
|
||||
#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
|
@ -1,72 +0,0 @@
|
||||
#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
|
@ -1,2 +0,0 @@
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include <catch2/catch.hpp>
|
@ -1,18 +0,0 @@
|
||||
#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;
|
||||
}
|
@ -1,137 +0,0 @@
|
||||
---
|
||||
Language: Cpp
|
||||
# BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -3
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveMacros: false
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: true
|
||||
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: false
|
||||
SplitEmptyRecord: false
|
||||
SplitEmptyNamespace: false
|
||||
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: false
|
||||
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
|
||||
...
|
||||
|
@ -1,45 +0,0 @@
|
||||
# Copyright (c) 2021 Luca Cappa
|
||||
# Released under the term specified in file LICENSE.txt
|
||||
# SPDX short identifier: MIT
|
||||
#
|
||||
# The peculiarity of this workflow is that assumes vcpkg stored as a submodule of this repository.
|
||||
# This workflow does the following:
|
||||
# - Restores vcpkg artifacts from cache.
|
||||
# - Sets up vcpkg if needed, then run CMake with CMakePreset.json using a configuration
|
||||
# that leverages the vcpkg's toolchain file. This will automatically run vcpkg to install dependencies
|
||||
# described by the vcpkg.json manifest file. It will be a no-op if those are restored from cache.
|
||||
# - Finally builds the sources with Ninja.
|
||||
name: build
|
||||
on: [push, workflow_dispatch]
|
||||
|
||||
jobs:
|
||||
VCPKG:
|
||||
name: ${{ matrix.os }}-${{ github.workflow }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- uses: lukka/get-cmake@latest
|
||||
|
||||
- name: Setup MacOS
|
||||
if: startsWith(matrix.os, 'macOS')
|
||||
run: brew install automake autoconf ninja cmake
|
||||
|
||||
- name: Setup Ubuntu
|
||||
if: startsWith(matrix.os, 'ubuntu')
|
||||
run: sudo apt install ninja-build cmake
|
||||
|
||||
- name: Run CMake+Ninja+CTest to generate/build/test.
|
||||
uses: lukka/run-cmake@v10
|
||||
id: runcmake
|
||||
with:
|
||||
configurePreset: 'ninja'
|
||||
buildPreset: 'ninja-release'
|
||||
testPreset: 'ninja-release'
|
@ -1,6 +0,0 @@
|
||||
{
|
||||
"name": "clap",
|
||||
"description": "Build C/C++ code with CMake and Ninja.",
|
||||
"iconName": "cmake",
|
||||
"categories": ["CMake", "cpp", "cplusplus", "Ninja"]
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
# Visual Studio
|
||||
obj/
|
||||
*.sln
|
||||
*.vcxproj
|
||||
*.vcxproj.filters
|
||||
*.vcxproj.user
|
||||
.vs/
|
||||
packages/
|
||||
target/
|
||||
*.pdb
|
||||
packages.config
|
||||
CMakeSettings.json
|
||||
.vscode
|
||||
.cache
|
||||
|
||||
# C++ IDE helpers
|
||||
compile_commands.json
|
||||
|
||||
# IntelliJ IDEA
|
||||
.idea
|
||||
|
||||
# CMake common patterns
|
||||
build*/
|
||||
cmake-build*/
|
||||
|
||||
# A place to store stuff and get it git ignored
|
||||
ignore/*
|
@ -1,12 +0,0 @@
|
||||
; 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
|
||||
branch = main
|
||||
commit = 3189bdfaf849eadeb5a0149bf3e2cb9fd0690518
|
||||
parent = 1b743700030422251f8e1b50f094c7a50ffff8fd
|
||||
method = merge
|
||||
cmdver = 0.4.3
|
@ -1,64 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.17)
|
||||
enable_testing()
|
||||
project(CLAP C CXX)
|
||||
|
||||
add_custom_target(clap-tests)
|
||||
|
||||
# If you use clap as a submodule of your plugin you need some interface projects
|
||||
# to allow you to link. clap-core gives you the include directory and clap-plugin-core
|
||||
# gives you the core + plugin-glue.
|
||||
add_library(clap-core INTERFACE)
|
||||
target_include_directories(clap-core INTERFACE include)
|
||||
|
||||
install(DIRECTORY include DESTINATION "." OPTIONAL EXCLUDE_FROM_ALL)
|
||||
|
||||
add_executable(clap-compile-c EXCLUDE_FROM_ALL src/main.c)
|
||||
|
||||
macro(clap_compile_cpp SUFFIX EXT STDC STDCPP)
|
||||
add_executable(clap-compile-${SUFFIX} EXCLUDE_FROM_ALL src/main.${EXT})
|
||||
target_link_libraries(clap-compile-${SUFFIX} clap-core)
|
||||
set_target_properties(clap-compile-${SUFFIX} PROPERTIES
|
||||
C_STANDARD ${STDC}
|
||||
CXX_STANDARD ${STDCPP})
|
||||
add_test(NAME test-clap-compile-${SUFFIX} COMMAND clap-compile-${SUFFIX})
|
||||
add_dependencies(clap-tests clap-compile-${SUFFIX})
|
||||
|
||||
if (${CMAKE_C_COMPILER_ID} STREQUAL "GNU" OR ${CMAKE_C_COMPILER_ID} STREQUAL "Clang")
|
||||
target_compile_options(clap-compile-${SUFFIX} PRIVATE -Wall -Wextra -pedantic)
|
||||
endif()
|
||||
|
||||
if (${CMAKE_C_COMPILER_ID} STREQUAL "Clang")
|
||||
target_compile_options(clap-compile-${SUFFIX} PRIVATE -Werror=pragma-pack)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
clap_compile_cpp(c11 c 11 11)
|
||||
clap_compile_cpp(cpp11 cc 11 11)
|
||||
clap_compile_cpp(cpp14 cc 11 14)
|
||||
clap_compile_cpp(c17 c 17 17)
|
||||
clap_compile_cpp(cpp17 cc 17 17)
|
||||
clap_compile_cpp(cpp20 cc 17 20)
|
||||
|
||||
add_library(clap-plugin-template MODULE EXCLUDE_FROM_ALL src/plugin-template.c)
|
||||
target_link_libraries(clap-plugin-template PRIVATE clap-core)
|
||||
set_target_properties(clap-plugin-template PROPERTIES C_STANDARD 11)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
target_link_libraries(clap-plugin-template PRIVATE -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/src/linux-my_plug.version)
|
||||
target_link_libraries(clap-plugin-template PRIVATE -Wl,-z,defs)
|
||||
set_target_properties(clap-plugin-template PROPERTIES SUFFIX ".clap" PREFIX "")
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
target_link_options(clap-plugin-template PRIVATE -exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/src/macos-symbols.txt)
|
||||
|
||||
set_target_properties(clap-plugin-template PROPERTIES
|
||||
BUNDLE True
|
||||
BUNDLE_EXTENSION clap
|
||||
MACOSX_BUNDLE_GUI_IDENTIFIER com.my_company.my_plug
|
||||
MACOSX_BUNDLE_BUNDLE_NAME my_plug
|
||||
MACOSX_BUNDLE_BUNDLE_VERSION "1"
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING "1"
|
||||
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/src/plugins.plist.in
|
||||
)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
set_target_properties(clap-plugin-template PROPERTIES SUFFIX ".clap" PREFIX "")
|
||||
endif()
|
@ -1,40 +0,0 @@
|
||||
{
|
||||
"version": 3,
|
||||
"cmakeMinimumRequired": {
|
||||
"major": 3,
|
||||
"minor": 17,
|
||||
"patch": 0
|
||||
},
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "ninja",
|
||||
"displayName": "Ninja",
|
||||
"description": "Configure and generate Ninja project files for all configurations",
|
||||
"binaryDir": "${sourceDir}/builds/${presetName}",
|
||||
"generator": "Ninja Multi-Config",
|
||||
"cacheVariables": {
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS": {
|
||||
"type": "boolean",
|
||||
"value": true
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"buildPresets": [
|
||||
{
|
||||
"name": "ninja-release",
|
||||
"configurePreset": "ninja",
|
||||
"displayName": "Build ninja-release",
|
||||
"description": "Build ninja Release configuration",
|
||||
"configuration": "RelWithDebInfo",
|
||||
"targets": ["clap-tests"]
|
||||
}
|
||||
],
|
||||
"testPresets": [
|
||||
{
|
||||
"name": "ninja-release",
|
||||
"configurePreset": "ninja",
|
||||
"configuration": "RelWithDebInfo"
|
||||
}
|
||||
]
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
## Changes in 1.0.1
|
||||
|
||||
* [gui.h](include/clap/ext/gui.h): fix doc: set_scale must be provided
|
||||
* [events.h](include/clap/events.h): remove `clap_event_type` which was never used
|
||||
* [draft/transport-control.h](include/clap/ext/draft/transport-control.h): rename from `CLAP_EXT_CV` to `CLAP_EXT_TRANSPORT_CONTROL`
|
||||
* [draft/tuning.h](include/clap/ext/draft/tuning.h): rename `clap_client_tuning` to `clap_plugin_tuning`
|
||||
* [macros.h](include/clap/private/macros.h): fix compatibility with C17
|
||||
|
||||
## Changes in 1.0.0
|
||||
|
||||
# New stable interfaces
|
||||
|
||||
* [audio-ports-config.h](include/clap/ext/audio-ports-config.h)
|
||||
* [audio-ports.h](include/clap/ext/audio-ports.h)
|
||||
* [event-registry.h](include/clap/ext/event-registry.h)
|
||||
* [gui.h](include/clap/ext/gui.h)
|
||||
* [latency.h](include/clap/ext/latency.h)
|
||||
* [log.h](include/clap/ext/log.h)
|
||||
* [note-name.h](include/clap/ext/note-name.h)
|
||||
* [note-ports.h](include/clap/ext/note-ports.h)
|
||||
* [params.h](include/clap/ext/params.h)
|
||||
* [posix-fd-support.h](include/clap/ext/posix-fd-support.h)
|
||||
* [render.h](include/clap/ext/render.h)
|
||||
* [state.h](include/clap/ext/state.h)
|
||||
* [tail.h](include/clap/ext/tail.h)
|
||||
* [thread-check.h](include/clap/ext/thread-check.h)
|
||||
* [thread-pool.h](include/clap/ext/thread-pool.h)
|
||||
* [timer-support.h](include/clap/ext/time-support.h)
|
||||
|
||||
# New draft interfaces
|
||||
|
||||
* [ambisonic.h](include/clap/ext/draft/ambisonic.h)
|
||||
* [check-for-update.h](include/clap/ext/draft/check-for-update.h)
|
||||
* [cv.h](include/clap/ext/draft/cv.h)
|
||||
* [file-reference.h](include/clap/ext/draft/file-reference.h)
|
||||
* [midi-mappings.h](include/clap/ext/draft/midi-mappings.h)
|
||||
* [preset-load.h](include/clap/ext/draft/preset-load.h)
|
||||
* [quick-controls.h](include/clap/ext/draft/quick-controls.h)
|
||||
* [surround.h](include/clap/ext/draft/surround.h)
|
||||
* [track-info.h](include/clap/ext/draft/track-info.h)
|
||||
* [transport-control.h](include/clap/ext/draft/transport-control.h)
|
||||
* [tuning.h](include/clap/ext/draft/tuning.h)
|
||||
* [voice-info.h](include/clap/ext/draft/voice-info.h)
|
@ -1,25 +0,0 @@
|
||||
CLAP is the result of countless conversations, brainstorms, reviews, tests,
|
||||
and iterations. A legion of developers with different backgrounds and points
|
||||
of view worked together and converged on a, well, clever solution.
|
||||
|
||||
All of the contributors cannot be listed. But here are a few, along with a
|
||||
thank you to all involved:
|
||||
|
||||
- Alexandre Bique (Bitwig and u-he/linux)
|
||||
- Claes Johanson (Bitwig)
|
||||
- David Schornsheim (Schroedingers-Cat, u-he)
|
||||
- Frank Hoffmann (u-he)
|
||||
- Giel Bremmers (MultitrackStudio)
|
||||
- Jan Storm (u-he)
|
||||
- John Schwartz (Cockos)
|
||||
- Nicholas Allen (Bitwig)
|
||||
- Paul Walker (BaconPaul, Surge)
|
||||
- Placidus Schelbert (Bitwig)
|
||||
- Robbert van der Helm (yabridge)
|
||||
- Robin Gareus (Ardour)
|
||||
- Thomas Binek (tas, u-he)
|
||||
- Timo Kaluza
|
||||
- Tor-Helge Skei (MIP2)
|
||||
- Urs Heckmann (u-he)
|
||||
- Vadim Zavalishin
|
||||
- William Light (LHI Audio)
|
21
deps/clap-juce-extensions/clap-libs/clap/LICENSE
vendored
@ -1,21 +0,0 @@
|
||||
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.
|
138
deps/clap-juce-extensions/clap-libs/clap/README.md
vendored
@ -1,138 +0,0 @@
|
||||
<p align=center>
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/free-audio/clap/main/artwork/clap-full-logo-white.png">
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/free-audio/clap/main/artwork/clap-full-logo-black.png">
|
||||
<img alt="CLAP" title="Clever Audio Plugin" src="https://raw.githubusercontent.com/free-audio/clap/main/artwork/clap-full-logo-black.png" width=200>
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
- [Learn about CLAP](#learn-about-clap)
|
||||
- [Entry point](#entry-point)
|
||||
- [Extensions](#extensions)
|
||||
- [Fundamental extensions](#fundamental-extensions)
|
||||
- [Support extensions](#support-extensions)
|
||||
- [Extra extensions](#extra-extensions)
|
||||
- [Resources](#resources)
|
||||
- [Plugins](#plugins)
|
||||
- [Hosts](#hosts)
|
||||
- [Examples](#examples)
|
||||
- [Community related projects](#community-related-projects)
|
||||
- [Programming Language Bindings](#programming-language-bindings)
|
||||
- [Artwork](#artwork)
|
||||
|
||||
# Learn about CLAP
|
||||
|
||||
CLAP stands for **CL**ever **A**udio **P**lugin.
|
||||
It is an audio plugin ABI which defines a standard for *Digital Audio Workstations* and audio plugins (synthesizers, audio effects, ...) to work together.
|
||||
|
||||
To work with CLAP, include [clap/clap.h](include/clap/clap.h).
|
||||
|
||||
The two most important objects are `clap_host` and `clap_plugin`.
|
||||
|
||||
[src/plugin-template.c](src/plugin-template.c) is a very minimal example which demonstrates how to wire a CLAP plugin.
|
||||
|
||||
## Entry point
|
||||
|
||||
The entry point is declared in [entry.h](include/clap/entry.h).
|
||||
|
||||
## Extensions
|
||||
|
||||
Most features comes from extensions, which are in fact C interfaces.
|
||||
```C
|
||||
// host extension
|
||||
const clap_host_log *log = host->extension(host, CLAP_EXT_LOG);
|
||||
if (log)
|
||||
log->log(host, CLAP_LOG_INFO, "Hello World! ;^)");
|
||||
|
||||
// plugin extension
|
||||
const clap_plugin_params *params = plugin->extension(plugin, CLAP_EXT_PARAMS);
|
||||
if (params)
|
||||
{
|
||||
uint32_t paramsCount = params->count(plugin);
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
The extensions are defined in [ext](include/clap/ext) folder.
|
||||
|
||||
Some extensions are still in the progress of being designed and they are in
|
||||
the [draft](include/clap/ext/draft) folder.
|
||||
|
||||
An extension comes with:
|
||||
- an header `#include <clap/ext/xxx.h>`
|
||||
- an extension identifier: `#define CLAP_EXT_XXX "clap/XXX"`
|
||||
- host interfaces are named like: `struct clap_host_xxx`
|
||||
- plugin interfaces are named like: `struct clap_plugin_xxx`
|
||||
- each methods must have a clear thread specification
|
||||
|
||||
You can create your own extensions and share them, make sure that the extension identifier
|
||||
- includes versioning in case the ABI breaks
|
||||
- a unique identifier
|
||||
|
||||
**All strings are valid UTF-8**.
|
||||
|
||||
## Fundamental extensions
|
||||
|
||||
This is a list of the extensions that you most likely want to implement
|
||||
and use to get a basic plugin experience:
|
||||
- [log](include/clap/ext/log.h), lets the host aggregate plugin logs
|
||||
- [thread-check](include/clap/ext/thread-check.h), check which thread you are currently on, useful for correctness validation
|
||||
- [audio-ports](include/clap/ext/audio-ports.h), define the audio ports
|
||||
- [note-ports](include/clap/ext/note-ports.h), define the note ports
|
||||
- [params](include/clap/ext/params.h), parameters management
|
||||
- [latency](include/clap/ext/latency.h), report the plugin latency
|
||||
- [render](include/clap/ext/render.h), renders realtime or offline
|
||||
- [tail](include/clap/ext/tail.h), processing tail length
|
||||
- [state](include/clap/ext/state.h), save and load the plugin state
|
||||
- [gui](include/clap/ext/gui.h), generic gui controller
|
||||
|
||||
## Support extensions
|
||||
|
||||
- [thread-pool](include/clap/ext/thread-pool.h), use the host thread pool
|
||||
- [timer-support](include/clap/ext/timer-support.h), lets the plugin register timer handlers
|
||||
- [posix-fd-support](include/clap/ext/posix-fd-support.h), lets the plugin register I/O handlers
|
||||
|
||||
## Extra extensions
|
||||
|
||||
- [note-name](include/clap/ext/note-name.h), give a name to notes, useful for drum machines
|
||||
- [tuning](include/clap/ext/draft/tuning.h), host provided microtuning
|
||||
- [track-info](include/clap/ext/draft/track-info.h)
|
||||
- [quick-controls](include/clap/ext/draft/quick-controls.h), bank of controls that can be mapped on a controlles with 8 knobs
|
||||
- [file-reference](include/clap/ext/draft/file-reference.h), let the host know about the plugin's file reference, and perform "Collect & Save"
|
||||
- [check-for-update](include/clap/ext/draft/check-for-update.h), check if there is a new version of a plugin
|
||||
- [audio-ports-config](include/clap/ext/audio-ports-config.h), simple list of possible configurations
|
||||
- [surround](include/clap/ext/draft/surround.h), inspect surround channel mapping
|
||||
- [ambisonic](include/clap/ext/draft/ambisonic.h), inspect ambisonic channel mapping
|
||||
|
||||
# Resources
|
||||
|
||||
## Plugins
|
||||
|
||||
- [u-he](https://u-he.com/fwd/clap/), synthesizers and effects
|
||||
- [Surge](https://surge-synthesizer.github.io/), open source synthesizer and effect
|
||||
- CLAP is enabled in [nightly builds](https://github.com/surge-synthesizer/releases-xt/releases/tag/Nightly)
|
||||
|
||||
## Hosts
|
||||
|
||||
- [Bitwig](https://bitwig.com), you need at least _Bitwig Studio 4.3 Beta 5_
|
||||
|
||||
## Examples
|
||||
|
||||
- [clap-host](https://github.com/free-audio/clap-host), very simple host
|
||||
- [clap-plugins](https://github.com/free-audio/clap-plugins), very simple plugins
|
||||
- [schwaaa's plugin](https://github.com/schwaaa/clap-plugin), basic example for prototyping CLAP audio plugins using Dear ImGui as the user interface
|
||||
|
||||
## Community related projects
|
||||
|
||||
- [clap-juce-extension](https://github.com/free-audio/clap-juce-extension), juce add-on
|
||||
- [MIP2](https://github.com/skei/MIP2), host and plugins
|
||||
- [Avendish](https://github.com/celtera/avendish), a reflection-based API for media plug-ins in C++ which supports Clap
|
||||
- [nih-plug](https://github.com/robbert-vdh/nih-plug), an API-agnostic, Rust-based plugin framework aiming to reduce boilerplate without getting in your way
|
||||
|
||||
## Programming Language Bindings
|
||||
|
||||
- [clap-sys](https://github.com/glowcoil/clap-sys), rust binding
|
||||
- [CLAP-for-Delphi](https://github.com/Bremmers/CLAP-for-Delphi), Delphi binding
|
||||
|
||||
## Artwork
|
||||
- [CLAP Logo Pack.zip](https://github.com/free-audio/clap/files/8805281/CLAP.Logo.Pack.zip)
|
@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 26.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.2" baseProfile="tiny" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
x="0px" y="0px" viewBox="0 0 255.1 269.3" overflow="visible" xml:space="preserve">
|
||||
<path d="M91.2,158.4c9.1,0,16.5-7.4,16.5-16.5v-28.3c0-22.1,18-40.1,40.1-40.1c1.2,0,2.4,0.1,3.5,0.2l-23.7-41l-40.1,69.4
|
||||
c1.2-0.1,2.3-0.2,3.5-0.2h9.8c-1,3.8-1.6,7.7-1.6,11.8v11.8h-8.3c-9.1,0-16.5,7.4-16.5,16.5C74.6,151,82,158.4,91.2,158.4z"/>
|
||||
<path d="M184.2,130.5c-6.4,13.7-20.3,23.2-36.4,23.2H138c1-3.8,1.6-7.7,1.6-11.8v-11.8h8.3c9.1,0,16.5-7.4,16.5-16.5
|
||||
c0-9.1-7.4-16.5-16.5-16.5c-9.1,0-16.5,7.4-16.5,16.5l0,28.3c0,22.1-18,40.1-40.1,40.1c-16.1,0-30-9.5-36.4-23.2l-19.9,34.5h185.7
|
||||
L184.2,130.5z"/>
|
||||
<path d="M159.3,209h-6.5c-3.6,0-6.5,2.9-6.5,6.5V235h6.5v-6.5h6.5v6.5h6.5v-19.5C165.8,211.9,162.9,209,159.3,209z M159.3,222h-6.5
|
||||
c0,0-0.1-1.4-0.1-3.2c0-1.8,0.1-3.2,0.1-3.2s1-0.1,3.2-0.1s3.2,0.1,3.2,0.1s0.1,1.1,0.1,3.2S159.3,222,159.3,222z"/>
|
||||
<path d="M216,208.9h-13v26h6.5v-6.5h6.5c3.6,0,6.5-2.9,6.5-6.5v-6.5C222.5,211.9,219.6,208.9,216,208.9z M216,221.9
|
||||
c0,0-1.1,0.1-3.2,0.1c-2.1,0-3.2-0.1-3.2-0.1v-6.5c0,0,1.4-0.1,3.2-0.1c1.8,0,3.2,0.1,3.2,0.1s0.1,1,0.1,3.2S216,221.9,216,221.9z"
|
||||
/>
|
||||
<path d="M32.9,215.5v13c0,3.6,2.9,6.5,6.5,6.5l13,0v-6.5h-13v-13h13V209h-13C35.8,209,32.9,211.9,32.9,215.5z"/>
|
||||
<path d="M97.4,209h-6.5v19.5c0,3.6,2.9,6.5,6.5,6.5l10.4,0v-6.5H97.4V209z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.5 KiB |
@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 26.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.2" baseProfile="tiny" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
x="0px" y="0px" viewBox="0 0 16 16" overflow="visible" xml:space="preserve">
|
||||
<g>
|
||||
<path d="M10.5,1.8c-1.8,0-3.4,1-4.3,2.5H6H5.5c-2.7,0-4.9,2.2-4.9,4.9s2.2,4.9,4.9,4.9c1.8,0,3.4-1,4.3-2.5H10h0.5
|
||||
c2.7,0,4.9-2.2,4.9-4.9C15.4,4,13.2,1.8,10.5,1.8L10.5,1.8z"/>
|
||||
</g>
|
||||
<path fill="#F0F2F4" d="M10.5,10.3H10V8.2h0.5c0.8,0,1.4-0.7,1.4-1.4c0-0.8-0.7-1.4-1.4-1.4C9.7,5.3,9,6,9,6.8l0,2.5
|
||||
c0,1.9-1.6,3.5-3.5,3.5S2,11.2,2,9.2s1.6-3.5,3.5-3.5H6v2.1H5.5c-0.8,0-1.4,0.7-1.4,1.4c0,0.8,0.7,1.4,1.4,1.4S7,10,7,9.2V6.8
|
||||
c0-1.9,1.6-3.5,3.5-3.5S14,4.8,14,6.8S12.4,10.3,10.5,10.3z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 833 B |
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 26.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.2" baseProfile="tiny" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
x="0px" y="0px" viewBox="0 0 32 32" overflow="visible" xml:space="preserve">
|
||||
<path fill="#1D1D1B" d="M11.3,14.2h1.1c-0.1,0.5-0.2,1-0.2,1.5v1.5h-0.9c-1.2,0-2.1,1-2.1,2.1c0,1.2,1,2.1,2.1,2.1s2.1-1,2.1-2.1
|
||||
v-3.7c0-2.9,2.3-5.2,5.2-5.2c0.2,0,0.3,0,0.5,0L16,5.2l-5.2,9C11,14.2,11.1,14.2,11.3,14.2z"/>
|
||||
<path fill="#1D1D1B" d="M23.3,17.9c-0.8,1.8-2.6,3-4.7,3h-1.1c0.1-0.5,0.2-1,0.2-1.5v-1.5h0.9c1.2,0,2.1-1,2.1-2.1
|
||||
c0-1.2-1-2.1-2.1-2.1c-1.2,0-2.1,1-2.1,2.1l0,3.7c0,2.9-2.3,5.2-5.2,5.2c-2.1,0-3.9-1.2-4.7-3L4,26h24L23.3,17.9z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 794 B |
@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 26.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.2" baseProfile="tiny" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
x="0px" y="0px" viewBox="0 0 255.1 255.1" overflow="visible" xml:space="preserve">
|
||||
<path fill="#1D1D1B" d="M91.1,172.5c9.1,0,16.5-7.4,16.5-16.5v-28.3c0-22.1,18-40.1,40.1-40.1c1.2,0,2.4,0.1,3.5,0.2l-23.7-41
|
||||
l-40,69.3c1.2-0.1,2.3-0.2,3.5-0.2h9.8c-1,3.8-1.6,7.7-1.6,11.8v11.8h-8.2c-9.1,0-16.5,7.4-16.5,16.5
|
||||
C74.6,165.1,82,172.5,91.1,172.5z"/>
|
||||
<path fill="#1D1D1B" d="M184.1,144.6c-6.4,13.7-20.3,23.2-36.4,23.2h-9.8c1-3.8,1.6-7.7,1.6-11.8v-11.8h8.2
|
||||
c9.1,0,16.5-7.4,16.5-16.5c0-9.1-7.4-16.5-16.5-16.5c-9.1,0-16.5,7.4-16.5,16.5l0,28.3c0,22.1-18,40.1-40.1,40.1
|
||||
c-16.1,0-30-9.5-36.4-23.2l-19.9,34.5h185.6L184.1,144.6z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 889 B |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 20 KiB |
@ -1,37 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "private/std.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Sample code for reading a stereo buffer:
|
||||
//
|
||||
// bool isLeftConstant = (buffer->constant_mask & (1 << 0)) != 0;
|
||||
// bool isRightConstant = (buffer->constant_mask & (1 << 1)) != 0;
|
||||
//
|
||||
// for (int i = 0; i < N; ++i) {
|
||||
// float l = data32[0][isLeftConstant ? 0 : i];
|
||||
// float r = data32[1][isRightConstant ? 0 : i];
|
||||
// }
|
||||
//
|
||||
// Note: checking the constant mask is optional, and this implies that
|
||||
// the buffer must be filled with the constant value.
|
||||
// Rationale: if a buffer reader doesn't check the constant mask, then it may
|
||||
// process garbage samples and in result, garbage samples may be transmitted
|
||||
// to the audio interface with all the bad consequences it can have.
|
||||
//
|
||||
// The constant mask is a hint.
|
||||
typedef struct clap_audio_buffer {
|
||||
// Either data32 or data64 pointer will be set.
|
||||
float **data32;
|
||||
double **data64;
|
||||
uint32_t channel_count;
|
||||
uint32_t latency; // latency from/to the audio interface
|
||||
uint64_t constant_mask;
|
||||
} clap_audio_buffer_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* CLAP - CLever Audio Plugin
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* Copyright (c) 2014...2022 Alexandre BIQUE <bique.alexandre@gmail.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "entry.h"
|
||||
#include "plugin-factory.h"
|
||||
#include "plugin-invalidation.h"
|
||||
#include "plugin-features.h"
|
||||
|
||||
#include "plugin.h"
|
||||
#include "host.h"
|
||||
|
||||
#include "ext/audio-ports.h"
|
||||
#include "ext/audio-ports-config.h"
|
||||
#include "ext/gui.h"
|
||||
#include "ext/log.h"
|
||||
#include "ext/params.h"
|
||||
#include "ext/render.h"
|
||||
#include "ext/state.h"
|
||||
#include "ext/latency.h"
|
||||
#include "ext/thread-check.h"
|
||||
#include "ext/timer-support.h"
|
||||
#include "ext/posix-fd-support.h"
|
||||
#include "ext/note-name.h"
|
||||
#include "ext/note-ports.h"
|
||||
#include "ext/thread-pool.h"
|
||||
#include "ext/event-registry.h"
|
||||
#include "ext/tail.h"
|
||||
|
||||
#include "ext/draft/preset-load.h"
|
||||
#include "ext/draft/quick-controls.h"
|
||||
#include "ext/draft/track-info.h"
|
||||
#include "ext/draft/tuning.h"
|
||||
#include "ext/draft/file-reference.h"
|
||||
#include "ext/draft/midi-mappings.h"
|
||||
#include "ext/draft/surround.h"
|
||||
#include "ext/draft/cv.h"
|
||||
#include "ext/draft/ambisonic.h"
|
||||
#include "ext/draft/voice-info.h"
|
@ -1,18 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "private/std.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct clap_color {
|
||||
uint8_t alpha;
|
||||
uint8_t red;
|
||||
uint8_t green;
|
||||
uint8_t blue;
|
||||
} clap_color_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,60 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "version.h"
|
||||
#include "private/macros.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// This interface is the entry point of the dynamic library.
|
||||
//
|
||||
// CLAP plugins standard search path:
|
||||
//
|
||||
// Linux
|
||||
// - ~/.clap
|
||||
// - /usr/lib/clap
|
||||
//
|
||||
// Windows
|
||||
// - %CommonFilesFolder%/CLAP/
|
||||
// - %LOCALAPPDATA%/Programs/Common/CLAP/
|
||||
//
|
||||
// MacOS
|
||||
// - /Library/Audio/Plug-Ins/CLAP
|
||||
// - ~/Library/Audio/Plug-Ins/CLAP
|
||||
//
|
||||
// Additionally, extra path may be specified in CLAP_PATH environment variable.
|
||||
// CLAP_PATH is formated in the same way as the OS' binary search path (PATH on UNIX, Path on Windows).
|
||||
//
|
||||
// Every methods must be thread-safe.
|
||||
typedef struct clap_plugin_entry {
|
||||
clap_version_t clap_version; // initialized to CLAP_VERSION
|
||||
|
||||
// This function must be called first, and can only be called once.
|
||||
//
|
||||
// It should be as fast as possible, in order to perform very quick scan of the plugin
|
||||
// descriptors.
|
||||
//
|
||||
// It is forbidden to display graphical user interface in this call.
|
||||
// It is forbidden to perform user inter-action in this call.
|
||||
//
|
||||
// If the initialization depends upon expensive computation, maybe try to do them ahead of time
|
||||
// and cache the result.
|
||||
bool (*init)(const char *plugin_path);
|
||||
|
||||
// No more calls into the DSO must be made after calling deinit().
|
||||
void (*deinit)(void);
|
||||
|
||||
// Get the pointer to a factory. See plugin-factory.h for an example.
|
||||
//
|
||||
// Returns null if the factory is not provided.
|
||||
// The returned pointer must *not* be freed by the caller.
|
||||
const void *(*get_factory)(const char *factory_id);
|
||||
} clap_plugin_entry_t;
|
||||
|
||||
/* Entry point */
|
||||
CLAP_EXPORT extern const clap_plugin_entry_t clap_entry;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,283 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "private/std.h"
|
||||
#include "fixedpoint.h"
|
||||
#include "id.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// event header
|
||||
// must be the first attribute of the event
|
||||
typedef struct clap_event_header {
|
||||
uint32_t size; // event size including this header, eg: sizeof (clap_event_note)
|
||||
uint32_t time; // sample offset within the buffer for this event
|
||||
uint16_t space_id; // event space, see clap_host_event_registry
|
||||
uint16_t type; // event type
|
||||
uint32_t flags; // see clap_event_flags
|
||||
} clap_event_header_t;
|
||||
|
||||
// The clap core event space
|
||||
static const CLAP_CONSTEXPR uint16_t CLAP_CORE_EVENT_SPACE_ID = 0;
|
||||
|
||||
enum clap_event_flags {
|
||||
// Indicate a live user event, for example a user turning a phisical knob
|
||||
// or playing a physical key.
|
||||
CLAP_EVENT_IS_LIVE = 1 << 0,
|
||||
|
||||
// Indicate that the event should not be recorded.
|
||||
// For example this is useful when a parameter changes because of a MIDI CC,
|
||||
// because if the host records both the MIDI CC automation and the parameter
|
||||
// automation there will be a conflict.
|
||||
CLAP_EVENT_DONT_RECORD = 1 << 1,
|
||||
};
|
||||
|
||||
// Some of the following events overlap, a note on can be expressed with:
|
||||
// - CLAP_EVENT_NOTE_ON
|
||||
// - CLAP_EVENT_MIDI
|
||||
// - CLAP_EVENT_MIDI2
|
||||
//
|
||||
// The preferred way of sending a note event is to use CLAP_EVENT_NOTE_*.
|
||||
//
|
||||
// The same event must not be sent twice: it is forbidden to send a the same note on
|
||||
// encoded with both CLAP_EVENT_NOTE_ON and CLAP_EVENT_MIDI.
|
||||
//
|
||||
// The plugins are encouraged to be able to handle note events encoded as raw midi or midi2,
|
||||
// or implement clap_plugin_event_filter and reject raw midi and midi2 events.
|
||||
enum {
|
||||
// NOTE_ON and NOTE_OFF represents a key pressed and key released event.
|
||||
// A NOTE_ON with a velocity of 0 is valid and should not be interpreted as a NOTE_OFF.
|
||||
//
|
||||
// NOTE_CHOKE is meant to choke the voice(s), like in a drum machine when a closed hihat
|
||||
// chokes an open hihat. This event can be sent by the host to the plugin. Here two use case:
|
||||
// - a plugin is inside a drum pad in Bitwig Studio's drum machine, and this pad is choked by
|
||||
// another one
|
||||
// - the user double clicks the DAW's stop button in the transport which then stops the sound on
|
||||
// every tracks
|
||||
//
|
||||
// NOTE_END is sent by the plugin to the host. The port, channel, key and note_id are those given
|
||||
// by the host in the NOTE_ON event. In other words, this event is matched against the
|
||||
// plugin's note input port.
|
||||
// NOTE_END is useful to help the host to match the plugin's voice life time.
|
||||
//
|
||||
// When using polyphonic modulations, the host has to allocate and release voices for its
|
||||
// polyphonic modulator. Yet only the plugin effectively knows when the host should terminate
|
||||
// a voice. NOTE_END solves that issue in a non-intrusive and cooperative way.
|
||||
//
|
||||
// CLAP assumes that the host will allocate a unique voice on NOTE_ON event for a given port,
|
||||
// channel and key. This voice will run until the plugin will instruct the host to terminate
|
||||
// it by sending a NOTE_END event.
|
||||
//
|
||||
// Consider the following sequence:
|
||||
// - process()
|
||||
// Host->Plugin NoteOn(port:0, channel:0, key:16, time:t0)
|
||||
// Host->Plugin NoteOn(port:0, channel:0, key:64, time:t0)
|
||||
// Host->Plugin NoteOff(port:0, channel:0, key:16, t1)
|
||||
// Host->Plugin NoteOff(port:0, channel:0, key:64, t1)
|
||||
// # on t2, both notes did terminate
|
||||
// Host->Plugin NoteOn(port:0, channel:0, key:64, t3)
|
||||
// # Here the plugin finished to process all the frames and will tell the host
|
||||
// # to terminate the voice on key 16 but not 64, because a note has been started at t3
|
||||
// Plugin->Host NoteEnd(port:0, channel:0, key:16, time:ignored)
|
||||
//
|
||||
// Those four events use clap_event_note.
|
||||
CLAP_EVENT_NOTE_ON,
|
||||
CLAP_EVENT_NOTE_OFF,
|
||||
CLAP_EVENT_NOTE_CHOKE,
|
||||
CLAP_EVENT_NOTE_END,
|
||||
|
||||
// Represents a note expression.
|
||||
// Uses clap_event_note_expression.
|
||||
CLAP_EVENT_NOTE_EXPRESSION,
|
||||
|
||||
// PARAM_VALUE sets the parameter's value; uses clap_event_param_value.
|
||||
// PARAM_MOD sets the parameter's modulation amount; uses clap_event_param_mod.
|
||||
//
|
||||
// The value heard is: param_value + param_mod.
|
||||
//
|
||||
// In case of a concurrent global value/modulation versus a polyphonic one,
|
||||
// the voice should only use the polyphonic one and the polyphonic modulation
|
||||
// amount will already include the monophonic signal.
|
||||
CLAP_EVENT_PARAM_VALUE,
|
||||
CLAP_EVENT_PARAM_MOD,
|
||||
|
||||
// Indicates that the user started or finished to adjust a knob.
|
||||
// This is not mandatory to wrap parameter changes with gesture events, but this improves a lot
|
||||
// the user experience when recording automation or overriding automation playback.
|
||||
// Uses clap_event_param_gesture.
|
||||
CLAP_EVENT_PARAM_GESTURE_BEGIN,
|
||||
CLAP_EVENT_PARAM_GESTURE_END,
|
||||
|
||||
CLAP_EVENT_TRANSPORT, // update the transport info; clap_event_transport
|
||||
CLAP_EVENT_MIDI, // raw midi event; clap_event_midi
|
||||
CLAP_EVENT_MIDI_SYSEX, // raw midi sysex event; clap_event_midi_sysex
|
||||
CLAP_EVENT_MIDI2, // raw midi 2 event; clap_event_midi2
|
||||
};
|
||||
|
||||
// Note on, off, end and choke events.
|
||||
// In the case of note choke or end events:
|
||||
// - the velocity is ignored.
|
||||
// - key and channel are used to match active notes, a value of -1 matches all.
|
||||
typedef struct clap_event_note {
|
||||
clap_event_header_t header;
|
||||
|
||||
int32_t note_id; // -1 if unspecified, otherwise >=0
|
||||
int16_t port_index;
|
||||
int16_t channel; // 0..15
|
||||
int16_t key; // 0..127
|
||||
double velocity; // 0..1
|
||||
} clap_event_note_t;
|
||||
|
||||
enum {
|
||||
// with 0 < x <= 4, plain = 20 * log(x)
|
||||
CLAP_NOTE_EXPRESSION_VOLUME,
|
||||
|
||||
// pan, 0 left, 0.5 center, 1 right
|
||||
CLAP_NOTE_EXPRESSION_PAN,
|
||||
|
||||
// relative tuning in semitone, from -120 to +120
|
||||
CLAP_NOTE_EXPRESSION_TUNING,
|
||||
|
||||
// 0..1
|
||||
CLAP_NOTE_EXPRESSION_VIBRATO,
|
||||
CLAP_NOTE_EXPRESSION_EXPRESSION,
|
||||
CLAP_NOTE_EXPRESSION_BRIGHTNESS,
|
||||
CLAP_NOTE_EXPRESSION_PRESSURE,
|
||||
};
|
||||
typedef int32_t clap_note_expression;
|
||||
|
||||
typedef struct clap_event_note_expression {
|
||||
clap_event_header_t header;
|
||||
|
||||
clap_note_expression expression_id;
|
||||
|
||||
// target a specific note_id, port, key and channel, -1 for global
|
||||
int32_t note_id;
|
||||
int16_t port_index;
|
||||
int16_t channel;
|
||||
int16_t key;
|
||||
|
||||
double value; // see expression for the range
|
||||
} clap_event_note_expression_t;
|
||||
|
||||
typedef struct clap_event_param_value {
|
||||
clap_event_header_t header;
|
||||
|
||||
// target parameter
|
||||
clap_id param_id; // @ref clap_param_info.id
|
||||
void *cookie; // @ref clap_param_info.cookie
|
||||
|
||||
// target a specific note_id, port, key and channel, -1 for global
|
||||
int32_t note_id;
|
||||
int16_t port_index;
|
||||
int16_t channel;
|
||||
int16_t key;
|
||||
|
||||
double value;
|
||||
} clap_event_param_value_t;
|
||||
|
||||
typedef struct clap_event_param_mod {
|
||||
clap_event_header_t header;
|
||||
|
||||
// target parameter
|
||||
clap_id param_id; // @ref clap_param_info.id
|
||||
void *cookie; // @ref clap_param_info.cookie
|
||||
|
||||
// target a specific note_id, port, key and channel, -1 for global
|
||||
int32_t note_id;
|
||||
int16_t port_index;
|
||||
int16_t channel;
|
||||
int16_t key;
|
||||
|
||||
double amount; // modulation amount
|
||||
} clap_event_param_mod_t;
|
||||
|
||||
typedef struct clap_event_param_gesture {
|
||||
clap_event_header_t header;
|
||||
|
||||
// target parameter
|
||||
clap_id param_id; // @ref clap_param_info.id
|
||||
} clap_event_param_gesture_t;
|
||||
|
||||
enum clap_transport_flags {
|
||||
CLAP_TRANSPORT_HAS_TEMPO = 1 << 0,
|
||||
CLAP_TRANSPORT_HAS_BEATS_TIMELINE = 1 << 1,
|
||||
CLAP_TRANSPORT_HAS_SECONDS_TIMELINE = 1 << 2,
|
||||
CLAP_TRANSPORT_HAS_TIME_SIGNATURE = 1 << 3,
|
||||
CLAP_TRANSPORT_IS_PLAYING = 1 << 4,
|
||||
CLAP_TRANSPORT_IS_RECORDING = 1 << 5,
|
||||
CLAP_TRANSPORT_IS_LOOP_ACTIVE = 1 << 6,
|
||||
CLAP_TRANSPORT_IS_WITHIN_PRE_ROLL = 1 << 7,
|
||||
};
|
||||
|
||||
typedef struct clap_event_transport {
|
||||
clap_event_header_t header;
|
||||
|
||||
uint32_t flags; // see clap_transport_flags
|
||||
|
||||
clap_beattime song_pos_beats; // position in beats
|
||||
clap_sectime song_pos_seconds; // position in seconds
|
||||
|
||||
double tempo; // in bpm
|
||||
double tempo_inc; // tempo increment for each samples and until the next
|
||||
// time info event
|
||||
|
||||
clap_beattime loop_start_beats;
|
||||
clap_beattime loop_end_beats;
|
||||
clap_sectime loop_start_seconds;
|
||||
clap_sectime loop_end_seconds;
|
||||
|
||||
clap_beattime bar_start; // start pos of the current bar
|
||||
int32_t bar_number; // bar at song pos 0 has the number 0
|
||||
|
||||
uint16_t tsig_num; // time signature numerator
|
||||
uint16_t tsig_denom; // time signature denominator
|
||||
} clap_event_transport_t;
|
||||
|
||||
typedef struct clap_event_midi {
|
||||
clap_event_header_t header;
|
||||
|
||||
uint16_t port_index;
|
||||
uint8_t data[3];
|
||||
} clap_event_midi_t;
|
||||
|
||||
typedef struct clap_event_midi_sysex {
|
||||
clap_event_header_t header;
|
||||
|
||||
uint16_t port_index;
|
||||
const uint8_t *buffer; // midi buffer
|
||||
uint32_t size;
|
||||
} clap_event_midi_sysex_t;
|
||||
|
||||
// While it is possible to use a series of midi2 event to send a sysex,
|
||||
// prefer clap_event_midi_sysex if possible for efficiency.
|
||||
typedef struct clap_event_midi2 {
|
||||
clap_event_header_t header;
|
||||
|
||||
uint16_t port_index;
|
||||
uint32_t data[4];
|
||||
} clap_event_midi2_t;
|
||||
|
||||
// Input event list, events must be sorted by time.
|
||||
typedef struct clap_input_events {
|
||||
void *ctx; // reserved pointer for the list
|
||||
|
||||
uint32_t (*size)(const struct clap_input_events *list);
|
||||
|
||||
// Don't free the returned event, it belongs to the list
|
||||
const clap_event_header_t *(*get)(const struct clap_input_events *list, uint32_t index);
|
||||
} clap_input_events_t;
|
||||
|
||||
// Output event list, events must be sorted by time.
|
||||
typedef struct clap_output_events {
|
||||
void *ctx; // reserved pointer for the list
|
||||
|
||||
// Pushes a copy of the event
|
||||
// returns false if the event could not be pushed to the queue (out of memory?)
|
||||
bool (*try_push)(const struct clap_output_events *list, const clap_event_header_t *event);
|
||||
} clap_output_events_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,73 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../string-sizes.h"
|
||||
#include "../plugin.h"
|
||||
|
||||
/// @page Audio Ports Config
|
||||
///
|
||||
/// This extension provides a way for the plugin to describe possible ports configurations, for
|
||||
/// example mono, stereo, surround, ... and a way for the host to select a configuration.
|
||||
///
|
||||
/// After the plugin initialization, the host may scan the list of configurations and eventually
|
||||
/// select one that fits the plugin context. The host can only select a configuration if the plugin
|
||||
/// is deactivated.
|
||||
///
|
||||
/// A configuration is a very simple description of the audio ports:
|
||||
/// - it describes the main input and output ports
|
||||
/// - it has a name that can be displayed to the user
|
||||
///
|
||||
/// The idea behind the configurations, is to let the user choose one via a menu.
|
||||
///
|
||||
/// Plugin with very complex configuration possibilities should let the user configure the ports
|
||||
/// from the plugin GUI, and call @ref clap_host_audio_ports.rescan(CLAP_AUDIO_PORTS_RESCAN_ALL).
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_AUDIO_PORTS_CONFIG[] = "clap.audio-ports-config";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Minimalistic description of ports configuration
|
||||
typedef struct clap_audio_ports_config {
|
||||
clap_id id;
|
||||
char name[CLAP_NAME_SIZE];
|
||||
|
||||
uint32_t input_port_count;
|
||||
uint32_t output_port_count;
|
||||
|
||||
// main input info
|
||||
bool has_main_input;
|
||||
uint32_t main_input_channel_count;
|
||||
const char *main_input_port_type;
|
||||
|
||||
// main output info
|
||||
bool has_main_output;
|
||||
uint32_t main_output_channel_count;
|
||||
const char *main_output_port_type;
|
||||
} clap_audio_ports_config_t;
|
||||
|
||||
// The audio ports config scan has to be done while the plugin is deactivated.
|
||||
typedef struct clap_plugin_audio_ports_config {
|
||||
// gets the number of available configurations
|
||||
// [main-thread]
|
||||
uint32_t (*count)(const clap_plugin_t *plugin);
|
||||
|
||||
// gets information about a configuration
|
||||
// [main-thread]
|
||||
bool (*get)(const clap_plugin_t *plugin, uint32_t index, clap_audio_ports_config_t *config);
|
||||
|
||||
// selects the configuration designated by id
|
||||
// returns true if the configuration could be applied
|
||||
// [main-thread,plugin-deactivated]
|
||||
bool (*select)(const clap_plugin_t *plugin, clap_id config_id);
|
||||
} clap_plugin_audio_ports_config_t;
|
||||
|
||||
typedef struct clap_host_audio_ports_config {
|
||||
// Rescan the full list of configs.
|
||||
// [main-thread]
|
||||
void (*rescan)(const clap_host_t *host);
|
||||
} clap_host_audio_ports_config_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,114 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
#include "../string-sizes.h"
|
||||
|
||||
/// @page Audio Ports
|
||||
///
|
||||
/// This extension provides a way for the plugin to describe its current audio ports.
|
||||
///
|
||||
/// If the plugin does not implement this extension, it won't have audio ports.
|
||||
///
|
||||
/// 32 bits support is required for both host and plugins. 64 bits audio is optional.
|
||||
///
|
||||
/// The plugin is only allowed to change its ports configuration while it is deactivated.
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_AUDIO_PORTS[] = "clap.audio-ports";
|
||||
static CLAP_CONSTEXPR const char CLAP_PORT_MONO[] = "mono";
|
||||
static CLAP_CONSTEXPR const char CLAP_PORT_STEREO[] = "stereo";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
// This port is the main audio input or output.
|
||||
// There can be only one main input and main output.
|
||||
// Main port must be at index 0.
|
||||
CLAP_AUDIO_PORT_IS_MAIN = 1 << 0,
|
||||
|
||||
// The port can be used with 64 bits audio
|
||||
CLAP_AUDIO_PORT_SUPPORTS_64BITS = 1 << 1,
|
||||
|
||||
// 64 bits audio is preferred with this port
|
||||
CLAP_AUDIO_PORT_PREFERS_64BITS = 1 << 2,
|
||||
|
||||
// This port must be used with the same sample size as all the other ports which have this flags.
|
||||
// In other words if all ports have this flags then the plugin may either be used entirely with
|
||||
// 64 bits audio or 32 bits audio, but it can't be mixed.
|
||||
CLAP_AUDIO_PORT_REQUIRES_COMMON_SAMPLE_SIZE = 1 << 3,
|
||||
};
|
||||
|
||||
typedef struct clap_audio_port_info {
|
||||
clap_id id; // stable identifier
|
||||
char name[CLAP_NAME_SIZE]; // displayable name
|
||||
|
||||
uint32_t flags;
|
||||
uint32_t channel_count;
|
||||
|
||||
// If null or empty then it is unspecified (arbitrary audio).
|
||||
// This filed can be compared against:
|
||||
// - CLAP_PORT_MONO
|
||||
// - CLAP_PORT_STEREO
|
||||
// - CLAP_PORT_SURROUND (defined in the surround extension)
|
||||
// - CLAP_PORT_AMBISONIC (defined in the ambisonic extension)
|
||||
// - CLAP_PORT_CV (defined in the cv extension)
|
||||
//
|
||||
// An extension can provide its own port type and way to inspect the channels.
|
||||
const char *port_type;
|
||||
|
||||
// in-place processing: allow the host to use the same buffer for input and output
|
||||
// if supported set the pair port id.
|
||||
// if not supported set to CLAP_INVALID_ID
|
||||
clap_id in_place_pair;
|
||||
} clap_audio_port_info_t;
|
||||
|
||||
// The audio ports scan has to be done while the plugin is deactivated.
|
||||
typedef struct clap_plugin_audio_ports {
|
||||
// number of ports, for either input or output
|
||||
// [main-thread]
|
||||
uint32_t (*count)(const clap_plugin_t *plugin, bool is_input);
|
||||
|
||||
// get info about about an audio port.
|
||||
// [main-thread]
|
||||
bool (*get)(const clap_plugin_t *plugin,
|
||||
uint32_t index,
|
||||
bool is_input,
|
||||
clap_audio_port_info_t *info);
|
||||
} clap_plugin_audio_ports_t;
|
||||
|
||||
enum {
|
||||
// The ports name did change, the host can scan them right away.
|
||||
CLAP_AUDIO_PORTS_RESCAN_NAMES = 1 << 0,
|
||||
|
||||
// [!active] The flags did change
|
||||
CLAP_AUDIO_PORTS_RESCAN_FLAGS = 1 << 1,
|
||||
|
||||
// [!active] The channel_count did change
|
||||
CLAP_AUDIO_PORTS_RESCAN_CHANNEL_COUNT = 1 << 2,
|
||||
|
||||
// [!active] The port type did change
|
||||
CLAP_AUDIO_PORTS_RESCAN_PORT_TYPE = 1 << 3,
|
||||
|
||||
// [!active] The in-place pair did change, this requires.
|
||||
CLAP_AUDIO_PORTS_RESCAN_IN_PLACE_PAIR = 1 << 4,
|
||||
|
||||
// [!active] The list of ports have changed: entries have been removed/added.
|
||||
CLAP_AUDIO_PORTS_RESCAN_LIST = 1 << 5,
|
||||
};
|
||||
|
||||
typedef struct clap_host_audio_ports {
|
||||
// Checks if the host allows a plugin to change a given aspect of the audio ports definition.
|
||||
// [main-thread]
|
||||
bool (*is_rescan_flag_supported)(const clap_host_t *host, uint32_t flag);
|
||||
|
||||
// Rescan the full list of audio ports according to the flags.
|
||||
// It is illegal to ask the host to rescan with a flag that is not supported.
|
||||
// Certain flags require the plugin to be de-activated.
|
||||
// [main-thread]
|
||||
void (*rescan)(const clap_host_t *host, uint32_t flags);
|
||||
} clap_host_audio_ports_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,55 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../plugin.h"
|
||||
|
||||
// This extension can be used to specify the channel mapping used by the plugin.
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_AMBISONIC[] = "clap.ambisonic.draft/0";
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_PORT_AMBISONIC[] = "ambisonic";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
// FuMa channel ordering
|
||||
CLAP_AMBISONIC_FUMA = 0,
|
||||
|
||||
// ACN channel ordering
|
||||
CLAP_AMBISONIC_ACN = 1,
|
||||
};
|
||||
|
||||
enum {
|
||||
CLAP_AMBISONIC_NORMALIZATION_MAXN = 0,
|
||||
CLAP_AMBISONIC_NORMALIZATION_SN3D = 1,
|
||||
CLAP_AMBISONIC_NORMALIZATION_N3D = 2,
|
||||
CLAP_AMBISONIC_NORMALIZATION_SN2D = 3,
|
||||
CLAP_AMBISONIC_NORMALIZATION_N2D = 4,
|
||||
};
|
||||
|
||||
typedef struct clap_ambisonic_info {
|
||||
uint32_t ordering;
|
||||
uint32_t normalization;
|
||||
} clap_ambisonic_info_t;
|
||||
|
||||
typedef struct clap_plugin_ambisonic {
|
||||
// Returns true on success
|
||||
// [main-thread]
|
||||
bool (*get_info)(const clap_plugin_t *plugin,
|
||||
bool is_input,
|
||||
uint32_t port_index,
|
||||
clap_ambisonic_info_t *info);
|
||||
|
||||
} clap_plugin_ambisonic_t;
|
||||
|
||||
typedef struct clap_host_ambisonic {
|
||||
// Informs the host that the info have changed.
|
||||
// The info can only change when the plugin is de-activated.
|
||||
// [main-thread]
|
||||
void (*changed)(const clap_host_t *host);
|
||||
} clap_host_ambisonic_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,31 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../plugin.h"
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_CHECK_FOR_UPDATE[] = "clap.check_for_update.draft/0";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct clap_check_for_update_info {
|
||||
const char *version; // latest version
|
||||
const char *release_date; // YYYY-MM-DD
|
||||
const char *url; // url to a download page which the user can visit
|
||||
|
||||
bool is_preview; // true if this version is a preview release
|
||||
} clap_check_for_update_info_t;
|
||||
|
||||
typedef struct clap_plugin_check_for_update {
|
||||
// [main-thread]
|
||||
void (*check)(const clap_plugin_t *plugin, bool include_preview);
|
||||
} clap_plugin_check_for_update;
|
||||
|
||||
typedef struct clap_host_check_for_update {
|
||||
// [main-thread]
|
||||
void (*on_new_version)(const clap_host_t *host, const clap_check_for_update_info_t *update_info);
|
||||
} clap_host_check_for_update_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,44 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../plugin.h"
|
||||
|
||||
// This extension can be used to specify the cv channel type used by the plugin.
|
||||
// Work in progress, suggestions are welcome
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_CV[] = "clap.cv.draft/0";
|
||||
static CLAP_CONSTEXPR const char CLAP_PORT_CV[] = "cv";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
// TODO: standardize values?
|
||||
CLAP_CV_VALUE = 0,
|
||||
CLAP_CV_GATE = 1,
|
||||
CLAP_CV_PITCH = 2,
|
||||
};
|
||||
|
||||
// TODO: maybe we want a channel_info instead, where we could have more details about the supported
|
||||
// ranges?
|
||||
|
||||
typedef struct clap_plugin_cv {
|
||||
// Returns true on success.
|
||||
// [main-thread]
|
||||
bool (*get_channel_type)(const clap_plugin_t *plugin,
|
||||
bool is_input,
|
||||
uint32_t port_index,
|
||||
uint32_t channel_index,
|
||||
uint32_t *channel_type);
|
||||
} clap_plugin_cv_t;
|
||||
|
||||
typedef struct clap_host_cv {
|
||||
// Informs the host that the channels type have changed.
|
||||
// The channels type can only change when the plugin is de-activated.
|
||||
// [main-thread,!active]
|
||||
void (*changed)(const clap_host_t *host);
|
||||
} clap_host_cv_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,85 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../plugin.h"
|
||||
#include "../../string-sizes.h"
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_FILE_REFERENCE[] = "clap.file-reference.draft/0";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// @page File Reference
|
||||
///
|
||||
/// This extension provides a way for the host to know about files which are used
|
||||
/// by the plugin, like a wavetable, a sample, ...
|
||||
///
|
||||
/// The host can then:
|
||||
/// - collect and save
|
||||
/// - search for missing files by using:
|
||||
/// - filename
|
||||
/// - hash
|
||||
/// - file size
|
||||
/// - be aware that some external file references are marked as dirty and needs to be saved.
|
||||
///
|
||||
/// Regarding the hashing algorithm, as of 2022 BLAKE3 seems to be the best choice in regards to
|
||||
/// performances and robustness while also providing a very small pure C library with permissive
|
||||
/// licensing. For more info see https://github.com/BLAKE3-team/BLAKE3
|
||||
///
|
||||
/// This extension only expose one hashing algorithm on purpose.
|
||||
|
||||
// This describes a file currently used by the plugin
|
||||
typedef struct clap_file_reference {
|
||||
clap_id resource_id;
|
||||
bool belongs_to_plugin_collection;
|
||||
|
||||
size_t path_capacity; // [in] the number of bytes reserved in path
|
||||
size_t path_size; // [out] the actual length of the path, can be bigger than path_capacity
|
||||
char *path; // [in,out] path to the file on the disk, must be null terminated, and maybe
|
||||
// truncated if the capacity is less than the size
|
||||
} clap_file_reference_t;
|
||||
|
||||
typedef struct clap_plugin_file_reference {
|
||||
// returns the number of file reference this plugin has
|
||||
// [main-thread]
|
||||
uint32_t (*count)(const clap_plugin_t *plugin);
|
||||
|
||||
// gets the file reference at index
|
||||
// returns true on success
|
||||
// [main-thread]
|
||||
bool (*get)(const clap_plugin_t *plugin, uint32_t index, clap_file_reference_t *file_reference);
|
||||
|
||||
// This method can be called even if the file is missing.
|
||||
// So the plugin is encouraged to store the digest in its state.
|
||||
//
|
||||
// digest is an array of 32 bytes.
|
||||
//
|
||||
// [main-thread]
|
||||
bool (*get_blake3_digest)(const clap_plugin_t *plugin, clap_id resource_id, uint8_t *digest);
|
||||
|
||||
// This method can be called even if the file is missing.
|
||||
// So the plugin is encouraged to store the file's size in its state.
|
||||
//
|
||||
// [main-thread]
|
||||
bool (*get_file_size)(const clap_plugin_t *plugin, clap_id resource_id, uint64_t *size);
|
||||
|
||||
// updates the path to a file reference
|
||||
// [main-thread]
|
||||
bool (*update_path)(const clap_plugin_t *plugin, clap_id resource_id, const char *path);
|
||||
|
||||
// [main-thread]
|
||||
bool (*save_resources)(const clap_plugin_t *plugin);
|
||||
} clap_plugin_file_reference_t;
|
||||
|
||||
typedef struct clap_host_file_reference {
|
||||
// informs the host that the file references have changed, the host should schedule a full rescan
|
||||
// [main-thread]
|
||||
void (*changed)(const clap_host_t *host);
|
||||
|
||||
// [main-thread]
|
||||
void (*set_dirty)(const clap_host_t *host, clap_id resource_id);
|
||||
} clap_host_file_reference;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,40 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../plugin.h"
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_MIDI_MAPPINGS[] = "clap.midi-mappings.draft/0";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
CLAP_MIDI_MAPPING_CC7,
|
||||
CLAP_MIDI_MAPPING_CC14,
|
||||
CLAP_MIDI_MAPPING_RPN,
|
||||
CLAP_MIDI_MAPPING_NRPN,
|
||||
};
|
||||
typedef int32_t clap_midi_mapping_type;
|
||||
|
||||
typedef struct clap_midi_mapping {
|
||||
int32_t channel;
|
||||
int32_t number;
|
||||
clap_id param_id;
|
||||
} clap_midi_mapping_t;
|
||||
|
||||
typedef struct clap_plugin_midi_mappings {
|
||||
// [main-thread]
|
||||
uint32_t (*count)(const clap_plugin_t *plugin);
|
||||
|
||||
// [main-thread]
|
||||
bool (*get)(const clap_plugin_t *plugin, uint32_t index, clap_midi_mapping_t *mapping);
|
||||
} clap_plugin_midi_mappings_t;
|
||||
|
||||
typedef struct clap_host_midi_mappings {
|
||||
// [main-thread]
|
||||
void (*changed)(const clap_host_t *host);
|
||||
} clap_host_midi_mappings_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,19 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../plugin.h"
|
||||
|
||||
static const char CLAP_EXT_PRESET_LOAD[] = "clap.preset-load.draft/0";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct clap_plugin_preset_load {
|
||||
// Loads a preset in the plugin native preset file format from a path.
|
||||
// [main-thread]
|
||||
bool (*from_file)(const clap_plugin_t *plugin, const char *path);
|
||||
} clap_plugin_preset_load_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,45 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../plugin.h"
|
||||
#include "../../string-sizes.h"
|
||||
|
||||
// This extensions provides a set a pages, where each page contains up to 8 controls.
|
||||
// Those controls are param_id, and they are meant to be mapped onto a physical controller.
|
||||
// We chose 8 because this what most controllers offers, and it is more or less a standard.
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_QUICK_CONTROLS[] = "clap.quick-controls.draft/0";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum { CLAP_QUICK_CONTROLS_COUNT = 8 };
|
||||
|
||||
typedef struct clap_quick_controls_page {
|
||||
clap_id id;
|
||||
char name[CLAP_NAME_SIZE];
|
||||
clap_id param_ids[CLAP_QUICK_CONTROLS_COUNT];
|
||||
} clap_quick_controls_page_t;
|
||||
|
||||
typedef struct clap_plugin_quick_controls {
|
||||
// [main-thread]
|
||||
uint32_t (*count)(const clap_plugin_t *plugin);
|
||||
|
||||
// [main-thread]
|
||||
bool (*get)(const clap_plugin_t *plugin, uint32_t page_index, clap_quick_controls_page_t *page);
|
||||
} clap_plugin_quick_controls_t;
|
||||
|
||||
typedef struct clap_host_quick_controls {
|
||||
// Informs the host that the quick controls have changed.
|
||||
// [main-thread]
|
||||
void (*changed)(const clap_host_t *host);
|
||||
|
||||
// Suggest a page to the host because it correspond to what the user is currently editing in the
|
||||
// plugin's GUI.
|
||||
// [main-thread]
|
||||
void (*suggest_page)(const clap_host_t *host, clap_id page_id);
|
||||
} clap_host_quick_controls_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,87 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../plugin.h"
|
||||
|
||||
// This extension can be used to specify the channel mapping used by the plugin.
|
||||
//
|
||||
// To have a consistent surround features across all the plugin instances,
|
||||
// here is the proposed workflow:
|
||||
// 1. the plugin queries the host preferred channel mapping and
|
||||
// adjusts its configuration to match it.
|
||||
// 2. the host checks how the plugin is effectively configured and honors it.
|
||||
//
|
||||
// If the host decides to change the project's surround setup:
|
||||
// 1. deactivate the plugin
|
||||
// 2. host calls clap_plugin_surround->changed()
|
||||
// 3. plugin calls clap_host_surround->get_preferred_channel_map()
|
||||
// 4. plugin eventualy calls clap_host_surround->changed()
|
||||
// 5. host calls clap_plugin_surround->get_channel_map() if changed
|
||||
// 6. host activates the plugin and can start processing audio
|
||||
//
|
||||
// If the plugin wants to change its surround setup:
|
||||
// 1. call host->request_restart() if the plugin is active
|
||||
// 2. once deactivated plugin calls clap_host_surround->changed()
|
||||
// 3. host calls clap_plugin_surround->get_channel_map()
|
||||
// 4. host activates the plugin and can start processing audio
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_SURROUND[] = "clap.surround.draft/1";
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_PORT_SURROUND[] = "surround";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
CLAP_SURROUND_FL = 0, // Front Left
|
||||
CLAP_SURROUND_FR = 1, // Front Right
|
||||
CLAP_SURROUND_FC = 2, // Front Center
|
||||
CLAP_SURROUND_LFE = 3, // Low Frequency
|
||||
CLAP_SURROUND_BL = 4, // Back Left
|
||||
CLAP_SURROUND_BR = 5, // Back Right
|
||||
CLAP_SURROUND_FLC = 6, // Front Left of Center
|
||||
CLAP_SURROUND_FRC = 7, // Front Right of Center
|
||||
CLAP_SURROUND_BC = 8, // Back Center
|
||||
CLAP_SURROUND_SL = 9, // Side Left
|
||||
CLAP_SURROUND_SR = 10, // Side Right
|
||||
CLAP_SURROUND_TC = 11, // Top Center
|
||||
CLAP_SURROUND_TFL = 12, // Front Left Height
|
||||
CLAP_SURROUND_TFC = 13, // Front Center Height
|
||||
CLAP_SURROUND_TFR = 14, // Front Right Height
|
||||
CLAP_SURROUND_TBL = 15, // Rear Left Height
|
||||
CLAP_SURROUND_TBC = 16, // Rear Center Height
|
||||
CLAP_SURROUND_TBR = 17, // Rear Right Height
|
||||
};
|
||||
|
||||
typedef struct clap_plugin_surround {
|
||||
// Stores into the channel_map array, the surround identifer of each channels.
|
||||
// Returns the number of elements stored in channel_map
|
||||
// [main-thread]
|
||||
uint32_t (*get_channel_map)(const clap_plugin_t *plugin,
|
||||
bool is_input,
|
||||
uint32_t port_index,
|
||||
uint8_t *channel_map,
|
||||
uint32_t channel_map_capacity);
|
||||
|
||||
// Informs the plugin that the host preferred channel map has changed.
|
||||
// [main-thread]
|
||||
void (*changed)(const clap_plugin_t *plugin);
|
||||
} clap_plugin_surround_t;
|
||||
|
||||
typedef struct clap_host_surround {
|
||||
// Informs the host that the channel map have changed.
|
||||
// The channel map can only change when the plugin is de-activated.
|
||||
// [main-thread]
|
||||
void (*changed)(const clap_host_t *host);
|
||||
|
||||
// Ask the host what is the prefered/project surround channel map.
|
||||
// [main-thread]
|
||||
void (*get_preferred_channel_map)(const clap_host_t *host,
|
||||
uint8_t *channel_map,
|
||||
uint32_t channel_map_capacity,
|
||||
uint32_t *channel_count);
|
||||
} clap_host_surround_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,37 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../plugin.h"
|
||||
#include "../../color.h"
|
||||
#include "../../string-sizes.h"
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_TRACK_INFO[] = "clap.track-info.draft/0";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct clap_track_info {
|
||||
clap_id id;
|
||||
int32_t index;
|
||||
char name[CLAP_NAME_SIZE];
|
||||
char path[CLAP_PATH_SIZE]; // Like "/group1/group2/drum-machine/drum-pad-13"
|
||||
int32_t channel_count;
|
||||
const char *audio_port_type;
|
||||
clap_color_t color;
|
||||
bool is_return_track;
|
||||
} clap_track_info_t;
|
||||
|
||||
typedef struct clap_plugin_track_info {
|
||||
// [main-thread]
|
||||
void (*changed)(const clap_plugin_t *plugin);
|
||||
} clap_plugin_track_info_t;
|
||||
|
||||
typedef struct clap_host_track_info {
|
||||
// Get info about the track the plugin belongs to.
|
||||
// [main-thread]
|
||||
bool (*get)(const clap_host_t *host, clap_track_info_t *info);
|
||||
} clap_host_track_info_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,64 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../plugin.h"
|
||||
|
||||
// This extension let the plugin submit transport requests to the host.
|
||||
// The host has no obligation to execute those request, so the interface maybe
|
||||
// partially working.
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_TRANSPORT_CONTROL[] = "clap.transport-control.draft/0";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct clap_host_transport_control {
|
||||
// Jumps back to the start point and starts the transport
|
||||
// [main-thread]
|
||||
void (*request_start)(const clap_host_t *host);
|
||||
|
||||
// Stops the transport, and jumps to the start point
|
||||
// [main-thread]
|
||||
void (*request_stop)(const clap_host_t *host);
|
||||
|
||||
// If not playing, starts the transport from its current position
|
||||
// [main-thread]
|
||||
void (*request_continue)(const clap_host_t *host);
|
||||
|
||||
// If playing, stops the transport at the current position
|
||||
// [main-thread]
|
||||
void (*request_pause)(const clap_host_t *host);
|
||||
|
||||
// Equivalent to what "space bar" does with most DAW
|
||||
// [main-thread]
|
||||
void (*request_toggle_play)(const clap_host_t *host);
|
||||
|
||||
// Jumps the transport to the given position.
|
||||
// Does not start the transport.
|
||||
// [main-thread]
|
||||
void (*request_jump)(const clap_host_t *host, clap_beattime position);
|
||||
|
||||
// Sets the loop region
|
||||
// [main-thread]
|
||||
void (*request_loop_region)(const clap_host_t *host, clap_beattime start, clap_beattime duration);
|
||||
|
||||
// Toggles looping
|
||||
// [main-thread]
|
||||
void (*request_toggle_loop)(const clap_host_t *host);
|
||||
|
||||
// Enables/Disables looping
|
||||
// [main-thread]
|
||||
void (*request_enable_loop)(const clap_host_t *host, bool is_enabled);
|
||||
|
||||
// Enables/Disables recording
|
||||
// [main-thread]
|
||||
void (*request_record)(const clap_host_t *host, bool is_recording);
|
||||
|
||||
// Toggles recording
|
||||
// [main-thread]
|
||||
void (*request_toggle_record)(const clap_host_t *host);
|
||||
} clap_host_transport_control_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,70 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../plugin.h"
|
||||
#include "../../events.h"
|
||||
#include "../../string-sizes.h"
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_TUNING[] = "clap.tuning.draft/2";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Use clap_host_event_registry->query(host, CLAP_EXT_TUNING, &space_id) to know the event space.
|
||||
//
|
||||
// This event defines the tuning to be used on the given port/channel.
|
||||
typedef struct clap_event_tuning {
|
||||
clap_event_header_t header;
|
||||
|
||||
int16_t port_index; // -1 global
|
||||
int16_t channel; // 0..15, -1 global
|
||||
clap_id tunning_id;
|
||||
} clap_event_tuning_t;
|
||||
|
||||
typedef struct clap_tuning_info {
|
||||
clap_id tuning_id;
|
||||
char name[CLAP_NAME_SIZE];
|
||||
bool is_dynamic; // true if the values may vary with time
|
||||
} clap_tuning_info_t;
|
||||
|
||||
typedef struct clap_plugin_tuning {
|
||||
// Called when a tuning is added or removed from the pool.
|
||||
// [main-thread]
|
||||
void (*changed)(const clap_plugin_t *plugin);
|
||||
} clap_plugin_tuning_t;
|
||||
|
||||
// This extension provides a dynamic tuning table to the plugin.
|
||||
typedef struct clap_host_tuning {
|
||||
// Gets the relative tuning in semitone against equal temperament with A4=440Hz.
|
||||
// The plugin may query the tuning at a rate that makes sense for *low* frequency modulations.
|
||||
//
|
||||
// If the tuning_id is not found or equals to CLAP_INVALID_ID,
|
||||
// then the function shall gracefuly return a sensible value.
|
||||
//
|
||||
// sample_offset is the sample offset from the begining of the current process block.
|
||||
//
|
||||
// should_play(...) should be checked before calling this function.
|
||||
//
|
||||
// [audio-thread & in-process]
|
||||
double (*get_relative)(const clap_host_t *host,
|
||||
clap_id tuning_id,
|
||||
int32_t channel,
|
||||
int32_t key,
|
||||
uint32_t sample_offset);
|
||||
|
||||
// Returns true if the note should be played.
|
||||
// [audio-thread & in-process]
|
||||
bool (*should_play)(const clap_host_t *host, clap_id tuning_id, int32_t channel, int32_t key);
|
||||
|
||||
// Returns the number of tunings in the pool.
|
||||
// [main-thread]
|
||||
uint32_t (*get_tuning_count)(const clap_host_t *host);
|
||||
|
||||
// Gets info about a tuning
|
||||
// [main-thread]
|
||||
bool (*get_info)(const clap_host_t *host, uint32_t tuning_index, clap_tuning_info_t *info);
|
||||
} clap_host_tuning_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,56 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../plugin.h"
|
||||
|
||||
// This extensions indicates the number of voices the synthesizer.
|
||||
// It is useful for the host when performing polyphonic modulations,
|
||||
// because the host needs its own voice management and should try to follow
|
||||
// what the plugin is doing:
|
||||
// - make the host's voice pool coherent with what the plugin has
|
||||
// - turn the host's voice management to mono when the plugin is mono
|
||||
|
||||
static const char CLAP_EXT_VOICE_INFO[] = "clap.voice-info.draft/0";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
// Allows the host to send overlapping NOTE_ON events.
|
||||
// The plugin will then rely upon the note_id to distinguish between them.
|
||||
CLAP_VOICE_INFO_SUPPORTS_OVERLAPPING_NOTES = 1 << 0,
|
||||
};
|
||||
|
||||
typedef struct clap_voice_info {
|
||||
// voice_count is the current number of voices that the patch can use
|
||||
// voice_capacity is the number of voices allocated voices
|
||||
// voice_count should not be confused with the number of active voices.
|
||||
//
|
||||
// 1 <= voice_count <= voice_capacity
|
||||
//
|
||||
// For example, a synth can have a capacity of 8 voices, but be configured
|
||||
// to only use 4 voices: {count: 4, capacity: 8}.
|
||||
//
|
||||
// If the voice_count is 1, then the synth is working in mono and the host
|
||||
// can decide to only use global modulation mapping.
|
||||
uint32_t voice_count;
|
||||
uint32_t voice_capacity;
|
||||
|
||||
uint64_t flags;
|
||||
} clap_voice_info_t;
|
||||
|
||||
typedef struct clap_plugin_voice_info {
|
||||
// gets the voice info, returns true on success
|
||||
// [main-thread && active]
|
||||
bool (*get)(const clap_plugin_t *plugin, clap_voice_info_t *info);
|
||||
} clap_plugin_voice_info_t;
|
||||
|
||||
typedef struct clap_host_voice_info {
|
||||
// informs the host that the voice info have changed
|
||||
// [main-thread]
|
||||
void (*changed)(const clap_host_t *host);
|
||||
} clap_host_voice_info_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,22 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_EVENT_REGISTRY[] = "clap.event-registry";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct clap_host_event_registry {
|
||||
// Queries an event space id.
|
||||
// The space id 0 is reserved for CLAP's core events. See CLAP_CORE_EVENT_SPACE.
|
||||
//
|
||||
// Return false and sets *space to UINT16_MAX if the space name is unknown to the host.
|
||||
// [main-thread]
|
||||
bool (*query)(const clap_host_t *host, const char *space_name, uint16_t *space_id);
|
||||
} clap_host_event_registry_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,218 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
|
||||
/// @page GUI
|
||||
///
|
||||
/// This extension defines how the plugin will present its GUI.
|
||||
///
|
||||
/// There are two approaches:
|
||||
/// 1. the plugin creates a window and embeds it into the host's window
|
||||
/// 2. the plugin creates a floating window
|
||||
///
|
||||
/// Embedding the window gives more control to the host, and feels more integrated.
|
||||
/// Floating window are sometimes the only option due to technical limitations.
|
||||
///
|
||||
/// Showing the GUI works as follow:
|
||||
/// 1. clap_plugin_gui->is_api_supported(), check what can work
|
||||
/// 2. clap_plugin_gui->create(), allocates gui resources
|
||||
/// 3. if the plugin window is floating
|
||||
/// 4. -> clap_plugin_gui->set_transient()
|
||||
/// 5. -> clap_plugin_gui->suggest_title()
|
||||
/// 6. else
|
||||
/// 7. -> clap_plugin_gui->set_scale()
|
||||
/// 8. -> clap_plugin_gui->can_resize()
|
||||
/// 9. -> if resizable and has known size from previous session, clap_plugin_gui->set_size()
|
||||
/// 10. -> else clap_plugin_gui->get_size(), gets initial size
|
||||
/// 11. -> clap_plugin_gui->set_parent()
|
||||
/// 12. clap_plugin_gui->show()
|
||||
/// 13. clap_plugin_gui->hide()/show() ...
|
||||
/// 14. clap_plugin_gui->destroy() when done with the gui
|
||||
///
|
||||
/// Resizing the window (initiated by the plugin, if embedded):
|
||||
/// 1. Plugins calls clap_host_gui->request_resize()
|
||||
/// 2. If the host returns true the new size is accepted,
|
||||
/// the host doesn't have to call clap_plugin_gui->set_size().
|
||||
/// If the host returns false, the new size is rejected.
|
||||
///
|
||||
/// Resizing the window (drag, if embedded)):
|
||||
/// 1. Only possible if clap_plugin_gui->can_resize() returns true
|
||||
/// 2. Mouse drag -> new_size
|
||||
/// 3. clap_plugin_gui->adjust_size(new_size) -> working_size
|
||||
/// 4. clap_plugin_gui->set_size(working_size)
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_GUI[] = "clap.gui";
|
||||
|
||||
// If your windowing API is not listed here, please open an issue and we'll figure it out.
|
||||
// https://github.com/free-audio/clap/issues/new
|
||||
|
||||
// uses physical size
|
||||
// embed using https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setparent
|
||||
static const CLAP_CONSTEXPR char CLAP_WINDOW_API_WIN32[] = "win32";
|
||||
|
||||
// uses logical size, don't call clap_plugin_gui->set_scale()
|
||||
static const CLAP_CONSTEXPR char CLAP_WINDOW_API_COCOA[] = "cocoa";
|
||||
|
||||
// uses physical size
|
||||
// embed using https://specifications.freedesktop.org/xembed-spec/xembed-spec-latest.html
|
||||
static const CLAP_CONSTEXPR char CLAP_WINDOW_API_X11[] = "x11";
|
||||
|
||||
// uses physical size
|
||||
// embed is currently not supported, use floating windows
|
||||
static const CLAP_CONSTEXPR char CLAP_WINDOW_API_WAYLAND[] = "wayland";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void *clap_hwnd;
|
||||
typedef void *clap_nsview;
|
||||
typedef unsigned long clap_xwnd;
|
||||
|
||||
// Represent a window reference.
|
||||
typedef struct clap_window {
|
||||
const char *api; // one of CLAP_WINDOW_API_XXX
|
||||
union {
|
||||
clap_nsview cocoa;
|
||||
clap_xwnd x11;
|
||||
clap_hwnd win32;
|
||||
void *ptr; // for anything defined outside of clap
|
||||
};
|
||||
} clap_window_t;
|
||||
|
||||
// Information to improve window resizement when initiated by the host or window manager.
|
||||
typedef struct clap_gui_resize_hints {
|
||||
bool can_resize_horizontally;
|
||||
bool can_resize_vertically;
|
||||
|
||||
// only if can resize horizontally and vertically
|
||||
bool preseve_aspect_ratio;
|
||||
uint32_t aspect_ratio_width;
|
||||
uint32_t aspect_ratio_height;
|
||||
} clap_gui_resize_hints_t;
|
||||
|
||||
// Size (width, height) is in pixels; the corresponding windowing system extension is
|
||||
// responsible to define if it is physical pixels or logical pixels.
|
||||
typedef struct clap_plugin_gui {
|
||||
// Returns true if the requested gui api is supported
|
||||
// [main-thread]
|
||||
bool (*is_api_supported)(const clap_plugin_t *plugin, const char *api, bool is_floating);
|
||||
|
||||
// Returns true if the plugin has a preferred api.
|
||||
// The host has no obligation to honor the plugin preferrence, this is just a hint.
|
||||
// [main-thread]
|
||||
bool (*get_preferred_api)(const clap_plugin_t *plugin, const char **api, bool *is_floating);
|
||||
|
||||
// Create and allocate all resources necessary for the gui.
|
||||
//
|
||||
// If is_floating is true, then the window will not be managed by the host. The plugin
|
||||
// can set its window to stays above the parent window, see set_transient().
|
||||
// api may be null or blank for floating window.
|
||||
//
|
||||
// If is_floating is false, then the plugin has to embbed its window into the parent window, see
|
||||
// set_parent().
|
||||
//
|
||||
// After this call, the GUI may not be visible yet; don't forget to call show().
|
||||
// [main-thread]
|
||||
bool (*create)(const clap_plugin_t *plugin, const char *api, bool is_floating);
|
||||
|
||||
// Free all resources associated with the gui.
|
||||
// [main-thread]
|
||||
void (*destroy)(const clap_plugin_t *plugin);
|
||||
|
||||
// Set the absolute GUI scaling factor, and override any OS info.
|
||||
// Should not be used if the windowing api relies upon logical pixels.
|
||||
//
|
||||
// If the plugin prefers to work out the scaling factor itself by querying the OS directly,
|
||||
// then ignore the call.
|
||||
//
|
||||
// Returns true if the scaling could be applied
|
||||
// Returns false if the call was ignored, or the scaling could not be applied.
|
||||
// [main-thread]
|
||||
bool (*set_scale)(const clap_plugin_t *plugin, double scale);
|
||||
|
||||
// Get the current size of the plugin UI.
|
||||
// clap_plugin_gui->create() must have been called prior to asking the size.
|
||||
// [main-thread]
|
||||
bool (*get_size)(const clap_plugin_t *plugin, uint32_t *width, uint32_t *height);
|
||||
|
||||
// Returns true if the window is resizeable (mouse drag).
|
||||
// Only for embedded windows.
|
||||
// [main-thread]
|
||||
bool (*can_resize)(const clap_plugin_t *plugin);
|
||||
|
||||
// Returns true if the plugin can provide hints on how to resize the window.
|
||||
// [main-thread]
|
||||
bool (*get_resize_hints)(const clap_plugin_t *plugin, clap_gui_resize_hints_t *hints);
|
||||
|
||||
// If the plugin gui is resizable, then the plugin will calculate the closest
|
||||
// usable size which fits in the given size.
|
||||
// This method does not change the size.
|
||||
//
|
||||
// Only for embedded windows.
|
||||
// [main-thread]
|
||||
bool (*adjust_size)(const clap_plugin_t *plugin, uint32_t *width, uint32_t *height);
|
||||
|
||||
// Sets the window size. Only for embedded windows.
|
||||
// [main-thread]
|
||||
bool (*set_size)(const clap_plugin_t *plugin, uint32_t width, uint32_t height);
|
||||
|
||||
// Embbeds the plugin window into the given window.
|
||||
// [main-thread & !floating]
|
||||
bool (*set_parent)(const clap_plugin_t *plugin, const clap_window_t *window);
|
||||
|
||||
// Set the plugin floating window to stay above the given window.
|
||||
// [main-thread & floating]
|
||||
bool (*set_transient)(const clap_plugin_t *plugin, const clap_window_t *window);
|
||||
|
||||
// Suggests a window title. Only for floating windows.
|
||||
// [main-thread & floating]
|
||||
void (*suggest_title)(const clap_plugin_t *plugin, const char *title);
|
||||
|
||||
// Show the window.
|
||||
// [main-thread]
|
||||
bool (*show)(const clap_plugin_t *plugin);
|
||||
|
||||
// Hide the window, this method do not free the resources, it just hides
|
||||
// the window content. Yet it maybe a good idea to stop painting timers.
|
||||
// [main-thread]
|
||||
bool (*hide)(const clap_plugin_t *plugin);
|
||||
} clap_plugin_gui_t;
|
||||
|
||||
typedef struct clap_host_gui {
|
||||
// The host should call get_resize_hints() again.
|
||||
// [thread-safe]
|
||||
void (*resize_hints_changed)(const clap_host_t *host);
|
||||
|
||||
/* Request the host to resize the client area to width, height.
|
||||
* Return true if the new size is accepted, false otherwise.
|
||||
* The host doesn't have to call set_size().
|
||||
*
|
||||
* Note: if not called from the main thread, then a return value simply means that the host
|
||||
* acknowledge the request and will process it asynchronously. If the request then can't be
|
||||
* satisfied then the host will call set_size() to revert the operation.
|
||||
*
|
||||
* [thread-safe] */
|
||||
bool (*request_resize)(const clap_host_t *host, uint32_t width, uint32_t height);
|
||||
|
||||
/* Request the host to show the plugin gui.
|
||||
* Return true on success, false otherwise.
|
||||
* [thread-safe] */
|
||||
bool (*request_show)(const clap_host_t *host);
|
||||
|
||||
/* Request the host to hide the plugin gui.
|
||||
* Return true on success, false otherwise.
|
||||
* [thread-safe] */
|
||||
bool (*request_hide)(const clap_host_t *host);
|
||||
|
||||
// The floating window has been closed, or the connection to the gui has been lost.
|
||||
//
|
||||
// If was_destroyed is true, then the host must call clap_plugin_gui->destroy() to acknowledge
|
||||
// the gui destruction.
|
||||
// [thread-safe]
|
||||
void (*closed)(const clap_host_t *host, bool was_destroyed);
|
||||
} clap_host_gui_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,28 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_LATENCY[] = "clap.latency";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// The audio ports scan has to be done while the plugin is deactivated.
|
||||
typedef struct clap_plugin_latency {
|
||||
// Returns the plugin latency.
|
||||
// [main-thread]
|
||||
uint32_t (*get)(const clap_plugin_t *plugin);
|
||||
} clap_plugin_latency_t;
|
||||
|
||||
typedef struct clap_host_latency {
|
||||
// Tell the host that the latency changed.
|
||||
// The latency is only allowed to change if the plugin is deactivated.
|
||||
// If the plugin is activated, call host->request_restart()
|
||||
// [main-thread]
|
||||
void (*changed)(const clap_host_t *host);
|
||||
} clap_host_latency_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,33 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_LOG[] = "clap.log";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
CLAP_LOG_DEBUG = 0,
|
||||
CLAP_LOG_INFO = 1,
|
||||
CLAP_LOG_WARNING = 2,
|
||||
CLAP_LOG_ERROR = 3,
|
||||
CLAP_LOG_FATAL = 4,
|
||||
|
||||
// Those severities should be used to report misbehaviour.
|
||||
// The plugin one can be used by a layer between the plugin and the host.
|
||||
CLAP_LOG_HOST_MISBEHAVING = 5,
|
||||
CLAP_LOG_PLUGIN_MISBEHAVING = 6,
|
||||
};
|
||||
typedef int32_t clap_log_severity;
|
||||
|
||||
typedef struct clap_host_log {
|
||||
// Log a message through the host.
|
||||
// [thread-safe]
|
||||
void (*log)(const clap_host_t *host, clap_log_severity severity, const char *msg);
|
||||
} clap_host_log_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,37 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
#include "../string-sizes.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_NOTE_NAME[] = "clap.note-name";
|
||||
|
||||
typedef struct clap_note_name {
|
||||
char name[CLAP_NAME_SIZE];
|
||||
int16_t port; // -1 for every port
|
||||
int16_t key; // -1 for every key
|
||||
int16_t channel; // -1 for every channel
|
||||
} clap_note_name_t;
|
||||
|
||||
typedef struct clap_plugin_note_name {
|
||||
// Return the number of note names
|
||||
// [main-thread]
|
||||
uint32_t (*count)(const clap_plugin_t *plugin);
|
||||
|
||||
// Returns true on success and stores the result into note_name
|
||||
// [main-thread]
|
||||
bool (*get)(const clap_plugin_t *plugin, uint32_t index, clap_note_name_t *note_name);
|
||||
} clap_plugin_note_name;
|
||||
|
||||
typedef struct clap_host_note_name {
|
||||
// Informs the host that the note names has changed.
|
||||
// [main-thread]
|
||||
void (*changed)(const clap_host_t *host);
|
||||
} clap_host_note_name_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,76 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
#include "../string-sizes.h"
|
||||
|
||||
/// @page Note Ports
|
||||
///
|
||||
/// This extension provides a way for the plugin to describe its current note ports.
|
||||
/// If the plugin does not implement this extension, it won't have note input or output.
|
||||
/// The plugin is only allowed to change its note ports configuration while it is deactivated.
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_NOTE_PORTS[] = "clap.note-ports";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum clap_note_dialect {
|
||||
// Uses clap_event_note and clap_event_note_expression.
|
||||
CLAP_NOTE_DIALECT_CLAP = 1 << 0,
|
||||
|
||||
// Uses clap_event_midi, no polyphonic expression
|
||||
CLAP_NOTE_DIALECT_MIDI = 1 << 1,
|
||||
|
||||
// Uses clap_event_midi, with polyphonic expression (MPE)
|
||||
CLAP_NOTE_DIALECT_MIDI_MPE = 1 << 2,
|
||||
|
||||
// Uses clap_event_midi2
|
||||
CLAP_NOTE_DIALECT_MIDI2 = 1 << 3,
|
||||
};
|
||||
|
||||
typedef struct clap_note_port_info {
|
||||
clap_id id; // stable identifier
|
||||
uint32_t supported_dialects; // bitfield, see clap_note_dialect
|
||||
uint32_t preferred_dialect; // one value of clap_note_dialect
|
||||
char name[CLAP_NAME_SIZE]; // displayable name, i18n?
|
||||
} clap_note_port_info_t;
|
||||
|
||||
// The note ports scan has to be done while the plugin is deactivated.
|
||||
typedef struct clap_plugin_note_ports {
|
||||
// number of ports, for either input or output
|
||||
// [main-thread]
|
||||
uint32_t (*count)(const clap_plugin_t *plugin, bool is_input);
|
||||
|
||||
// get info about about a note port.
|
||||
// [main-thread]
|
||||
bool (*get)(const clap_plugin_t *plugin,
|
||||
uint32_t index,
|
||||
bool is_input,
|
||||
clap_note_port_info_t *info);
|
||||
} clap_plugin_note_ports_t;
|
||||
|
||||
enum {
|
||||
// The ports have changed, the host shall perform a full scan of the ports.
|
||||
// This flag can only be used if the plugin is not active.
|
||||
// If the plugin active, call host->request_restart() and then call rescan()
|
||||
// when the host calls deactivate()
|
||||
CLAP_NOTE_PORTS_RESCAN_ALL = 1 << 0,
|
||||
|
||||
// The ports name did change, the host can scan them right away.
|
||||
CLAP_NOTE_PORTS_RESCAN_NAMES = 1 << 1,
|
||||
};
|
||||
|
||||
typedef struct clap_host_note_ports {
|
||||
// Query which dialects the host supports
|
||||
// [main-thread]
|
||||
uint32_t (*supported_dialects)(const clap_host_t *host);
|
||||
|
||||
// Rescan the full list of note ports according to the flags.
|
||||
// [main-thread]
|
||||
void (*rescan)(const clap_host_t *host, uint32_t flags);
|
||||
} clap_host_note_ports_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,297 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
#include "../string-sizes.h"
|
||||
|
||||
/// @page Parameters
|
||||
/// @brief parameters management
|
||||
///
|
||||
/// Main idea:
|
||||
///
|
||||
/// The host sees the plugin as an atomic entity; and acts as a controler on top of its parameters.
|
||||
/// The plugin is responsible to keep in sync its audio processor and its GUI.
|
||||
///
|
||||
/// The host can read at any time parameters value on the [main-thread] using
|
||||
/// @ref clap_plugin_params.value().
|
||||
///
|
||||
/// There is two options to communicate parameter value change, and they are not concurrent.
|
||||
/// - send automation points during clap_plugin.process()
|
||||
/// - send automation points during clap_plugin_params.flush(), this one is used when the plugin is
|
||||
/// not processing
|
||||
///
|
||||
/// When the plugin changes a parameter value, it must inform the host.
|
||||
/// It will send @ref CLAP_EVENT_PARAM_VALUE event during process() or flush().
|
||||
/// If the user is adjusting the value, don't forget to mark the begining and end
|
||||
/// of the gesture by send CLAP_EVENT_PARAM_GESTURE_BEGIN and CLAP_EVENT_PARAM_GESTURE_END events.
|
||||
///
|
||||
/// @note MIDI CCs are a tricky because you may not know when the parameter adjustment ends.
|
||||
/// Also if the hosts records incoming MIDI CC and parameter change automation at the same time,
|
||||
/// there will be a conflict at playback: MIDI CC vs Automation.
|
||||
/// The parameter automation will always target the same parameter because the param_id is stable.
|
||||
/// The MIDI CC may have a different mapping in the future and may result in a different playback.
|
||||
///
|
||||
/// When a MIDI CC changes a parameter's value, set the flag CLAP_EVENT_DONT_RECORD in
|
||||
/// clap_event_param.header.flags. That way the host may record the MIDI CC automation, but not the
|
||||
/// parameter change and there won't be conflict at playback.
|
||||
///
|
||||
/// Scenarios:
|
||||
///
|
||||
/// I. Loading a preset
|
||||
/// - load the preset in a temporary state
|
||||
/// - call @ref clap_host_params.changed() if anything changed
|
||||
/// - call @ref clap_host_latency.changed() if latency changed
|
||||
/// - invalidate any other info that may be cached by the host
|
||||
/// - if the plugin is activated and the preset will introduce breaking change
|
||||
/// (latency, audio ports, new parameters, ...) be sure to wait for the host
|
||||
/// to deactivate the plugin to apply those changes.
|
||||
/// If there are no breaking changes, the plugin can apply them them right away.
|
||||
/// The plugin is resonsible to update both its audio processor and its gui.
|
||||
///
|
||||
/// II. Turning a knob on the DAW interface
|
||||
/// - the host will send an automation event to the plugin via a process() or flush()
|
||||
///
|
||||
/// III. Turning a knob on the Plugin interface
|
||||
/// - if the plugin is not processing, call clap_host_params->request_flush() or
|
||||
/// clap_host->request_process().
|
||||
/// - send an automation event and don't forget to set begin_adjust, end_adjust and should_record
|
||||
/// flags
|
||||
/// - the plugin is responsible to send the parameter value to its audio processor
|
||||
///
|
||||
/// IV. Turning a knob via automation
|
||||
/// - host sends an automation point during clap_plugin->process() or clap_plugin_params->flush().
|
||||
/// - the plugin is responsible to update its GUI
|
||||
///
|
||||
/// V. Turning a knob via plugin's internal MIDI mapping
|
||||
/// - the plugin sends a CLAP_EVENT_PARAM_SET output event, set should_record to false
|
||||
/// - the plugin is responsible to update its GUI
|
||||
///
|
||||
/// VI. Adding or removing parameters
|
||||
/// - if the plugin is activated call clap_host->restart()
|
||||
/// - once the plugin isn't active:
|
||||
/// - apply the new state
|
||||
/// - if a parameter is gone or is created with an id that may have been used before,
|
||||
/// call clap_host_params.clear(host, param_id, CLAP_PARAM_CLEAR_ALL)
|
||||
/// - call clap_host_params->rescan(CLAP_PARAM_RESCAN_ALL)
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_PARAMS[] = "clap.params";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
// Is this param stepped? (integer values only)
|
||||
// if so the double value is converted to integer using a cast (equivalent to trunc).
|
||||
CLAP_PARAM_IS_STEPPED = 1 << 0,
|
||||
|
||||
// Useful for for periodic parameters like a phase
|
||||
CLAP_PARAM_IS_PERIODIC = 1 << 1,
|
||||
|
||||
// The parameter should not be shown to the user, because it is currently not used.
|
||||
// It is not necessary to process automation for this parameter.
|
||||
CLAP_PARAM_IS_HIDDEN = 1 << 2,
|
||||
|
||||
// The parameter can't be changed by the host.
|
||||
CLAP_PARAM_IS_READONLY = 1 << 3,
|
||||
|
||||
// This parameter is used to merge the plugin and host bypass button.
|
||||
// It implies that the parameter is stepped.
|
||||
// min: 0 -> bypass off
|
||||
// max: 1 -> bypass on
|
||||
CLAP_PARAM_IS_BYPASS = 1 << 4,
|
||||
|
||||
// When set:
|
||||
// - automation can be recorded
|
||||
// - automation can be played back
|
||||
//
|
||||
// The host can send live user changes for this parameter regardless of this flag.
|
||||
//
|
||||
// If this parameters affect the internal processing structure of the plugin, ie: max delay, fft
|
||||
// size, ... and the plugins needs to re-allocate its working buffers, then it should call
|
||||
// host->request_restart(), and perform the change once the plugin is re-activated.
|
||||
CLAP_PARAM_IS_AUTOMATABLE = 1 << 5,
|
||||
|
||||
// Does this param supports per note automations?
|
||||
CLAP_PARAM_IS_AUTOMATABLE_PER_NOTE_ID = 1 << 6,
|
||||
|
||||
// Does this param supports per note automations?
|
||||
CLAP_PARAM_IS_AUTOMATABLE_PER_KEY = 1 << 7,
|
||||
|
||||
// Does this param supports per channel automations?
|
||||
CLAP_PARAM_IS_AUTOMATABLE_PER_CHANNEL = 1 << 8,
|
||||
|
||||
// Does this param supports per port automations?
|
||||
CLAP_PARAM_IS_AUTOMATABLE_PER_PORT = 1 << 9,
|
||||
|
||||
// Does the parameter support the modulation signal?
|
||||
CLAP_PARAM_IS_MODULATABLE = 1 << 10,
|
||||
|
||||
// Does this param supports per note automations?
|
||||
CLAP_PARAM_IS_MODULATABLE_PER_NOTE_ID = 1 << 11,
|
||||
|
||||
// Does this param supports per note automations?
|
||||
CLAP_PARAM_IS_MODULATABLE_PER_KEY = 1 << 12,
|
||||
|
||||
// Does this param supports per channel automations?
|
||||
CLAP_PARAM_IS_MODULATABLE_PER_CHANNEL = 1 << 13,
|
||||
|
||||
// Does this param supports per channel automations?
|
||||
CLAP_PARAM_IS_MODULATABLE_PER_PORT = 1 << 14,
|
||||
|
||||
// Any change to this parameter will affect the plugin output and requires to be done via
|
||||
// process() if the plugin is active.
|
||||
//
|
||||
// A simple example would be a DC Offset, changing it will change the output signal and must be
|
||||
// processed.
|
||||
CLAP_PARAM_REQUIRES_PROCESS = 1 << 15,
|
||||
};
|
||||
typedef uint32_t clap_param_info_flags;
|
||||
|
||||
/* This describes a parameter */
|
||||
typedef struct clap_param_info {
|
||||
// stable parameter identifier, it must never change.
|
||||
clap_id id;
|
||||
|
||||
clap_param_info_flags flags;
|
||||
|
||||
// This value is optional and set by the plugin.
|
||||
// Its purpose is to provide a fast access to the plugin parameter:
|
||||
//
|
||||
// Parameter *p = findParameter(param_id);
|
||||
// param_info->cookie = p;
|
||||
//
|
||||
// /* and later on */
|
||||
// Parameter *p = (Parameter *)cookie;
|
||||
//
|
||||
// It is invalidated on clap_host_params->rescan(CLAP_PARAM_RESCAN_ALL) and when the plugin is
|
||||
// destroyed.
|
||||
void *cookie;
|
||||
|
||||
// the display name
|
||||
char name[CLAP_NAME_SIZE];
|
||||
|
||||
// the module path containing the param, eg:"oscillators/wt1"
|
||||
// '/' will be used as a separator to show a tree like structure.
|
||||
char module[CLAP_PATH_SIZE];
|
||||
|
||||
double min_value; // minimum plain value
|
||||
double max_value; // maximum plain value
|
||||
double default_value; // default plain value
|
||||
} clap_param_info_t;
|
||||
|
||||
typedef struct clap_plugin_params {
|
||||
// Returns the number of parameters.
|
||||
// [main-thread]
|
||||
uint32_t (*count)(const clap_plugin_t *plugin);
|
||||
|
||||
// Copies the parameter's info to param_info and returns true on success.
|
||||
// [main-thread]
|
||||
bool (*get_info)(const clap_plugin_t *plugin,
|
||||
uint32_t param_index,
|
||||
clap_param_info_t *param_info);
|
||||
|
||||
// Gets the parameter plain value.
|
||||
// [main-thread]
|
||||
bool (*get_value)(const clap_plugin_t *plugin, clap_id param_id, double *value);
|
||||
|
||||
// Formats the display text for the given parameter value.
|
||||
// The host should always format the parameter value to text using this function
|
||||
// before displaying it to the user.
|
||||
// [main-thread]
|
||||
bool (*value_to_text)(
|
||||
const clap_plugin_t *plugin, clap_id param_id, double value, char *display, uint32_t size);
|
||||
|
||||
// Converts the display text to a parameter value.
|
||||
// [main-thread]
|
||||
bool (*text_to_value)(const clap_plugin_t *plugin,
|
||||
clap_id param_id,
|
||||
const char *display,
|
||||
double *value);
|
||||
|
||||
// Flushes a set of parameter changes.
|
||||
// This method must not be called concurrently to clap_plugin->process().
|
||||
// This method must not be used if the plugin is processing.
|
||||
//
|
||||
// [active && !processing : audio-thread]
|
||||
// [!active : main-thread]
|
||||
void (*flush)(const clap_plugin_t *plugin,
|
||||
const clap_input_events_t *in,
|
||||
const clap_output_events_t *out);
|
||||
} clap_plugin_params_t;
|
||||
|
||||
enum {
|
||||
// The parameter values did change, eg. after loading a preset.
|
||||
// The host will scan all the parameters value.
|
||||
// The host will not record those changes as automation points.
|
||||
// New values takes effect immediately.
|
||||
CLAP_PARAM_RESCAN_VALUES = 1 << 0,
|
||||
|
||||
// The value to text conversion changed, and the text needs to be rendered again.
|
||||
CLAP_PARAM_RESCAN_TEXT = 1 << 1,
|
||||
|
||||
// The parameter info did change, use this flag for:
|
||||
// - name change
|
||||
// - module change
|
||||
// - is_periodic (flag)
|
||||
// - is_hidden (flag)
|
||||
// New info takes effect immediately.
|
||||
CLAP_PARAM_RESCAN_INFO = 1 << 2,
|
||||
|
||||
// Invalidates everything the host knows about parameters.
|
||||
// It can only be used while the plugin is deactivated.
|
||||
// If the plugin is activated use clap_host->restart() and delay any change until the host calls
|
||||
// clap_plugin->deactivate().
|
||||
//
|
||||
// You must use this flag if:
|
||||
// - some parameters were added or removed.
|
||||
// - some parameters had critical changes:
|
||||
// - is_per_note (flag)
|
||||
// - is_per_channel (flag)
|
||||
// - is_readonly (flag)
|
||||
// - is_bypass (flag)
|
||||
// - is_stepped (flag)
|
||||
// - is_modulatable (flag)
|
||||
// - min_value
|
||||
// - max_value
|
||||
// - cookie
|
||||
CLAP_PARAM_RESCAN_ALL = 1 << 3,
|
||||
};
|
||||
typedef uint32_t clap_param_rescan_flags;
|
||||
|
||||
enum {
|
||||
// Clears all possible references to a parameter
|
||||
CLAP_PARAM_CLEAR_ALL = 1 << 0,
|
||||
|
||||
// Clears all automations to a parameter
|
||||
CLAP_PARAM_CLEAR_AUTOMATIONS = 1 << 1,
|
||||
|
||||
// Clears all modulations to a parameter
|
||||
CLAP_PARAM_CLEAR_MODULATIONS = 1 << 2,
|
||||
};
|
||||
typedef uint32_t clap_param_clear_flags;
|
||||
|
||||
typedef struct clap_host_params {
|
||||
// Rescan the full list of parameters according to the flags.
|
||||
// [main-thread]
|
||||
void (*rescan)(const clap_host_t *host, clap_param_rescan_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 the host to call clap_plugin_params->fush().
|
||||
// This is useful if the plugin has parameters value changes to report to the host but the plugin
|
||||
// is not processing.
|
||||
//
|
||||
// eg. the plugin has a USB socket to some hardware controllers and receives a parameter change
|
||||
// while it is not processing.
|
||||
//
|
||||
// This must not be called on the [audio-thread].
|
||||
//
|
||||
// [thread-safe]
|
||||
void (*request_flush)(const clap_host_t *host);
|
||||
} clap_host_params_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,46 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
|
||||
// This extension let your plugin hook itself into the host select/poll/epoll/kqueue reactor.
|
||||
// This is useful to handle asynchronous I/O on the main thread.
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_POSIX_FD_SUPPORT[] = "clap.posix-fd-support";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
// IO events flags, they can be used to form a mask which describes:
|
||||
// - which events you are interested in (register_fd/modify_fd)
|
||||
// - which events happened (on_fd)
|
||||
CLAP_POSIX_FD_READ = 1 << 0,
|
||||
CLAP_POSIX_FD_WRITE = 1 << 1,
|
||||
CLAP_POSIX_FD_ERROR = 1 << 2,
|
||||
};
|
||||
typedef uint32_t clap_posix_fd_flags_t;
|
||||
|
||||
typedef struct clap_plugin_posix_fd_support {
|
||||
// This callback is "level-triggered".
|
||||
// It means that a writable fd will continuously produce "on_fd()" events;
|
||||
// don't forget using modify_fd() to remove the write notification once you're
|
||||
// done writting.
|
||||
//
|
||||
// [main-thread]
|
||||
void (*on_fd)(const clap_plugin_t *plugin, int fd, clap_posix_fd_flags_t flags);
|
||||
} clap_plugin_posix_fd_support_t;
|
||||
|
||||
typedef struct clap_host_posix_fd_support {
|
||||
// [main-thread]
|
||||
bool (*register_fd)(const clap_host_t *host, int fd, clap_posix_fd_flags_t flags);
|
||||
|
||||
// [main-thread]
|
||||
bool (*modify_fd)(const clap_host_t *host, int fd, clap_posix_fd_flags_t flags);
|
||||
|
||||
// [main-thread]
|
||||
bool (*unregister_fd)(const clap_host_t *host, int fd);
|
||||
} clap_host_posix_fd_support_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,39 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_RENDER[] = "clap.render";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
// Default setting, for "realtime" processing
|
||||
CLAP_RENDER_REALTIME = 0,
|
||||
|
||||
// For processing without realtime pressure
|
||||
// The plugin may use more expensive algorithms for higher sound quality.
|
||||
CLAP_RENDER_OFFLINE = 1,
|
||||
};
|
||||
typedef int32_t clap_plugin_render_mode;
|
||||
|
||||
// The render extension is used to let the plugin know if it has "realtime"
|
||||
// pressure to process.
|
||||
//
|
||||
// If this information does not influence your rendering code, then don't
|
||||
// implement this extension.
|
||||
typedef struct clap_plugin_render {
|
||||
// Returns true if the plugin has an hard requirement to process in real-time.
|
||||
// This is especially useful for plugin acting as a proxy to an hardware device.
|
||||
// [main-thread]
|
||||
bool (*has_hard_realtime_requirement)(const clap_plugin_t *plugin);
|
||||
|
||||
// Returns true if the rendering mode could be applied.
|
||||
// [main-thread]
|
||||
bool (*set)(const clap_plugin_t *plugin, clap_plugin_render_mode mode);
|
||||
} clap_plugin_render_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,33 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
#include "../stream.h"
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_STATE[] = "clap.state";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct clap_plugin_state {
|
||||
// Saves the plugin state into stream.
|
||||
// Returns true if the state was correctly saved.
|
||||
// [main-thread]
|
||||
bool (*save)(const clap_plugin_t *plugin, const clap_ostream_t *stream);
|
||||
|
||||
// Loads the plugin state from stream.
|
||||
// Returns true if the state was correctly restored.
|
||||
// [main-thread]
|
||||
bool (*load)(const clap_plugin_t *plugin, const clap_istream_t *stream);
|
||||
} clap_plugin_state_t;
|
||||
|
||||
typedef struct clap_host_state {
|
||||
// Tell the host that the plugin state has changed and should be saved again.
|
||||
// If a parameter value changes, then it is implicit that the state is dirty.
|
||||
// [main-thread]
|
||||
void (*mark_dirty)(const clap_host_t *host);
|
||||
} clap_host_state_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,26 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_TAIL[] = "clap.tail";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct clap_plugin_tail {
|
||||
// Returns tail length in samples.
|
||||
// Any value greater or equal to INT32_MAX implies infinite tail.
|
||||
// [main-thread,audio-thread]
|
||||
uint32_t (*get)(const clap_plugin_t *plugin);
|
||||
} clap_plugin_tail_t;
|
||||
|
||||
typedef struct clap_host_tail {
|
||||
// Tell the host that the tail has changed.
|
||||
// [audio-thread]
|
||||
void (*changed)(const clap_host_t *host);
|
||||
} clap_host_tail_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,26 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_THREAD_CHECK[] = "clap.thread-check";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// This interface is useful to do runtime checks and make
|
||||
// sure that the functions are called on the correct threads.
|
||||
// It is highly recommended to implement this extension
|
||||
typedef struct clap_host_thread_check {
|
||||
// Returns true if "this" thread is the main thread.
|
||||
// [thread-safe]
|
||||
bool (*is_main_thread)(const clap_host_t *host);
|
||||
|
||||
// Returns true if "this" thread is one of the audio threads.
|
||||
// [thread-safe]
|
||||
bool (*is_audio_thread)(const clap_host_t *host);
|
||||
} clap_host_thread_check_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,66 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
|
||||
/// @page
|
||||
///
|
||||
/// This extension let the plugin use the host's thread pool.
|
||||
///
|
||||
/// The plugin must provide @ref clap_plugin_thread_pool, and the host may provide @ref
|
||||
/// clap_host_thread_pool. If it doesn't, the plugin should process its data by its own mean. In the
|
||||
/// worst case, a single threaded for-loop.
|
||||
///
|
||||
/// Simple example with N voices to process
|
||||
///
|
||||
/// @code
|
||||
/// void myplug_thread_pool_exec(const clap_plugin *plugin, uint32_t voice_index)
|
||||
/// {
|
||||
/// compute_voice(plugin, voice_index);
|
||||
/// }
|
||||
///
|
||||
/// void myplug_process(const clap_plugin *plugin, const clap_process *process)
|
||||
/// {
|
||||
/// ...
|
||||
/// bool didComputeVoices = false;
|
||||
/// if (host_thread_pool && host_thread_pool.exec)
|
||||
/// didComputeVoices = host_thread_pool.request_exec(host, plugin, N);
|
||||
///
|
||||
/// if (!didComputeVoices)
|
||||
/// for (uint32_t i = 0; i < N; ++i)
|
||||
/// myplug_thread_pool_exec(plugin, N);
|
||||
/// ...
|
||||
/// }
|
||||
/// @endcode
|
||||
///
|
||||
/// Be aware that using a thread pool may break hard real-time rules due to the thread
|
||||
/// synchronization involved.
|
||||
///
|
||||
/// If the host knows that it is running under hard real-time pressure it may decide to not
|
||||
/// provide this interface.
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_THREAD_POOL[] = "clap.thread-pool";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct clap_plugin_thread_pool {
|
||||
// Called by the thread pool
|
||||
void (*exec)(const clap_plugin_t *plugin, uint32_t task_index);
|
||||
} clap_plugin_thread_pool_t;
|
||||
|
||||
typedef struct clap_host_thread_pool {
|
||||
// Schedule num_tasks jobs in the host thread pool.
|
||||
// It can't be called concurrently or from the thread pool.
|
||||
// Will block until all the tasks are processed.
|
||||
// This must be used exclusively for realtime processing within the process call.
|
||||
// Returns true if the host did execute all the tasks, false if it rejected the request.
|
||||
// The host should check that the plugin is within the process call, and if not, reject the exec
|
||||
// request.
|
||||
// [audio-thread]
|
||||
bool (*request_exec)(const clap_host_t *host, uint32_t num_tasks);
|
||||
} clap_host_thread_pool_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,29 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_TIMER_SUPPORT[] = "clap.timer-support";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct clap_plugin_timer_support {
|
||||
// [main-thread]
|
||||
void (*on_timer)(const clap_plugin_t *plugin, clap_id timer_id);
|
||||
} clap_plugin_timer_support_t;
|
||||
|
||||
typedef struct clap_host_timer_support {
|
||||
// Registers a periodic timer.
|
||||
// The host may adjust the period if it is under a certain threshold.
|
||||
// 30 Hz should be allowed.
|
||||
// [main-thread]
|
||||
bool (*register_timer)(const clap_host_t *host, uint32_t period_ms, clap_id *timer_id);
|
||||
|
||||
// [main-thread]
|
||||
bool (*unregister_timer)(const clap_host_t *host, clap_id timer_id);
|
||||
} clap_host_timer_support_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,16 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "private/std.h"
|
||||
#include "private/macros.h"
|
||||
|
||||
/// We use fixed point representation of beat time and seconds time
|
||||
/// Usage:
|
||||
/// double x = ...; // in beats
|
||||
/// clap_beattime y = round(CLAP_BEATTIME_FACTOR * x);
|
||||
|
||||
// This will never change
|
||||
static const CLAP_CONSTEXPR int64_t CLAP_BEATTIME_FACTOR = 1LL << 31;
|
||||
static const CLAP_CONSTEXPR int64_t CLAP_SECTIME_FACTOR = 1LL << 31;
|
||||
|
||||
typedef int64_t clap_beattime;
|
||||
typedef int64_t clap_sectime;
|
@ -1,41 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "version.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct clap_host {
|
||||
clap_version_t clap_version; // initialized to CLAP_VERSION
|
||||
|
||||
void *host_data; // reserved pointer for the host
|
||||
|
||||
// name and version are mandatory.
|
||||
const char *name; // eg: "Bitwig Studio"
|
||||
const char *vendor; // eg: "Bitwig GmbH"
|
||||
const char *url; // eg: "https://bitwig.com"
|
||||
const char *version; // eg: "4.3"
|
||||
|
||||
// Query an extension.
|
||||
// [thread-safe]
|
||||
const void *(*get_extension)(const struct clap_host *host, const char *extension_id);
|
||||
|
||||
// Request the host to deactivate and then reactivate the plugin.
|
||||
// The operation may be delayed by the host.
|
||||
// [thread-safe]
|
||||
void (*request_restart)(const struct clap_host *host);
|
||||
|
||||
// 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 (*request_process)(const struct clap_host *host);
|
||||
|
||||
// Request the host to schedule a call to plugin->on_main_thread(plugin) on the main thread.
|
||||
// [thread-safe]
|
||||
void (*request_callback)(const struct clap_host *host);
|
||||
} clap_host_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "private/std.h"
|
||||
#include "private/macros.h"
|
||||
|
||||
typedef uint32_t clap_id;
|
||||
|
||||
static const CLAP_CONSTEXPR clap_id CLAP_INVALID_ID = UINT32_MAX;
|
@ -1,39 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "plugin.h"
|
||||
|
||||
static const CLAP_CONSTEXPR char CLAP_PLUGIN_FACTORY_ID[] = "clap.plugin-factory";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Every methods must be thread-safe.
|
||||
// It is very important to be able to scan the plugin as quickly as possible.
|
||||
//
|
||||
// If the content of the factory may change due to external events, like the user installed
|
||||
typedef struct clap_plugin_factory {
|
||||
// Get the number of plugins available.
|
||||
// [thread-safe]
|
||||
uint32_t (*get_plugin_count)(const struct clap_plugin_factory *factory);
|
||||
|
||||
// Retrieves a plugin descriptor by its index.
|
||||
// Returns null in case of error.
|
||||
// The descriptor must not be freed.
|
||||
// [thread-safe]
|
||||
const clap_plugin_descriptor_t *(*get_plugin_descriptor)(
|
||||
const struct clap_plugin_factory *factory, uint32_t index);
|
||||
|
||||
// Create a clap_plugin by its plugin_id.
|
||||
// The returned pointer must be freed by calling plugin->destroy(plugin);
|
||||
// The plugin is not allowed to use the host callbacks in the create method.
|
||||
// Returns null in case of error.
|
||||
// [thread-safe]
|
||||
const clap_plugin_t *(*create_plugin)(const struct clap_plugin_factory *factory,
|
||||
const clap_host_t *host,
|
||||
const char *plugin_id);
|
||||
} clap_plugin_factory_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,76 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "private/macros.h"
|
||||
|
||||
// This files provides a set of standard plugin features meant to be use
|
||||
// within clap_plugin_descriptor.features.
|
||||
//
|
||||
// For practical reasons we'll avoid spaces and use `-` instead to facilitate
|
||||
// scripts that generate the feature array.
|
||||
//
|
||||
// Non standard feature should be formated as follow: "$namespace:$feature"
|
||||
|
||||
/////////////////////
|
||||
// Plugin category //
|
||||
/////////////////////
|
||||
|
||||
// Add this feature if your plugin can process note events and then produce audio
|
||||
#define CLAP_PLUGIN_FEATURE_INSTRUMENT "instrument"
|
||||
|
||||
// Add this feature if your plugin is an audio effect
|
||||
#define CLAP_PLUGIN_FEATURE_AUDIO_EFFECT "audio-effect"
|
||||
|
||||
// Add this feature if your plugin is a note effect or a note generator/sequencer
|
||||
#define CLAP_PLUGIN_FEATURE_NOTE_EFFECT "note-effect"
|
||||
|
||||
// Add this feature if your plugin is an analyzer
|
||||
#define CLAP_PLUGIN_FEATURE_ANALYZER "analyzer"
|
||||
|
||||
/////////////////////////
|
||||
// Plugin sub-category //
|
||||
/////////////////////////
|
||||
|
||||
#define CLAP_PLUGIN_FEATURE_SYNTHESIZER "synthesizer"
|
||||
#define CLAP_PLUGIN_FEATURE_SAMPLER "sampler"
|
||||
#define CLAP_PLUGIN_FEATURE_DRUM "drum" // For single drum
|
||||
#define CLAP_PLUGIN_FEATURE_DRUM_MACHINE "drum-machine"
|
||||
|
||||
#define CLAP_PLUGIN_FEATURE_FILTER "filter"
|
||||
#define CLAP_PLUGIN_FEATURE_PHASER "phaser"
|
||||
#define CLAP_PLUGIN_FEATURE_EQUALIZER "equalizer"
|
||||
#define CLAP_PLUGIN_FEATURE_DEESSER "de-esser"
|
||||
#define CLAP_PLUGIN_FEATURE_PHASE_VOCODER "phase-vocoder"
|
||||
#define CLAP_PLUGIN_FEATURE_GRANULAR "granular"
|
||||
#define CLAP_PLUGIN_FEATURE_FREQUENCY_SHIFTER "frequency-shifter"
|
||||
#define CLAP_PLUGIN_FEATURE_PITCH_SHIFTER "pitch-shifter"
|
||||
|
||||
#define CLAP_PLUGIN_FEATURE_DISTORTION "distortion"
|
||||
#define CLAP_PLUGIN_FEATURE_TRANSIENT_SHAPER "transient-shaper"
|
||||
#define CLAP_PLUGIN_FEATURE_COMPRESSOR "compressor"
|
||||
#define CLAP_PLUGIN_FEATURE_LIMITER "limiter"
|
||||
|
||||
#define CLAP_PLUGIN_FEATURE_FLANGER "flanger"
|
||||
#define CLAP_PLUGIN_FEATURE_CHORUS "chorus"
|
||||
#define CLAP_PLUGIN_FEATURE_DELAY "delay"
|
||||
#define CLAP_PLUGIN_FEATURE_REVERB "reverb"
|
||||
|
||||
#define CLAP_PLUGIN_FEATURE_TREMOLO "tremolo"
|
||||
#define CLAP_PLUGIN_FEATURE_GLITCH "glitch"
|
||||
|
||||
#define CLAP_PLUGIN_FEATURE_UTILITY "utility"
|
||||
#define CLAP_PLUGIN_FEATURE_PITCH_CORRECTION "pitch-correction"
|
||||
#define CLAP_PLUGIN_FEATURE_RESTORATION "restoration" // repair the sound
|
||||
|
||||
#define CLAP_PLUGIN_FEATURE_MULTI_EFFECTS "multi-effects"
|
||||
|
||||
#define CLAP_PLUGIN_FEATURE_MIXING "mixing"
|
||||
#define CLAP_PLUGIN_FEATURE_MASTERING "mastering"
|
||||
|
||||
////////////////////////
|
||||
// Audio Capabilities //
|
||||
////////////////////////
|
||||
|
||||
#define CLAP_PLUGIN_FEATURE_MONO "mono"
|
||||
#define CLAP_PLUGIN_FEATURE_STEREO "stereo"
|
||||
#define CLAP_PLUGIN_FEATURE_SURROUND "surround"
|
||||
#define CLAP_PLUGIN_FEATURE_AMBISONIC "ambisonic"
|
@ -1,45 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "private/std.h"
|
||||
#include "private/macros.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct clap_plugin_invalidation_source {
|
||||
// Directory containing the file(s) to scan, must be absolute
|
||||
const char *directory;
|
||||
|
||||
// globing pattern, in the form *.dll
|
||||
const char *filename_glob;
|
||||
|
||||
// should the directory be scanned recursively?
|
||||
bool recursive_scan;
|
||||
} clap_plugin_invalidation_source_t;
|
||||
|
||||
static const CLAP_CONSTEXPR char CLAP_PLUGIN_INVALIDATION_FACTORY_ID[] =
|
||||
"clap.plugin-invalidation-factory/draft0";
|
||||
|
||||
// Used to figure out when a plugin needs to be scanned again.
|
||||
// Imagine a situation with a single entry point: my-plugin.clap which then scans itself
|
||||
// a set of "sub-plugins". New plugin may be available even if my-plugin.clap file doesn't change.
|
||||
// This interfaces solves this issue and gives a way to the host to monitor additional files.
|
||||
typedef struct clap_plugin_invalidation_factory {
|
||||
// Get the number of invalidation source.
|
||||
uint32_t (*count)(const struct clap_plugin_invalidation_factory *factory);
|
||||
|
||||
// Get the invalidation source by its index.
|
||||
// [thread-safe]
|
||||
const clap_plugin_invalidation_source_t *(*get)(
|
||||
const struct clap_plugin_invalidation_factory *factory, uint32_t index);
|
||||
|
||||
// In case the host detected a invalidation event, it can call refresh() to let the
|
||||
// plugin_entry update the set of plugins available.
|
||||
// If the function returned false, then the plugin needs to be reloaded.
|
||||
bool (*refresh)(const struct clap_plugin_invalidation_factory *factory);
|
||||
} clap_plugin_invalidation_factory_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,95 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "private/macros.h"
|
||||
#include "host.h"
|
||||
#include "process.h"
|
||||
#include "plugin-features.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct clap_plugin_descriptor {
|
||||
clap_version_t clap_version; // initialized to CLAP_VERSION
|
||||
|
||||
// Mandatory fields must be set and must not be blank.
|
||||
// Otherwise the fields can be null or blank, though it is safer to make them blank.
|
||||
const char *id; // eg: "com.u-he.diva", mandatory
|
||||
const char *name; // eg: "Diva", mandatory
|
||||
const char *vendor; // eg: "u-he"
|
||||
const char *url; // eg: "https://u-he.com/products/diva/"
|
||||
const char *manual_url; // eg: "https://dl.u-he.com/manuals/plugins/diva/Diva-user-guide.pdf"
|
||||
const char *support_url; // eg: "https://u-he.com/support/"
|
||||
const char *version; // eg: "1.4.4"
|
||||
const char *description; // eg: "The spirit of analogue"
|
||||
|
||||
// Arbitrary list of keywords.
|
||||
// They can be matched by the host indexer and used to classify the plugin.
|
||||
// The array of pointers must be null terminated.
|
||||
// For some standard features see plugin-features.h
|
||||
const char **features;
|
||||
} clap_plugin_descriptor_t;
|
||||
|
||||
typedef struct clap_plugin {
|
||||
const clap_plugin_descriptor_t *desc;
|
||||
|
||||
void *plugin_data; // reserved pointer for the plugin
|
||||
|
||||
// Must be called after creating the plugin.
|
||||
// If init returns false, the host must destroy the plugin instance.
|
||||
// [main-thread]
|
||||
bool (*init)(const struct clap_plugin *plugin);
|
||||
|
||||
// Free the plugin and its resources.
|
||||
// It is not required to deactivate the plugin prior to this call.
|
||||
// [main-thread & !active]
|
||||
void (*destroy)(const struct clap_plugin *plugin);
|
||||
|
||||
// Activate and deactivate the plugin.
|
||||
// In this call the plugin may allocate memory and prepare everything needed for the process
|
||||
// call. The process's sample rate will be constant and process's frame count will included in
|
||||
// the [min, max] range, which is bounded by [1, INT32_MAX].
|
||||
// Once activated the latency and port configuration must remain constant, until deactivation.
|
||||
//
|
||||
// [main-thread & !active_state]
|
||||
bool (*activate)(const struct clap_plugin *plugin,
|
||||
double sample_rate,
|
||||
uint32_t min_frames_count,
|
||||
uint32_t max_frames_count);
|
||||
// [main-thread & active_state]
|
||||
void (*deactivate)(const struct clap_plugin *plugin);
|
||||
|
||||
// Call start processing before processing.
|
||||
// [audio-thread & active_state & !processing_state]
|
||||
bool (*start_processing)(const struct clap_plugin *plugin);
|
||||
|
||||
// Call stop processing before sending the plugin to sleep.
|
||||
// [audio-thread & active_state & processing_state]
|
||||
void (*stop_processing)(const struct clap_plugin *plugin);
|
||||
|
||||
// - Clears all buffers, performs a full reset of the processing state (filters, oscillators,
|
||||
// enveloppes, lfo, ...) and kills all voices.
|
||||
// - The parameter's value remain unchanged.
|
||||
// - clap_process.steady_time may jump backward.
|
||||
//
|
||||
// [audio-thread & active_state]
|
||||
void (*reset)(const struct clap_plugin *plugin);
|
||||
|
||||
// process audio, events, ...
|
||||
// [audio-thread & active_state & processing_state]
|
||||
clap_process_status (*process)(const struct clap_plugin *plugin, const clap_process_t *process);
|
||||
|
||||
// Query an extension.
|
||||
// The returned pointer is owned by the plugin.
|
||||
// [thread-safe]
|
||||
const void *(*get_extension)(const struct clap_plugin *plugin, const char *id);
|
||||
|
||||
// Called by the host on the main thread in response to a previous call to:
|
||||
// host->request_callback(host);
|
||||
// [main-thread]
|
||||
void (*on_main_thread)(const struct clap_plugin *plugin);
|
||||
} clap_plugin_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|