├── .clang-format ├── .github └── workflows │ ├── cmake.yml │ └── properties │ └── build.properties.json ├── .gitignore ├── CMakeLists.txt ├── CMakePresets.json ├── ChangeLog.md ├── Contributors.md ├── LICENSE ├── README.md ├── artwork ├── CLAP Full Logo.eps ├── CLAP Full Logo.svg ├── CLAP Icon Extension.eps ├── CLAP Icon Extension.svg ├── CLAP Icon.eps ├── CLAP Icon.svg ├── CLAP Logo Guidelines.pdf ├── CLAP Simple Logo.eps ├── CLAP Simple Logo.svg ├── clap-full-logo-black.png ├── clap-full-logo-white.png ├── clap-simple-logo-black.png └── clap-simple-logo-white.png ├── clap.pc.in ├── conventions └── extension-id.md ├── include └── clap │ ├── all.h │ ├── audio-buffer.h │ ├── clap.h │ ├── color.h │ ├── entry.h │ ├── events.h │ ├── ext │ ├── ambisonic.h │ ├── audio-ports-activation.h │ ├── audio-ports-config.h │ ├── audio-ports.h │ ├── configurable-audio-ports.h │ ├── context-menu.h │ ├── draft │ │ ├── extensible-audio-ports.h │ │ ├── gain-adjustment-metering.h │ │ ├── mini-curve-display.h │ │ ├── project-location.h │ │ ├── resource-directory.h │ │ ├── scratch-memory.h │ │ ├── transport-control.h │ │ ├── triggers.h │ │ ├── tuning.h │ │ └── undo.h │ ├── event-registry.h │ ├── gui.h │ ├── latency.h │ ├── log.h │ ├── note-name.h │ ├── note-ports.h │ ├── param-indication.h │ ├── params.h │ ├── posix-fd-support.h │ ├── preset-load.h │ ├── remote-controls.h │ ├── render.h │ ├── state-context.h │ ├── state.h │ ├── surround.h │ ├── tail.h │ ├── thread-check.h │ ├── thread-pool.h │ ├── timer-support.h │ ├── track-info.h │ └── voice-info.h │ ├── factory │ ├── draft │ │ ├── plugin-invalidation.h │ │ └── plugin-state-converter.h │ ├── plugin-factory.h │ └── preset-discovery.h │ ├── fixedpoint.h │ ├── host.h │ ├── id.h │ ├── plugin-features.h │ ├── plugin.h │ ├── private │ ├── macros.h │ └── std.h │ ├── process.h │ ├── stream.h │ ├── string-sizes.h │ ├── timestamp.h │ ├── universal-plugin-id.h │ └── version.h └── src ├── linux-my_plug.version ├── macos-symbols.txt ├── main.c ├── main.cc ├── plugin-template.c └── plugins.plist.in /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | # BasedOnStyle: LLVM 4 | AccessModifierOffset: -3 5 | AlignAfterOpenBracket: Align 6 | AlignConsecutiveMacros: false 7 | AlignConsecutiveAssignments: false 8 | AlignConsecutiveDeclarations: true 9 | AlignEscapedNewlines: Right 10 | AlignOperands: true 11 | AlignTrailingComments: true 12 | AllowAllArgumentsOnNextLine: true 13 | AllowAllConstructorInitializersOnNextLine: true 14 | AllowAllParametersOfDeclarationOnNextLine: true 15 | AllowShortBlocksOnASingleLine: Never 16 | AllowShortCaseLabelsOnASingleLine: false 17 | AllowShortFunctionsOnASingleLine: All 18 | AllowShortLambdasOnASingleLine: All 19 | AllowShortIfStatementsOnASingleLine: Never 20 | AllowShortLoopsOnASingleLine: false 21 | AlwaysBreakAfterDefinitionReturnType: None 22 | AlwaysBreakAfterReturnType: None 23 | AlwaysBreakBeforeMultilineStrings: false 24 | AlwaysBreakTemplateDeclarations: Yes 25 | BinPackArguments: false 26 | BinPackParameters: false 27 | BraceWrapping: 28 | AfterCaseLabel: false 29 | AfterClass: true 30 | AfterControlStatement: true 31 | AfterEnum: true 32 | AfterFunction: true 33 | AfterNamespace: true 34 | AfterObjCDeclaration: true 35 | AfterStruct: true 36 | AfterUnion: true 37 | AfterExternBlock: true 38 | BeforeCatch: true 39 | BeforeElse: true 40 | IndentBraces: false 41 | SplitEmptyFunction: false 42 | SplitEmptyRecord: false 43 | SplitEmptyNamespace: false 44 | BreakBeforeBinaryOperators: None 45 | BreakBeforeBraces: Attach 46 | BreakBeforeInheritanceComma: false 47 | BreakInheritanceList: BeforeColon 48 | BreakBeforeTernaryOperators: true 49 | BreakConstructorInitializersBeforeComma: false 50 | BreakConstructorInitializers: BeforeColon 51 | BreakAfterJavaFieldAnnotations: false 52 | BreakStringLiterals: true 53 | ColumnLimit: 100 54 | CommentPragmas: '^ IWYU pragma:' 55 | CompactNamespaces: true 56 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 57 | ConstructorInitializerIndentWidth: 3 58 | ContinuationIndentWidth: 3 59 | Cpp11BracedListStyle: true 60 | DeriveLineEnding: false 61 | DerivePointerAlignment: false 62 | DisableFormat: false 63 | ExperimentalAutoDetectBinPacking: false 64 | FixNamespaceComments: true 65 | ForEachMacros: 66 | - foreach 67 | - Q_FOREACH 68 | - BOOST_FOREACH 69 | IncludeBlocks: Preserve 70 | IncludeCategories: 71 | - Regex: '^"(llvm|llvm-c|clang|clang-c)/' 72 | Priority: 2 73 | SortPriority: 0 74 | - Regex: '^(<|"(gtest|gmock|isl|json)/)' 75 | Priority: 3 76 | SortPriority: 0 77 | - Regex: '.*' 78 | Priority: 1 79 | SortPriority: 0 80 | IncludeIsMainRegex: '(Test)?$' 81 | IncludeIsMainSourceRegex: '' 82 | IndentCaseLabels: false 83 | IndentGotoLabels: true 84 | IndentPPDirectives: AfterHash 85 | IndentWidth: 3 86 | IndentWrappedFunctionNames: false 87 | JavaScriptQuotes: Leave 88 | JavaScriptWrapImports: true 89 | KeepEmptyLinesAtTheStartOfBlocks: true 90 | MacroBlockBegin: '' 91 | MacroBlockEnd: '' 92 | MaxEmptyLinesToKeep: 1 93 | NamespaceIndentation: All 94 | ObjCBinPackProtocolList: Auto 95 | ObjCBlockIndentWidth: 3 96 | ObjCSpaceAfterProperty: false 97 | ObjCSpaceBeforeProtocolList: true 98 | PenaltyBreakAssignment: 2 99 | PenaltyBreakBeforeFirstCallParameter: 19 100 | PenaltyBreakComment: 300 101 | PenaltyBreakFirstLessLess: 120 102 | PenaltyBreakString: 1000 103 | PenaltyBreakTemplateDeclaration: 10 104 | PenaltyExcessCharacter: 1000000 105 | PenaltyReturnTypeOnItsOwnLine: 60 106 | PointerAlignment: Right 107 | ReflowComments: true 108 | SortIncludes: false 109 | SortUsingDeclarations: true 110 | SpaceAfterCStyleCast: false 111 | SpaceAfterLogicalNot: false 112 | SpaceAfterTemplateKeyword: true 113 | SpaceBeforeAssignmentOperators: true 114 | SpaceBeforeCpp11BracedList: false 115 | SpaceBeforeCtorInitializerColon: true 116 | SpaceBeforeInheritanceColon: true 117 | SpaceBeforeParens: ControlStatements 118 | SpaceBeforeRangeBasedForLoopColon: true 119 | SpaceInEmptyBlock: false 120 | SpaceInEmptyParentheses: false 121 | SpacesBeforeTrailingComments: 1 122 | SpacesInAngles: false 123 | SpacesInConditionalStatement: false 124 | SpacesInContainerLiterals: true 125 | SpacesInCStyleCastParentheses: false 126 | SpacesInParentheses: false 127 | SpacesInSquareBrackets: false 128 | SpaceBeforeSquareBrackets: false 129 | Standard: Latest 130 | StatementMacros: 131 | - Q_UNUSED 132 | - QT_REQUIRE_VERSION 133 | TabWidth: 8 134 | UseCRLF: false 135 | UseTab: Never 136 | ... 137 | 138 | -------------------------------------------------------------------------------- /.github/workflows/cmake.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021 Luca Cappa 2 | # Released under the term specified in file LICENSE.txt 3 | # SPDX short identifier: MIT 4 | # 5 | # The peculiarity of this workflow is that assumes vcpkg stored as a submodule of this repository. 6 | # This workflow does the following: 7 | # - Restores vcpkg artifacts from cache. 8 | # - Sets up vcpkg if needed, then run CMake with CMakePreset.json using a configuration 9 | # that leverages the vcpkg's toolchain file. This will automatically run vcpkg to install dependencies 10 | # described by the vcpkg.json manifest file. It will be a no-op if those are restored from cache. 11 | # - Finally builds the sources with Ninja. 12 | name: build 13 | on: [push, pull_request, workflow_dispatch] 14 | 15 | jobs: 16 | VCPKG: 17 | name: ${{ matrix.os }}-${{ github.workflow }} 18 | runs-on: ${{ matrix.os }} 19 | strategy: 20 | fail-fast: false 21 | matrix: 22 | os: [ubuntu-latest, macos-latest, windows-latest] 23 | 24 | steps: 25 | - uses: actions/checkout@v3 26 | with: 27 | submodules: true 28 | 29 | - uses: lukka/get-cmake@latest 30 | if: startsWith(matrix.os, 'win') 31 | 32 | - name: Setup MacOS 33 | if: startsWith(matrix.os, 'macOS') 34 | run: brew install automake autoconf ninja cmake 35 | 36 | - name: Setup Ubuntu 37 | if: startsWith(matrix.os, 'ubuntu') 38 | run: sudo apt install ninja-build cmake 39 | 40 | - name: Run CMake+Ninja+CTest to generate/build/test. 41 | uses: lukka/run-cmake@v10 42 | id: runcmake-ninja 43 | with: 44 | configurePreset: 'ninja' 45 | buildPreset: 'ninja-release' 46 | testPreset: 'ninja-release' 47 | 48 | - name: Run CMake+MSVC+CTest to generate/build/test. 49 | uses: lukka/run-cmake@v10 50 | if: startsWith(matrix.os, 'win') 51 | id: runcmake-msvc 52 | with: 53 | configurePreset: 'msvc' 54 | buildPreset: 'msvc-release' 55 | testPreset: 'msvc-release' 56 | -------------------------------------------------------------------------------- /.github/workflows/properties/build.properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "clap", 3 | "description": "Build C/C++ code with CMake and Ninja.", 4 | "iconName": "cmake", 5 | "categories": ["CMake", "cpp", "cplusplus", "Ninja"] 6 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | # Visual Studio 35 | obj/ 36 | *.sln 37 | *.vcxproj 38 | *.vcxproj.filters 39 | *.vcxproj.user 40 | .vs/ 41 | packages/ 42 | target/ 43 | *.pdb 44 | packages.config 45 | CMakeSettings.json 46 | .vscode 47 | .cache 48 | 49 | # C++ IDE helpers 50 | compile_commands.json 51 | 52 | # IntelliJ IDEA 53 | .idea 54 | 55 | # CMake common patterns 56 | build*/ 57 | cmake-build*/ 58 | 59 | # A place to store stuff and get it git ignored 60 | ignore/* 61 | 62 | .DS_Store 63 | 64 | # Meson 65 | .meson-subproject* 66 | 67 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.17) 2 | enable_testing() 3 | 4 | # Extract the version from header file 5 | file(READ "include/clap/version.h" clap_version_header) 6 | string(REGEX MATCH "CLAP_VERSION_MAJOR ([0-9]+)" _ ${clap_version_header}) 7 | set(CLAP_VERSION_MAJOR ${CMAKE_MATCH_1}) 8 | string(REGEX MATCH "CLAP_VERSION_MINOR ([0-9]+)" _ ${clap_version_header}) 9 | set(CLAP_VERSION_MINOR ${CMAKE_MATCH_1}) 10 | string(REGEX MATCH "CLAP_VERSION_REVISION ([0-9]+)" _ ${clap_version_header}) 11 | set(CLAP_VERSION_REVISION ${CMAKE_MATCH_1}) 12 | 13 | message(STATUS "CLAP version: ${CLAP_VERSION_MAJOR}.${CLAP_VERSION_MINOR}.${CLAP_VERSION_REVISION}") 14 | 15 | project(CLAP LANGUAGES C CXX VERSION ${CLAP_VERSION_MAJOR}.${CLAP_VERSION_MINOR}.${CLAP_VERSION_REVISION}) 16 | 17 | option(CLAP_BUILD_TESTS "Should CLAP build tests and the like?" OFF) 18 | 19 | # If you use clap as a submodule of your plugin you need some interface projects 20 | # to allow you to link 21 | add_library(clap INTERFACE) 22 | target_include_directories(clap INTERFACE 23 | $ 24 | $) 25 | 26 | # `clap-core` is deprecated, please `clap` instead. 27 | add_library(clap-core ALIAS clap) 28 | 29 | include(GNUInstallDirs) 30 | install(DIRECTORY "include/clap" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") 31 | install(TARGETS clap EXPORT clap INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") 32 | install(EXPORT clap DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/clap" FILE "clap-config.cmake") 33 | 34 | include(CMakePackageConfigHelpers) 35 | write_basic_package_version_file( 36 | "${CMAKE_CURRENT_BINARY_DIR}/clap-config-version.cmake" 37 | VERSION "${PROJECT_VERSION}" 38 | COMPATIBILITY AnyNewerVersion) 39 | install(FILES "${CMAKE_CURRENT_BINARY_DIR}/clap-config-version.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/clap") 40 | 41 | # In addition to the above generated `clap-config.cmake` file, we'll also 42 | # provide a pkg-config file to make it easier to consume this library in a 43 | # portable way 44 | configure_file(clap.pc.in "${CMAKE_CURRENT_BINARY_DIR}/clap.pc" @ONLY) 45 | install(FILES "${CMAKE_CURRENT_BINARY_DIR}/clap.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") 46 | 47 | # clap-tests should always be available, to avoid build failing here and there 48 | # because the target doesn't exists 49 | add_custom_target(clap-tests) 50 | 51 | if (${CLAP_BUILD_TESTS}) 52 | message(STATUS "Including CLAP tests, compile tests, and versions") 53 | include(CheckIncludeFile) 54 | 55 | macro(clap_compile_cpp SUFFIX EXT STDC STDCPP) 56 | add_executable(clap-compile-${SUFFIX} EXCLUDE_FROM_ALL src/main.${EXT}) 57 | target_link_libraries(clap-compile-${SUFFIX} clap) 58 | set_target_properties(clap-compile-${SUFFIX} PROPERTIES 59 | C_STANDARD ${STDC} 60 | CXX_STANDARD ${STDCPP}) 61 | add_test(NAME test-clap-compile-${SUFFIX} COMMAND clap-compile-${SUFFIX}) 62 | add_dependencies(clap-tests clap-compile-${SUFFIX}) 63 | 64 | if (${EXT} STREQUAL "cc") 65 | target_compile_definitions(clap-compile-${SUFFIX} PRIVATE CLAP_COMPILE_TEST_CXX_VERSION=${STDCPP}) 66 | endif() 67 | 68 | if (${CMAKE_C_COMPILER_ID} STREQUAL "GNU" OR ${CMAKE_C_COMPILER_ID} STREQUAL "Clang") 69 | target_compile_options(clap-compile-${SUFFIX} PRIVATE -Wall -Wextra -pedantic) 70 | endif() 71 | 72 | if (${CMAKE_C_COMPILER_ID} STREQUAL "Clang") 73 | target_compile_options(clap-compile-${SUFFIX} PRIVATE -Werror=pragma-pack) 74 | endif() 75 | endmacro() 76 | 77 | clap_compile_cpp(c11 c 11 11) 78 | clap_compile_cpp(cpp11 cc 11 11) 79 | clap_compile_cpp(cpp14 cc 11 14) 80 | if(${CMAKE_VERSION} VERSION_LESS "3.21") 81 | message(STATUS "Skipping C17 tests due to older CMAKE_VERSION ${CMAKE_VERSION}") 82 | else() 83 | clap_compile_cpp(c17 c 17 17) 84 | endif() 85 | clap_compile_cpp(cpp17 cc 17 17) 86 | clap_compile_cpp(cpp20 cc 17 20) 87 | 88 | check_include_file(threads.h CLAP_HAS_THREADS_H) 89 | 90 | add_library(clap-plugin-template MODULE EXCLUDE_FROM_ALL src/plugin-template.c) 91 | target_link_libraries(clap-plugin-template PRIVATE clap) 92 | set_target_properties(clap-plugin-template PROPERTIES C_STANDARD 11) 93 | add_dependencies(clap-tests clap-plugin-template) 94 | 95 | if(CLAP_HAS_THREADS_H) 96 | target_compile_definitions(clap-plugin-template PRIVATE CLAP_HAS_THREADS_H) 97 | endif() 98 | 99 | if(CMAKE_SYSTEM_NAME STREQUAL "Linux") 100 | target_link_libraries(clap-plugin-template PRIVATE -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/src/linux-my_plug.version) 101 | target_link_libraries(clap-plugin-template PRIVATE -Wl,-z,defs) 102 | set_target_properties(clap-plugin-template PROPERTIES SUFFIX ".clap" PREFIX "") 103 | elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") 104 | target_link_options(clap-plugin-template PRIVATE -exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/src/macos-symbols.txt) 105 | 106 | set_target_properties(clap-plugin-template PROPERTIES 107 | BUNDLE True 108 | BUNDLE_EXTENSION clap 109 | MACOSX_BUNDLE_GUI_IDENTIFIER com.my_company.my_plug 110 | MACOSX_BUNDLE_BUNDLE_NAME my_plug 111 | MACOSX_BUNDLE_BUNDLE_VERSION "1" 112 | MACOSX_BUNDLE_SHORT_VERSION_STRING "1" 113 | MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/src/plugins.plist.in 114 | ) 115 | elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows") 116 | set_target_properties(clap-plugin-template PROPERTIES SUFFIX ".clap" PREFIX "") 117 | endif() 118 | endif() 119 | -------------------------------------------------------------------------------- /CMakePresets.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "cmakeMinimumRequired": { 4 | "major": 3, 5 | "minor": 17, 6 | "patch": 0 7 | }, 8 | "configurePresets": [ 9 | { 10 | "name": "ninja", 11 | "displayName": "Ninja", 12 | "description": "Configure and generate Ninja project files for all configurations", 13 | "binaryDir": "${sourceDir}/builds/${presetName}", 14 | "generator": "Ninja Multi-Config", 15 | "cacheVariables": { 16 | "CMAKE_EXPORT_COMPILE_COMMANDS": { 17 | "type": "boolean", 18 | "value": true 19 | }, 20 | "CLAP_BUILD_TESTS": { 21 | "type": "boolean", 22 | "value": true 23 | } 24 | } 25 | }, 26 | { 27 | "name": "msvc", 28 | "displayName": "MSVC", 29 | "description": "Configure and generate MSVC project files for all configurations", 30 | "binaryDir": "${sourceDir}/builds/${presetName}", 31 | "generator": "Visual Studio 17 2022", 32 | "cacheVariables": { 33 | "CMAKE_EXPORT_COMPILE_COMMANDS": { 34 | "type": "boolean", 35 | "value": true 36 | }, 37 | "CLAP_BUILD_TESTS": { 38 | "type": "boolean", 39 | "value": true 40 | } 41 | } 42 | } 43 | ], 44 | "buildPresets": [ 45 | { 46 | "name": "ninja-release", 47 | "configurePreset": "ninja", 48 | "displayName": "Build ninja-release", 49 | "description": "Build ninja Release configuration", 50 | "configuration": "RelWithDebInfo", 51 | "targets": ["clap-tests"] 52 | }, 53 | { 54 | "name": "msvc-release", 55 | "configurePreset": "msvc", 56 | "displayName": "Build msvc-release", 57 | "description": "Build msvc Release configuration", 58 | "configuration": "RelWithDebInfo", 59 | "targets": ["clap-tests"] 60 | } 61 | ], 62 | "testPresets": [ 63 | { 64 | "name": "ninja-release", 65 | "configurePreset": "ninja", 66 | "configuration": "RelWithDebInfo" 67 | }, 68 | { 69 | "name": "msvc-release", 70 | "configurePreset": "msvc", 71 | "configuration": "RelWithDebInfo" 72 | } 73 | ] 74 | } -------------------------------------------------------------------------------- /Contributors.md: -------------------------------------------------------------------------------- 1 | CLAP is the result of countless conversations, brainstorms, reviews, tests, 2 | and iterations. A legion of developers with different backgrounds and points 3 | of view worked together and converged on a, well, clever solution. 4 | 5 | All of the contributors cannot be listed. But here are a few, along with a 6 | thank you to all involved: 7 | 8 | - Alexandre Bique (Bitwig and u-he/linux) 9 | - Claes Johanson (Bitwig) 10 | - David Schornsheim (Schroedingers-Cat, u-he) 11 | - Frank Hoffmann (u-he) 12 | - Giel Bremmers (MultitrackStudio) 13 | - Jan Storm (u-he) 14 | - John Schwartz (Cockos) 15 | - Nicholas Allen (Bitwig) 16 | - Paul Walker (BaconPaul, Surge) 17 | - Placidus Schelbert (Bitwig) 18 | - Robbert van der Helm (yabridge) 19 | - Robin Gareus (Ardour) 20 | - Thomas Binek (tas, u-he) 21 | - Timo Kaluza 22 | - Tor-Helge Skei (MIP2) 23 | - Urs Heckmann (u-he) 24 | - Vadim Zavalishin 25 | - William Light (LHI Audio) 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Alexandre BIQUE 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | 4 | 5 | CLAP 6 | 7 |

8 | 9 | - [Learn about CLAP](#learn-about-clap) 10 | - [Entry point](#entry-point) 11 | - [Extensions](#extensions) 12 | - [Fundamental extensions](#fundamental-extensions) 13 | - [Support extensions](#support-extensions) 14 | - [Deeper Host integration](#deeper-host-integration) 15 | - [Third-party extensions](#third-party-extensions) 16 | - [Adapters](#adapters) 17 | - [Resources](#resources) 18 | - [Examples](#examples) 19 | - [Community related projects](#community-related-projects) 20 | - [Programming Language Bindings](#programming-language-bindings) 21 | - [Artwork](#artwork) 22 | 23 | # Learn about CLAP 24 | 25 | CLAP stands for **CL**ever **A**udio **P**lugin. It is an interface that 26 | provides a stable ABI to define a standard for *Digital Audio Workstations* and 27 | audio plugins (synthesizers, audio effects, ...) to work together. 28 | 29 | The ABI, or **A**pplication **B**inary **I**nterface, serves as a means of 30 | communication between a host and a plugin. It provides backwards compatibility, 31 | that is, a plugin binary compiled with CLAP 1.x can be loaded by any other 32 | CLAP 1.y. 33 | 34 | To work with CLAP, include [clap/clap.h](include/clap/clap.h). 35 | To also include the draft extensions, include [clap/all.h](include/clap/all.h). 36 | 37 | The two most important objects are `clap_host` and `clap_plugin`. 38 | 39 | [src/plugin-template.c](src/plugin-template.c) is a very minimal example which demonstrates how to wire a CLAP plugin. 40 | 41 | ## Entry point 42 | 43 | The entry point is declared in [entry.h](include/clap/entry.h). 44 | 45 | ## Extensions 46 | 47 | Most features come from extensions, which are in fact C interfaces. 48 | ```C 49 | // host extension 50 | const clap_host_log *log = host->extension(host, CLAP_EXT_LOG); 51 | if (log) 52 | log->log(host, CLAP_LOG_INFO, "Hello World! ;^)"); 53 | 54 | // plugin extension 55 | const clap_plugin_params *params = plugin->extension(plugin, CLAP_EXT_PARAMS); 56 | if (params) 57 | { 58 | uint32_t paramsCount = params->count(plugin); 59 | // ... 60 | } 61 | ``` 62 | 63 | The extensions are defined in the [ext](include/clap/ext) folder. 64 | 65 | Some extensions are still in the progress of being designed and they are in 66 | the [draft](include/clap/ext/draft) folder. 67 | 68 | An extension comes with: 69 | - a header `#include ` 70 | - an extension identifier: `#define CLAP_EXT_XXX "clap/XXX"` 71 | - host interfaces are named like: `struct clap_host_xxx` 72 | - plugin interfaces are named like: `struct clap_plugin_xxx` 73 | - each method must have a clear thread specification 74 | 75 | You can create your own extensions and share them. Make sure that the extension identifier: 76 | - includes versioning in case the ABI breaks 77 | - is a unique identifier 78 | 79 | **All strings are valid UTF-8**. 80 | 81 | ## Fundamental extensions 82 | 83 | This is a list of the extensions that you most likely want to implement 84 | and use to get a basic plugin experience: 85 | - [state](include/clap/ext/state.h), save and load the plugin state 86 | - [state-context](include/clap/ext/state-context.h), same as state but with additional context info (preset, duplicate, project) 87 | - [resource-directory](include/clap/ext/draft/resource-directory.h), host provided folder for the plugin to save extra resource like multi-samples, ... (draft) 88 | - [params](include/clap/ext/params.h), parameters management 89 | - [note-ports](include/clap/ext/note-ports.h), define the note ports 90 | - [audio-ports](include/clap/ext/audio-ports.h), define the audio ports 91 | - [surround](include/clap/ext/surround.h), inspect surround channel mapping 92 | - [ambisonic](include/clap/ext/draft/ambisonic.h), inspect ambisonic channel mapping 93 | - [configurable-audio-ports](include/clap/ext/configurable-audio-ports.h), request the plugin to apply a given configuration 94 | - [audio-ports-config](include/clap/ext/audio-ports-config.h), simple list of pre-defined audio ports configurations, meant to be exposed to the user 95 | - [audio-ports-activation](include/clap/ext/audio-ports-activation.h), activate and deactivate a given audio port 96 | - [extensible-audio-ports](include/clap/ext/draft/extensible-audio-ports.h), let the host add audio ports to the plugin, this is useful for dynamic number of audio inputs (draft) 97 | - [render](include/clap/ext/render.h), renders realtime or offline 98 | - [latency](include/clap/ext/latency.h), report the plugin latency 99 | - [tail](include/clap/ext/tail.h), processing tail length 100 | - [gui](include/clap/ext/gui.h), generic gui controller 101 | - [voice-info](include/clap/ext/voice-info.h), let the host know how many voices the plugin has, this is important for polyphonic modulations 102 | - [track-info](include/clap/ext/track-info.h), give some info to the plugin about the track it belongs to 103 | - [tuning](include/clap/ext/draft/tuning.h), host provided microtuning (draft) 104 | - [triggers](include/clap/ext/draft/triggers.h), plugin's triggers, similar to parameters but stateless 105 | 106 | ## Support extensions 107 | 108 | - [thread-check](include/clap/ext/thread-check.h), check which thread you are currently on, useful for correctness validation 109 | - [thread-pool](include/clap/ext/thread-pool.h), use the host thread pool 110 | - [log](include/clap/ext/log.h), lets the host aggregate plugin logs 111 | - [timer-support](include/clap/ext/timer-support.h), lets the plugin register timer handlers 112 | - [posix-fd-support](include/clap/ext/posix-fd-support.h), lets the plugin register I/O handlers 113 | 114 | ## Deeper Host integration 115 | 116 | - [remote-controls](include/clap/ext/remote-controls.h), bank of controls that can be mapped on a controlles with 8 knobs 117 | - [preset-discovery](include/clap/factory/preset-discovery.h), let the host index the plugin's preset in their native file format 118 | - [preset-load](include/clap/ext/preset-load.h), let the host ask the plugin to load a preset 119 | - [param-indication](include/clap/ext/param-indication.h), let the plugin know when a physical control is mapped to a parameter and if there is automation data 120 | - [note-name](include/clap/ext/note-name.h), give a name to notes, useful for drum machines 121 | - [transport-control](include/clap/ext/draft/transport-control.h), let the plugin control the host's transport (draft) 122 | - [context-menu](include/clap/ext/context-menu.h), exchange context menu entries between host and plugin, let the plugin ask the host to popup its own context menu 123 | 124 | ## Third-party extensions 125 | 126 | - [`cockos.reaper_extension`](https://github.com/justinfrankel/reaper-sdk/blob/main/reaper-plugins/reaper_plugin.h#L138), access the [REAPER](http://reaper.fm) API 127 | 128 | # Adapters 129 | 130 | - [clap-wrapper](https://github.com/free-audio/clap-wrapper), wrappers for using CLAP in other plugin environments 131 | 132 | # Resources 133 | 134 | - [clap-validator](https://github.com/robbert-vdh/clap-validator), a validator and automatic test suite for CLAP plugins. 135 | - [clapdb](https://clapdb.tech), a list of plugins and DAWs which supports CLAP 136 | 137 | ## Examples 138 | 139 | - [clap-host](https://github.com/free-audio/clap-host), very simple host 140 | - [clap-plugins](https://github.com/free-audio/clap-plugins), very simple plugins 141 | 142 | ## Community related projects 143 | 144 | - [clap-juce-extension](https://github.com/free-audio/clap-juce-extension), juce add-on 145 | - [MIP2](https://github.com/skei/MIP2), host and plugins 146 | - [Avendish](https://github.com/celtera/avendish), a reflection-based API for media plug-ins in C++ which supports Clap 147 | - [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 148 | - [iPlug2](https://iplug2.github.io), a liberally licensed C++ audio plug-in framework that supports Clap 149 | 150 | ## Programming Language Bindings 151 | 152 | - [clap-sys](https://github.com/glowcoil/clap-sys), rust binding 153 | - [CLAP-for-Delphi](https://github.com/Bremmers/CLAP-for-Delphi), Delphi binding 154 | - [clap-zig-bindings](https://sr.ht/~interpunct/clap-zig-bindings/), Zig bindings 155 | - [CLAP for Ada](https://github.com/ficorax/cfa), Ada 2012 binding 156 | 157 | ## Artwork 158 | 159 | - [CLAP Logo Pack.zip](https://github.com/free-audio/clap/files/8805281/CLAP.Logo.Pack.zip) 160 | -------------------------------------------------------------------------------- /artwork/CLAP Full Logo.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/free-audio/clap/69a69252fdd6ac1d06e246d9a04c0a89d9607a17/artwork/CLAP Full Logo.eps -------------------------------------------------------------------------------- /artwork/CLAP Full Logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 7 | 10 | 12 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /artwork/CLAP Icon Extension.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/free-audio/clap/69a69252fdd6ac1d06e246d9a04c0a89d9607a17/artwork/CLAP Icon Extension.eps -------------------------------------------------------------------------------- /artwork/CLAP Icon Extension.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /artwork/CLAP Icon.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/free-audio/clap/69a69252fdd6ac1d06e246d9a04c0a89d9607a17/artwork/CLAP Icon.eps -------------------------------------------------------------------------------- /artwork/CLAP Icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 7 | 9 | 10 | -------------------------------------------------------------------------------- /artwork/CLAP Logo Guidelines.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/free-audio/clap/69a69252fdd6ac1d06e246d9a04c0a89d9607a17/artwork/CLAP Logo Guidelines.pdf -------------------------------------------------------------------------------- /artwork/CLAP Simple Logo.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/free-audio/clap/69a69252fdd6ac1d06e246d9a04c0a89d9607a17/artwork/CLAP Simple Logo.eps -------------------------------------------------------------------------------- /artwork/CLAP Simple Logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /artwork/clap-full-logo-black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/free-audio/clap/69a69252fdd6ac1d06e246d9a04c0a89d9607a17/artwork/clap-full-logo-black.png -------------------------------------------------------------------------------- /artwork/clap-full-logo-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/free-audio/clap/69a69252fdd6ac1d06e246d9a04c0a89d9607a17/artwork/clap-full-logo-white.png -------------------------------------------------------------------------------- /artwork/clap-simple-logo-black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/free-audio/clap/69a69252fdd6ac1d06e246d9a04c0a89d9607a17/artwork/clap-simple-logo-black.png -------------------------------------------------------------------------------- /artwork/clap-simple-logo-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/free-audio/clap/69a69252fdd6ac1d06e246d9a04c0a89d9607a17/artwork/clap-simple-logo-white.png -------------------------------------------------------------------------------- /clap.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@CMAKE_INSTALL_PREFIX@ 2 | includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ 3 | 4 | Name: clap 5 | Description: The interface headers for the CLAP audio plugin API 6 | Version: @CMAKE_PROJECT_VERSION@ 7 | 8 | Cflags: -I${includedir} 9 | -------------------------------------------------------------------------------- /conventions/extension-id.md: -------------------------------------------------------------------------------- 1 | # Extension ID 2 | 3 | ## Naming 4 | 5 | The extension shall be named in the form: `clap.$NAME/$REV`. 6 | Where: 7 | - `$NAME` is the name of the exension. 8 | - `$REV` is the revision of the extension. This is an integer that is incremented for each iteration. It should start at 1. 9 | 10 | For extensions made by third-parties and not officially published by the CLAP project, please use the following form: `$REVERSE_URI.$NAME/$REV`. 11 | Where: 12 | - `$REVERSE_URI` would be something like `com.bitwig`. 13 | 14 | ## Draft 15 | 16 | An extension is considered a draft extension if it is in the [draft](../include/clap/ext/draft/) folder. 17 | Make sure to also include it in [all.h](../include/clap/all.h). 18 | 19 | When the extension is migrating from draft to stable, its extension ID must not change. 20 | Move its inclusion from [all.h](../include/clap/all.h) into [clap.h](../include/clap/clap.h). 21 | 22 | All extensions must go though the draft phase first. 23 | 24 | ## For factory ID 25 | 26 | Everything about the extension id symmetrically applies to factory id. 27 | 28 | ## History 29 | 30 | Before version 1.2.0 when this document was written, existing extensions didn't honor these rules. 31 | We wanted to stabilize some draft extensions without breaking compatibility, yet their extension IDs contained the string `draft`. 32 | While these strings weren't user-facing, we still wanted to remove them, so we updated the extension IDs according to this document and introduced IDs with `_COMPAT` suffixes to provide backward compatibility with the draft versions. 33 | -------------------------------------------------------------------------------- /include/clap/all.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "clap.h" 4 | 5 | #include "factory/draft/plugin-invalidation.h" 6 | #include "factory/draft/plugin-state-converter.h" 7 | 8 | #include "ext/draft/extensible-audio-ports.h" 9 | #include "ext/draft/gain-adjustment-metering.h" 10 | #include "ext/draft/mini-curve-display.h" 11 | #include "ext/draft/project-location.h" 12 | #include "ext/draft/resource-directory.h" 13 | #include "ext/draft/scratch-memory.h" 14 | #include "ext/draft/transport-control.h" 15 | #include "ext/draft/triggers.h" 16 | #include "ext/draft/tuning.h" 17 | #include "ext/draft/undo.h" 18 | -------------------------------------------------------------------------------- /include/clap/audio-buffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "private/std.h" 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | // Sample code for reading a stereo buffer: 10 | // 11 | // bool isLeftConstant = (buffer->constant_mask & (1 << 0)) != 0; 12 | // bool isRightConstant = (buffer->constant_mask & (1 << 1)) != 0; 13 | // 14 | // for (int i = 0; i < N; ++i) { 15 | // float l = data32[0][isLeftConstant ? 0 : i]; 16 | // float r = data32[1][isRightConstant ? 0 : i]; 17 | // } 18 | // 19 | // Note: checking the constant mask is optional, and this implies that 20 | // the buffer must be filled with the constant value. 21 | // Rationale: if a buffer reader doesn't check the constant mask, then it may 22 | // process garbage samples and in result, garbage samples may be transmitted 23 | // to the audio interface with all the bad consequences it can have. 24 | // 25 | // The constant mask is a hint. 26 | typedef struct clap_audio_buffer { 27 | // Either data32 or data64 pointer will be set. 28 | float **data32; 29 | double **data64; 30 | uint32_t channel_count; 31 | uint32_t latency; // latency from/to the audio interface 32 | uint64_t constant_mask; 33 | } clap_audio_buffer_t; 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif 38 | -------------------------------------------------------------------------------- /include/clap/clap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * CLAP - CLever Audio Plugin 3 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~ 4 | * 5 | * Copyright (c) 2014...2022 Alexandre BIQUE 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in 15 | * all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | * THE SOFTWARE. 24 | */ 25 | 26 | #pragma once 27 | 28 | #include "entry.h" 29 | 30 | #include "factory/plugin-factory.h" 31 | #include "factory/preset-discovery.h" 32 | 33 | #include "plugin.h" 34 | #include "plugin-features.h" 35 | #include "host.h" 36 | #include "universal-plugin-id.h" 37 | 38 | #include "ext/ambisonic.h" 39 | #include "ext/audio-ports-activation.h" 40 | #include "ext/audio-ports-config.h" 41 | #include "ext/audio-ports.h" 42 | #include "ext/configurable-audio-ports.h" 43 | #include "ext/context-menu.h" 44 | #include "ext/event-registry.h" 45 | #include "ext/gui.h" 46 | #include "ext/latency.h" 47 | #include "ext/log.h" 48 | #include "ext/note-name.h" 49 | #include "ext/note-ports.h" 50 | #include "ext/param-indication.h" 51 | #include "ext/params.h" 52 | #include "ext/posix-fd-support.h" 53 | #include "ext/preset-load.h" 54 | #include "ext/remote-controls.h" 55 | #include "ext/render.h" 56 | #include "ext/state-context.h" 57 | #include "ext/state.h" 58 | #include "ext/surround.h" 59 | #include "ext/tail.h" 60 | #include "ext/thread-check.h" 61 | #include "ext/thread-pool.h" 62 | #include "ext/timer-support.h" 63 | #include "ext/track-info.h" 64 | #include "ext/voice-info.h" 65 | -------------------------------------------------------------------------------- /include/clap/color.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "private/std.h" 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | typedef struct clap_color { 10 | uint8_t alpha; 11 | uint8_t red; 12 | uint8_t green; 13 | uint8_t blue; 14 | } clap_color_t; 15 | 16 | static const CLAP_CONSTEXPR clap_color_t CLAP_COLOR_TRANSPARENT = { 0, 0, 0, 0 }; 17 | 18 | #ifdef __cplusplus 19 | } 20 | #endif 21 | -------------------------------------------------------------------------------- /include/clap/entry.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "version.h" 4 | #include "private/macros.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | // This interface is the entry point of the dynamic library. 11 | // 12 | // CLAP plugins standard search path: 13 | // 14 | // Linux 15 | // - ~/.clap 16 | // - /usr/lib/clap 17 | // 18 | // Windows 19 | // - %COMMONPROGRAMFILES%\CLAP 20 | // - %LOCALAPPDATA%\Programs\Common\CLAP 21 | // 22 | // MacOS 23 | // - /Library/Audio/Plug-Ins/CLAP 24 | // - ~/Library/Audio/Plug-Ins/CLAP 25 | // 26 | // In addition to the OS-specific default locations above, a CLAP host must query the environment 27 | // for a CLAP_PATH variable, which is a list of directories formatted in the same manner as the host 28 | // OS binary search path (PATH on Unix, separated by `:` and Path on Windows, separated by ';', as 29 | // of this writing). 30 | // 31 | // Each directory should be recursively searched for files and/or bundles as appropriate in your OS 32 | // ending with the extension `.clap`. 33 | // 34 | // init and deinit in most cases are called once, in a matched pair, when the dso is loaded / unloaded. 35 | // In some rare situations it may be called multiple times in a process, so the functions must be defensive, 36 | // mutex locking and counting calls if undertaking non trivial non idempotent actions. 37 | // 38 | // Rationale: 39 | // 40 | // The intent of the init() and deinit() functions is to provide a "normal" initialization patterh 41 | // which occurs when the shared object is loaded or unloaded. As such, hosts will call each once and 42 | // in matched pairs. In CLAP specifications prior to 1.2.0, this single-call was documented as a 43 | // requirement. 44 | // 45 | // We realized, though, that this is not a requirement hosts can meet. If hosts load a plugin 46 | // which itself wraps another CLAP for instance, while also loading that same clap in its memory 47 | // space, both the host and the wrapper will call init() and deinit() and have no means to communicate 48 | // the state. 49 | // 50 | // With CLAP 1.2.0 and beyond we are changing the spec to indicate that a host should make an 51 | // absolute best effort to call init() and deinit() once, and always in matched pairs (for every 52 | // init() which returns true, one deinit() should be called). 53 | // 54 | // This takes the de-facto burden on plugin writers to deal with multiple calls into a hard requirement. 55 | // 56 | // Most init() / deinit() pairs we have seen are the relatively trivial {return true;} and {}. But 57 | // if your init() function does non-trivial one time work, the plugin author must maintain a counter 58 | // and must manage a mutex lock. The most obvious implementation will maintain a static counter and a 59 | // global mutex, increment the counter on each init, decrement it on each deinit, and only undertake 60 | // the init or deinit action when the counter is zero. 61 | typedef struct clap_plugin_entry { 62 | clap_version_t clap_version; // initialized to CLAP_VERSION 63 | 64 | // Initializes the DSO. 65 | // 66 | // This function must be called first, before any-other CLAP-related function or symbol from this 67 | // DSO. 68 | // 69 | // It also must only be called once, until a later call to deinit() is made, after which init() 70 | // can be called once more to re-initialize the DSO. 71 | // This enables hosts to e.g. quickly load and unload a DSO for scanning its plugins, and then 72 | // load it again later to actually use the plugins if needed. 73 | // 74 | // As stated above, even though hosts are forbidden to do so directly, multiple calls before any 75 | // deinit() call may still happen. Implementations *should* take this into account, and *must* 76 | // do so as of CLAP 1.2.0. 77 | // 78 | // It should be as fast as possible, in order to perform a very quick scan of the plugin 79 | // descriptors. 80 | // 81 | // It is forbidden to display graphical user interfaces in this call. 82 | // It is forbidden to perform any user interaction in this call. 83 | // 84 | // If the initialization depends upon expensive computation, maybe try to do them ahead of time 85 | // and cache the result. 86 | // 87 | // Returns true on success. If init() returns false, then the DSO must be considered 88 | // uninitialized, and the host must not call deinit() nor any other CLAP-related symbols from the 89 | // DSO. 90 | // This function also returns true in the case where the DSO is already initialized, and no 91 | // actual initialization work is done in this call, as explain above. 92 | // 93 | // plugin_path is the path to the DSO (Linux, Windows), or the bundle (macOS). 94 | // 95 | // This function may be called on any thread, including a different one from the one a later call 96 | // to deinit() (or a later init()) can be made. 97 | // However, it is forbidden to call this function simultaneously from multiple threads. 98 | // It is also forbidden to call it simultaneously with *any* other CLAP-related symbols from the 99 | // DSO, including (but not limited to) deinit(). 100 | bool(CLAP_ABI *init)(const char *plugin_path); 101 | 102 | // De-initializes the DSO, freeing any resources allocated or initialized by init(). 103 | // 104 | // After this function is called, no more calls into the DSO must be made, except calling init() 105 | // again to re-initialize the DSO. 106 | // This means that after deinit() is called, the DSO can be considered to be in the same state 107 | // as if init() was never called at all yet, enabling it to be re-initialized as needed. 108 | // 109 | // As stated above, even though hosts are forbidden to do so directly, multiple calls before any 110 | // new init() call may still happen. Implementations *should* take this into account, and *must* 111 | // do so as of CLAP 1.2.0. 112 | // 113 | // Just like init(), this function may be called on any thread, including a different one from 114 | // the one init() was called from, or from the one a later init() call can be made. 115 | // However, it is forbidden to call this function simultaneously from multiple threads. 116 | // It is also forbidden to call it simultaneously with *any* other CLAP-related symbols from the 117 | // DSO, including (but not limited to) deinit(). 118 | void(CLAP_ABI *deinit)(void); 119 | 120 | // Get the pointer to a factory. See factory/plugin-factory.h for an example. 121 | // 122 | // Returns null if the factory is not provided. 123 | // The returned pointer must *not* be freed by the caller. 124 | // 125 | // Unlike init() and deinit(), this function can be called simultaneously by multiple threads. 126 | // 127 | // [thread-safe] 128 | const void *(CLAP_ABI *get_factory)(const char *factory_id); 129 | } clap_plugin_entry_t; 130 | 131 | /* Entry point */ 132 | CLAP_EXPORT extern const clap_plugin_entry_t clap_entry; 133 | 134 | #ifdef __cplusplus 135 | } 136 | #endif 137 | -------------------------------------------------------------------------------- /include/clap/ext/ambisonic.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../plugin.h" 4 | 5 | // This extension can be used to specify the channel mapping used by the plugin. 6 | static CLAP_CONSTEXPR const char CLAP_EXT_AMBISONIC[] = "clap.ambisonic/3"; 7 | 8 | // The latest draft is 100% compatible. 9 | // This compat ID may be removed in 2026. 10 | static CLAP_CONSTEXPR const char CLAP_EXT_AMBISONIC_COMPAT[] = "clap.ambisonic.draft/3"; 11 | 12 | static CLAP_CONSTEXPR const char CLAP_PORT_AMBISONIC[] = "ambisonic"; 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | enum clap_ambisonic_ordering { 19 | // FuMa channel ordering 20 | CLAP_AMBISONIC_ORDERING_FUMA = 0, 21 | 22 | // ACN channel ordering 23 | CLAP_AMBISONIC_ORDERING_ACN = 1, 24 | }; 25 | 26 | enum clap_ambisonic_normalization { 27 | CLAP_AMBISONIC_NORMALIZATION_MAXN = 0, 28 | CLAP_AMBISONIC_NORMALIZATION_SN3D = 1, 29 | CLAP_AMBISONIC_NORMALIZATION_N3D = 2, 30 | CLAP_AMBISONIC_NORMALIZATION_SN2D = 3, 31 | CLAP_AMBISONIC_NORMALIZATION_N2D = 4, 32 | }; 33 | 34 | typedef struct clap_ambisonic_config { 35 | uint32_t ordering; // see clap_ambisonic_ordering 36 | uint32_t normalization; // see clap_ambisonic_normalization 37 | } clap_ambisonic_config_t; 38 | 39 | typedef struct clap_plugin_ambisonic { 40 | // Returns true if the given configuration is supported. 41 | // [main-thread] 42 | bool(CLAP_ABI *is_config_supported)(const clap_plugin_t *plugin, 43 | const clap_ambisonic_config_t *config); 44 | 45 | // Returns true on success 46 | // [main-thread] 47 | bool(CLAP_ABI *get_config)(const clap_plugin_t *plugin, 48 | bool is_input, 49 | uint32_t port_index, 50 | clap_ambisonic_config_t *config); 51 | 52 | } clap_plugin_ambisonic_t; 53 | 54 | typedef struct clap_host_ambisonic { 55 | // Informs the host that the info has changed. 56 | // The info can only change when the plugin is de-activated. 57 | // [main-thread] 58 | void(CLAP_ABI *changed)(const clap_host_t *host); 59 | } clap_host_ambisonic_t; 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif 64 | -------------------------------------------------------------------------------- /include/clap/ext/audio-ports-activation.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../plugin.h" 4 | 5 | /// @page Audio Ports Activation 6 | /// 7 | /// This extension provides a way for the host to activate and de-activate audio ports. 8 | /// Deactivating a port provides the following benefits: 9 | /// - the plugin knows ahead of time that a given input is not present and can choose 10 | /// an optimized computation path, 11 | /// - the plugin knows that an output is not consumed by the host, and doesn't need to 12 | /// compute it. 13 | /// 14 | /// Audio ports can only be activated or deactivated when the plugin is deactivated, unless 15 | /// can_activate_while_processing() returns true. 16 | /// 17 | /// Audio buffers must still be provided if the audio port is deactivated. 18 | /// In such case, they shall be filled with 0 (or whatever is the neutral value in your context) 19 | /// and the constant_mask shall be set. 20 | /// 21 | /// Audio ports are initially in the active state after creating the plugin instance. 22 | /// Audio ports state are not saved in the plugin state, so the host must restore the 23 | /// audio ports state after creating the plugin instance. 24 | /// 25 | /// Audio ports state is invalidated by clap_plugin_audio_ports_config.select() and 26 | /// clap_host_audio_ports.rescan(CLAP_AUDIO_PORTS_RESCAN_LIST). 27 | 28 | static CLAP_CONSTEXPR const char CLAP_EXT_AUDIO_PORTS_ACTIVATION[] = 29 | "clap.audio-ports-activation/2"; 30 | 31 | // The latest draft is 100% compatible. 32 | // This compat ID may be removed in 2026. 33 | static CLAP_CONSTEXPR const char CLAP_EXT_AUDIO_PORTS_ACTIVATION_COMPAT[] = 34 | "clap.audio-ports-activation/draft-2"; 35 | 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif 39 | 40 | typedef struct clap_plugin_audio_ports_activation { 41 | // Returns true if the plugin supports activation/deactivation while processing. 42 | // [main-thread] 43 | bool(CLAP_ABI *can_activate_while_processing)(const clap_plugin_t *plugin); 44 | 45 | // Activate the given port. 46 | // 47 | // It is only possible to activate and de-activate on the audio-thread if 48 | // can_activate_while_processing() returns true. 49 | // 50 | // sample_size indicate if the host will provide 32 bit audio buffers or 64 bits one. 51 | // Possible values are: 32, 64 or 0 if unspecified. 52 | // 53 | // returns false if failed, or invalid parameters 54 | // [active ? audio-thread : main-thread] 55 | bool(CLAP_ABI *set_active)(const clap_plugin_t *plugin, 56 | bool is_input, 57 | uint32_t port_index, 58 | bool is_active, 59 | uint32_t sample_size); 60 | } clap_plugin_audio_ports_activation_t; 61 | 62 | #ifdef __cplusplus 63 | } 64 | #endif 65 | -------------------------------------------------------------------------------- /include/clap/ext/audio-ports-config.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../string-sizes.h" 4 | #include "../plugin.h" 5 | #include "audio-ports.h" 6 | 7 | /// @page Audio Ports Config 8 | /// 9 | /// This extension let the plugin provide port configurations presets. 10 | /// For example mono, stereo, surround, ambisonic, ... 11 | /// 12 | /// After the plugin initialization, the host may scan the list of configurations and eventually 13 | /// select one that fits the plugin context. The host can only select a configuration if the plugin 14 | /// is deactivated. 15 | /// 16 | /// A configuration is a very simple description of the audio ports: 17 | /// - it describes the main input and output ports 18 | /// - it has a name that can be displayed to the user 19 | /// 20 | /// The idea behind the configurations, is to let the user choose one via a menu. 21 | /// 22 | /// Plugins with very complex configuration possibilities should let the user configure the ports 23 | /// from the plugin GUI, and call @ref clap_host_audio_ports.rescan(CLAP_AUDIO_PORTS_RESCAN_ALL). 24 | /// 25 | /// To inquire the exact bus layout, the plugin implements the clap_plugin_audio_ports_config_info_t 26 | /// extension where all busses can be retrieved in the same way as in the audio-port extension. 27 | 28 | static CLAP_CONSTEXPR const char CLAP_EXT_AUDIO_PORTS_CONFIG[] = "clap.audio-ports-config"; 29 | 30 | static CLAP_CONSTEXPR const char CLAP_EXT_AUDIO_PORTS_CONFIG_INFO[] = 31 | "clap.audio-ports-config-info/1"; 32 | 33 | // The latest draft is 100% compatible. 34 | // This compat ID may be removed in 2026. 35 | static CLAP_CONSTEXPR const char CLAP_EXT_AUDIO_PORTS_CONFIG_INFO_COMPAT[] = 36 | "clap.audio-ports-config-info/draft-0"; 37 | 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | // Minimalistic description of ports configuration 43 | typedef struct clap_audio_ports_config { 44 | clap_id id; 45 | char name[CLAP_NAME_SIZE]; 46 | 47 | uint32_t input_port_count; 48 | uint32_t output_port_count; 49 | 50 | // main input info 51 | bool has_main_input; 52 | uint32_t main_input_channel_count; 53 | const char *main_input_port_type; 54 | 55 | // main output info 56 | bool has_main_output; 57 | uint32_t main_output_channel_count; 58 | const char *main_output_port_type; 59 | } clap_audio_ports_config_t; 60 | 61 | // The audio ports config scan has to be done while the plugin is deactivated. 62 | typedef struct clap_plugin_audio_ports_config { 63 | // Gets the number of available configurations 64 | // [main-thread] 65 | uint32_t(CLAP_ABI *count)(const clap_plugin_t *plugin); 66 | 67 | // Gets information about a configuration 68 | // Returns true on success and stores the result into config. 69 | // [main-thread] 70 | bool(CLAP_ABI *get)(const clap_plugin_t *plugin, 71 | uint32_t index, 72 | clap_audio_ports_config_t *config); 73 | 74 | // Selects the configuration designated by id 75 | // Returns true if the configuration could be applied. 76 | // Once applied the host should scan again the audio ports. 77 | // [main-thread & plugin-deactivated] 78 | bool(CLAP_ABI *select)(const clap_plugin_t *plugin, clap_id config_id); 79 | } clap_plugin_audio_ports_config_t; 80 | 81 | // Extended config info 82 | typedef struct clap_plugin_audio_ports_config_info { 83 | 84 | // Gets the id of the currently selected config, or CLAP_INVALID_ID if the current port 85 | // layout isn't part of the config list. 86 | // 87 | // [main-thread] 88 | clap_id(CLAP_ABI *current_config)(const clap_plugin_t *plugin); 89 | 90 | // Get info about an audio port, for a given config_id. 91 | // This is analogous to clap_plugin_audio_ports.get(). 92 | // Returns true on success and stores the result into info. 93 | // [main-thread] 94 | bool(CLAP_ABI *get)(const clap_plugin_t *plugin, 95 | clap_id config_id, 96 | uint32_t port_index, 97 | bool is_input, 98 | clap_audio_port_info_t *info); 99 | } clap_plugin_audio_ports_config_info_t; 100 | 101 | typedef struct clap_host_audio_ports_config { 102 | // Rescan the full list of configs. 103 | // [main-thread] 104 | void(CLAP_ABI *rescan)(const clap_host_t *host); 105 | } clap_host_audio_ports_config_t; 106 | 107 | #ifdef __cplusplus 108 | } 109 | #endif 110 | -------------------------------------------------------------------------------- /include/clap/ext/audio-ports.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../plugin.h" 4 | #include "../string-sizes.h" 5 | 6 | /// @page Audio Ports 7 | /// 8 | /// This extension provides a way for the plugin to describe its current audio ports. 9 | /// 10 | /// If the plugin does not implement this extension, it won't have audio ports. 11 | /// 12 | /// 32 bits support is required for both host and plugins. 64 bits audio is optional. 13 | /// 14 | /// The plugin is only allowed to change its ports configuration while it is deactivated. 15 | 16 | static CLAP_CONSTEXPR const char CLAP_EXT_AUDIO_PORTS[] = "clap.audio-ports"; 17 | static CLAP_CONSTEXPR const char CLAP_PORT_MONO[] = "mono"; 18 | static CLAP_CONSTEXPR const char CLAP_PORT_STEREO[] = "stereo"; 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | enum { 25 | // This port is the main audio input or output. 26 | // There can be only one main input and main output. 27 | // Main port must be at index 0. 28 | CLAP_AUDIO_PORT_IS_MAIN = 1 << 0, 29 | 30 | // This port can be used with 64 bits audio 31 | CLAP_AUDIO_PORT_SUPPORTS_64BITS = 1 << 1, 32 | 33 | // 64 bits audio is preferred with this port 34 | CLAP_AUDIO_PORT_PREFERS_64BITS = 1 << 2, 35 | 36 | // This port must be used with the same sample size as all the other ports which have this flag. 37 | // In other words if all ports have this flag then the plugin may either be used entirely with 38 | // 64 bits audio or 32 bits audio, but it can't be mixed. 39 | CLAP_AUDIO_PORT_REQUIRES_COMMON_SAMPLE_SIZE = 1 << 3, 40 | }; 41 | 42 | typedef struct clap_audio_port_info { 43 | // id identifies a port and must be stable. 44 | // id may overlap between input and output ports. 45 | clap_id id; 46 | char name[CLAP_NAME_SIZE]; // displayable name 47 | 48 | uint32_t flags; 49 | uint32_t channel_count; 50 | 51 | // If null or empty then it is unspecified (arbitrary audio). 52 | // This field can be compared against: 53 | // - CLAP_PORT_MONO 54 | // - CLAP_PORT_STEREO 55 | // - CLAP_PORT_SURROUND (defined in the surround extension) 56 | // - CLAP_PORT_AMBISONIC (defined in the ambisonic extension) 57 | // 58 | // An extension can provide its own port type and way to inspect the channels. 59 | const char *port_type; 60 | 61 | // in-place processing: allow the host to use the same buffer for input and output 62 | // if supported set the pair port id. 63 | // if not supported set to CLAP_INVALID_ID 64 | clap_id in_place_pair; 65 | } clap_audio_port_info_t; 66 | 67 | // The audio ports scan has to be done while the plugin is deactivated. 68 | typedef struct clap_plugin_audio_ports { 69 | // Number of ports, for either input or output 70 | // [main-thread] 71 | uint32_t(CLAP_ABI *count)(const clap_plugin_t *plugin, bool is_input); 72 | 73 | // Get info about an audio port. 74 | // Returns true on success and stores the result into info. 75 | // [main-thread] 76 | bool(CLAP_ABI *get)(const clap_plugin_t *plugin, 77 | uint32_t index, 78 | bool is_input, 79 | clap_audio_port_info_t *info); 80 | } clap_plugin_audio_ports_t; 81 | 82 | enum { 83 | // The ports name did change, the host can scan them right away. 84 | CLAP_AUDIO_PORTS_RESCAN_NAMES = 1 << 0, 85 | 86 | // [!active] The flags did change 87 | CLAP_AUDIO_PORTS_RESCAN_FLAGS = 1 << 1, 88 | 89 | // [!active] The channel_count did change 90 | CLAP_AUDIO_PORTS_RESCAN_CHANNEL_COUNT = 1 << 2, 91 | 92 | // [!active] The port type did change 93 | CLAP_AUDIO_PORTS_RESCAN_PORT_TYPE = 1 << 3, 94 | 95 | // [!active] The in-place pair did change, this requires. 96 | CLAP_AUDIO_PORTS_RESCAN_IN_PLACE_PAIR = 1 << 4, 97 | 98 | // [!active] The list of ports have changed: entries have been removed/added. 99 | CLAP_AUDIO_PORTS_RESCAN_LIST = 1 << 5, 100 | }; 101 | 102 | typedef struct clap_host_audio_ports { 103 | // Checks if the host allows a plugin to change a given aspect of the audio ports definition. 104 | // [main-thread] 105 | bool(CLAP_ABI *is_rescan_flag_supported)(const clap_host_t *host, uint32_t flag); 106 | 107 | // Rescan the full list of audio ports according to the flags. 108 | // It is illegal to ask the host to rescan with a flag that is not supported. 109 | // Certain flags require the plugin to be de-activated. 110 | // [main-thread] 111 | void(CLAP_ABI *rescan)(const clap_host_t *host, uint32_t flags); 112 | } clap_host_audio_ports_t; 113 | 114 | #ifdef __cplusplus 115 | } 116 | #endif 117 | -------------------------------------------------------------------------------- /include/clap/ext/configurable-audio-ports.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "audio-ports.h" 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | // This extension lets the host configure the plugin's input and output audio ports. 10 | // This is a "push" approach to audio ports configuration. 11 | 12 | static CLAP_CONSTEXPR const char CLAP_EXT_CONFIGURABLE_AUDIO_PORTS[] = 13 | "clap.configurable-audio-ports/1"; 14 | 15 | // The latest draft is 100% compatible. 16 | // This compat ID may be removed in 2026. 17 | static CLAP_CONSTEXPR const char CLAP_EXT_CONFIGURABLE_AUDIO_PORTS_COMPAT[] = 18 | "clap.configurable-audio-ports.draft1"; 19 | 20 | typedef struct clap_audio_port_configuration_request { 21 | // Identifies the port by is_input and port_index 22 | bool is_input; 23 | uint32_t port_index; 24 | 25 | // The requested number of channels. 26 | uint32_t channel_count; 27 | 28 | // The port type, see audio-ports.h, clap_audio_port_info.port_type for interpretation. 29 | const char *port_type; 30 | 31 | // cast port_details according to port_type: 32 | // - CLAP_PORT_MONO: (discard) 33 | // - CLAP_PORT_STEREO: (discard) 34 | // - CLAP_PORT_SURROUND: const uint8_t *channel_map 35 | // - CLAP_PORT_AMBISONIC: const clap_ambisonic_config_t *info 36 | const void *port_details; 37 | } clap_audio_port_configuration_request_t; 38 | 39 | typedef struct clap_plugin_configurable_audio_ports { 40 | // Returns true if the given configurations can be applied using apply_configuration(). 41 | // [main-thread && !active] 42 | bool(CLAP_ABI *can_apply_configuration)( 43 | const clap_plugin_t *plugin, 44 | const struct clap_audio_port_configuration_request *requests, 45 | uint32_t request_count); 46 | 47 | // Submit a bunch of configuration requests which will atomically be applied together, 48 | // or discarded together. 49 | // 50 | // Once the configuration is successfully applied, it isn't necessary for the plugin to call 51 | // clap_host_audio_ports->changed(); and it isn't necessary for the host to scan the 52 | // audio ports. 53 | // 54 | // Returns true if applied. 55 | // [main-thread && !active] 56 | bool(CLAP_ABI *apply_configuration)(const clap_plugin_t *plugin, 57 | const struct clap_audio_port_configuration_request *requests, 58 | uint32_t request_count); 59 | } clap_plugin_configurable_audio_ports_t; 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif 64 | -------------------------------------------------------------------------------- /include/clap/ext/context-menu.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../plugin.h" 4 | 5 | // This extension lets the host and plugin exchange menu items and let the plugin ask the host to 6 | // show its context menu. 7 | 8 | static CLAP_CONSTEXPR const char CLAP_EXT_CONTEXT_MENU[] = "clap.context-menu/1"; 9 | 10 | // The latest draft is 100% compatible. 11 | // This compat ID may be removed in 2026. 12 | static CLAP_CONSTEXPR const char CLAP_EXT_CONTEXT_MENU_COMPAT[] = "clap.context-menu.draft/0"; 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | // There can be different target kind for a context menu 19 | enum { 20 | CLAP_CONTEXT_MENU_TARGET_KIND_GLOBAL = 0, 21 | CLAP_CONTEXT_MENU_TARGET_KIND_PARAM = 1, 22 | }; 23 | 24 | // Describes the context menu target 25 | typedef struct clap_context_menu_target { 26 | uint32_t kind; 27 | clap_id id; 28 | } clap_context_menu_target_t; 29 | 30 | enum { 31 | // Adds a clickable menu entry. 32 | // data: const clap_context_menu_item_entry_t* 33 | CLAP_CONTEXT_MENU_ITEM_ENTRY, 34 | 35 | // Adds a clickable menu entry which will feature both a checkmark and a label. 36 | // data: const clap_context_menu_item_check_entry_t* 37 | CLAP_CONTEXT_MENU_ITEM_CHECK_ENTRY, 38 | 39 | // Adds a separator line. 40 | // data: NULL 41 | CLAP_CONTEXT_MENU_ITEM_SEPARATOR, 42 | 43 | // Starts a sub menu with the given label. 44 | // data: const clap_context_menu_item_begin_submenu_t* 45 | CLAP_CONTEXT_MENU_ITEM_BEGIN_SUBMENU, 46 | 47 | // Ends the current sub menu. 48 | // data: NULL 49 | CLAP_CONTEXT_MENU_ITEM_END_SUBMENU, 50 | 51 | // Adds a title entry 52 | // data: const clap_context_menu_item_title_t * 53 | CLAP_CONTEXT_MENU_ITEM_TITLE, 54 | }; 55 | typedef uint32_t clap_context_menu_item_kind_t; 56 | 57 | typedef struct clap_context_menu_entry { 58 | // text to be displayed 59 | const char *label; 60 | 61 | // if false, then the menu entry is greyed out and not clickable 62 | bool is_enabled; 63 | clap_id action_id; 64 | } clap_context_menu_entry_t; 65 | 66 | typedef struct clap_context_menu_check_entry { 67 | // text to be displayed 68 | const char *label; 69 | 70 | // if false, then the menu entry is greyed out and not clickable 71 | bool is_enabled; 72 | 73 | // if true, then the menu entry will be displayed as checked 74 | bool is_checked; 75 | clap_id action_id; 76 | } clap_context_menu_check_entry_t; 77 | 78 | typedef struct clap_context_menu_item_title { 79 | // text to be displayed 80 | const char *title; 81 | 82 | // if false, then the menu entry is greyed out 83 | bool is_enabled; 84 | } clap_context_menu_item_title_t; 85 | 86 | typedef struct clap_context_menu_submenu { 87 | // text to be displayed 88 | const char *label; 89 | 90 | // if false, then the menu entry is greyed out and won't show submenu 91 | bool is_enabled; 92 | } clap_context_menu_submenu_t; 93 | 94 | // Context menu builder. 95 | // This object isn't thread-safe and must be used on the same thread as it was provided. 96 | typedef struct clap_context_menu_builder { 97 | void *ctx; 98 | 99 | // Adds an entry to the menu. 100 | // item_data type is determined by item_kind. 101 | // Returns true on success. 102 | bool(CLAP_ABI *add_item)(const struct clap_context_menu_builder *builder, 103 | clap_context_menu_item_kind_t item_kind, 104 | const void *item_data); 105 | 106 | // Returns true if the menu builder supports the given item kind 107 | bool(CLAP_ABI *supports)(const struct clap_context_menu_builder *builder, 108 | clap_context_menu_item_kind_t item_kind); 109 | } clap_context_menu_builder_t; 110 | 111 | typedef struct clap_plugin_context_menu { 112 | // Insert plugin's menu items into the menu builder. 113 | // If target is null, assume global context. 114 | // Returns true on success. 115 | // [main-thread] 116 | bool(CLAP_ABI *populate)(const clap_plugin_t *plugin, 117 | const clap_context_menu_target_t *target, 118 | const clap_context_menu_builder_t *builder); 119 | 120 | // Performs the given action, which was previously provided to the host via populate(). 121 | // If target is null, assume global context. 122 | // Returns true on success. 123 | // [main-thread] 124 | bool(CLAP_ABI *perform)(const clap_plugin_t *plugin, 125 | const clap_context_menu_target_t *target, 126 | clap_id action_id); 127 | } clap_plugin_context_menu_t; 128 | 129 | typedef struct clap_host_context_menu { 130 | // Insert host's menu items into the menu builder. 131 | // If target is null, assume global context. 132 | // Returns true on success. 133 | // [main-thread] 134 | bool(CLAP_ABI *populate)(const clap_host_t *host, 135 | const clap_context_menu_target_t *target, 136 | const clap_context_menu_builder_t *builder); 137 | 138 | // Performs the given action, which was previously provided to the plugin via populate(). 139 | // If target is null, assume global context. 140 | // Returns true on success. 141 | // [main-thread] 142 | bool(CLAP_ABI *perform)(const clap_host_t *host, 143 | const clap_context_menu_target_t *target, 144 | clap_id action_id); 145 | 146 | // Returns true if the host can display a popup menu for the plugin. 147 | // This may depend upon the current windowing system used to display the plugin, so the 148 | // return value is invalidated after creating the plugin window. 149 | // [main-thread] 150 | bool(CLAP_ABI *can_popup)(const clap_host_t *host); 151 | 152 | // Shows the host popup menu for a given parameter. 153 | // If the plugin is using embedded GUI, then x and y are relative to the plugin's window, 154 | // otherwise they're absolute coordinate, and screen index might be set accordingly. 155 | // If target is null, assume global context. 156 | // Returns true on success. 157 | // [main-thread] 158 | bool(CLAP_ABI *popup)(const clap_host_t *host, 159 | const clap_context_menu_target_t *target, 160 | int32_t screen_index, 161 | int32_t x, 162 | int32_t y); 163 | } clap_host_context_menu_t; 164 | 165 | #ifdef __cplusplus 166 | } 167 | #endif 168 | -------------------------------------------------------------------------------- /include/clap/ext/draft/extensible-audio-ports.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../audio-ports.h" 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | // This extension lets the host add and remove audio ports to the plugin. 10 | static CLAP_CONSTEXPR const char CLAP_EXT_EXTENSIBLE_AUDIO_PORTS[] = 11 | "clap.extensible-audio-ports/1"; 12 | 13 | typedef struct clap_plugin_extensible_audio_ports { 14 | // Asks the plugin to add a new port (at the end of the list), with the following settings. 15 | // port_type: see clap_audio_port_info.port_type for interpretation. 16 | // port_details: see clap_audio_port_configuration_request.port_details for interpretation. 17 | // Returns true on success. 18 | // [main-thread && !is_active] 19 | bool(CLAP_ABI *add_port)(const clap_plugin_t *plugin, 20 | bool is_input, 21 | uint32_t channel_count, 22 | const char *port_type, 23 | const void *port_details); 24 | 25 | // Asks the plugin to remove a port. 26 | // Returns true on success. 27 | // [main-thread && !is_active] 28 | bool(CLAP_ABI *remove_port)(const clap_plugin_t *plugin, bool is_input, uint32_t index); 29 | } clap_plugin_extensible_audio_ports_t; 30 | 31 | #ifdef __cplusplus 32 | } 33 | #endif 34 | -------------------------------------------------------------------------------- /include/clap/ext/draft/gain-adjustment-metering.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../plugin.h" 4 | 5 | // This extension lets the plugin report the current gain adjustment 6 | // (typically, gain reduction) to the host. 7 | 8 | static CLAP_CONSTEXPR const char CLAP_EXT_GAIN_ADJUSTMENT_METERING[] = "clap.gain-adjustment-metering/0"; 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | typedef struct clap_plugin_gain_adjustment_metering { 15 | // Returns the current gain adjustment in dB. The value is intended 16 | // for informational display, for example in a host meter or tooltip. 17 | // The returned value represents the gain adjustment that the plugin 18 | // applied to the last sample in the most recently processed block. 19 | // 20 | // The returned value is in dB. Zero means the plugin is applying no gain 21 | // reduction, or is not processing. A negative value means the plugin is 22 | // applying gain reduction, as with a compressor or limiter. A positive 23 | // value means the plugin is adding gain, as with an expander. The value 24 | // represents the dynamic gain reduction or expansion applied by the 25 | // plugin, before any make-up gain or other adjustment. A single value is 26 | // returned for all audio channels. 27 | // 28 | // [audio-thread] 29 | double(CLAP_ABI *get)(const clap_plugin_t *plugin); 30 | } clap_plugin_gain_adjustment_metering_t; 31 | 32 | #ifdef __cplusplus 33 | } 34 | #endif 35 | -------------------------------------------------------------------------------- /include/clap/ext/draft/mini-curve-display.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../plugin.h" 4 | 5 | // This extension allows a host to render a small curve provided by the plugin. 6 | // A useful application is to render an EQ frequency response in the DAW mixer view. 7 | 8 | static CLAP_CONSTEXPR const char CLAP_EXT_MINI_CURVE_DISPLAY[] = "clap.mini-curve-display/3"; 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | enum clap_mini_curve_display_curve_kind { 15 | // If the curve's kind doesn't fit in any proposed kind, use this one 16 | // and perhaps, make a pull request to extend the list. 17 | CLAP_MINI_CURVE_DISPLAY_CURVE_KIND_UNSPECIFIED = 0, 18 | 19 | // The mini curve is intended to draw the total gain response of the plugin. 20 | // In this case the y values are in dB and the x values are in Hz (logarithmic). 21 | // This would be useful in for example an equalizer. 22 | CLAP_MINI_CURVE_DISPLAY_CURVE_KIND_GAIN_RESPONSE = 1, 23 | 24 | // The mini curve is intended to draw the total phase response of the plugin. 25 | // In this case the y values are in radians and the x values are in Hz (logarithmic). 26 | // This would be useful in for example an equalizer. 27 | CLAP_MINI_CURVE_DISPLAY_CURVE_KIND_PHASE_RESPONSE = 2, 28 | 29 | // The mini curve is intended to draw the transfer curve of the plugin. 30 | // In this case the both x and y values are in dB. 31 | // This would be useful in for example a compressor or distortion plugin. 32 | CLAP_MINI_CURVE_DISPLAY_CURVE_KIND_TRANSFER_CURVE = 3, 33 | 34 | // This mini curve is intended to draw gain reduction over time. In this case 35 | // x refers to the window in seconds and y refers to level in dB, x_min is 36 | // always 0, and x_max would be the duration of the window. 37 | // This would be useful in for example a compressor or limiter. 38 | CLAP_MINI_CURVE_DISPLAY_CURVE_KIND_GAIN_REDUCTION = 4, 39 | 40 | // This curve is intended as a generic time series plot. In this case 41 | // x refers to the window in seconds. x_min is always 0, and x_max would be the duration of the 42 | // window. 43 | // Y is not specified and up to the plugin. 44 | CLAP_MINI_CURVE_DISPLAY_CURVE_KIND_TIME_SERIES = 5, 45 | 46 | // Note: more entries could be added here in the future 47 | }; 48 | 49 | typedef struct clap_mini_curve_display_curve_hints { 50 | 51 | // Range for the x axis. 52 | double x_min; 53 | double x_max; 54 | 55 | // Range for the y axis. 56 | double y_min; 57 | double y_max; 58 | 59 | } clap_mini_curve_display_curve_hints_t; 60 | 61 | // A set of points representing the curve to be painted. 62 | typedef struct clap_mini_curve_display_curve_data { 63 | // Indicates the kind of curve those values represent, the host can use this 64 | // information to paint the curve using a meaningful color. 65 | int32_t curve_kind; 66 | 67 | // values[0] will be the leftmost value and values[data_size -1] will be the rightmost 68 | // value. 69 | // 70 | // The value 0 and UINT16_MAX won't be painted. 71 | // The value 1 will be at the bottom of the curve and UINT16_MAX - 1 will be at the top. 72 | uint16_t *values; 73 | uint32_t values_count; 74 | } clap_mini_curve_display_curve_data_t; 75 | 76 | typedef struct clap_plugin_mini_curve_display { 77 | // Returns the number of curves the plugin wants to paint. 78 | // Be aware that the space to display those curves will be small, and too much data will make 79 | // the output hard to read. 80 | uint32_t(CLAP_ABI *get_curve_count)(const clap_plugin_t *plugin); 81 | 82 | // Renders the curve into each the curves buffer. 83 | // 84 | // curves is an array, and each entries (up to curves_size) contains pre-allocated 85 | // values buffer that must be filled by the plugin. 86 | // 87 | // The host will "stack" the curves, from the first one to the last one. 88 | // curves[0] is the first curve to be painted. 89 | // curves[n + 1] will be painted over curves[n]. 90 | // 91 | // Returns the number of curves rendered. 92 | // [main-thread] 93 | uint32_t(CLAP_ABI *render)(const clap_plugin_t *plugin, 94 | clap_mini_curve_display_curve_data_t *curves, 95 | uint32_t curves_size); 96 | 97 | // Tells the plugin if the curve is currently observed or not. 98 | // When it isn't observed render() can't be called. 99 | // 100 | // When is_obseverd becomes true, the curve content and axis name are implicitly invalidated. So 101 | // the plugin don't need to call host->changed. 102 | // 103 | // [main-thread] 104 | void(CLAP_ABI *set_observed)(const clap_plugin_t *plugin, bool is_observed); 105 | 106 | // Retrives the axis name. 107 | // x_name and y_name must not to be null. 108 | // Returns true on success, if the name capacity was sufficient. 109 | // [main-thread] 110 | bool(CLAP_ABI *get_axis_name)(const clap_plugin_t *plugin, 111 | uint32_t curve_index, 112 | char *x_name, 113 | char *y_name, 114 | uint32_t name_capacity); 115 | } clap_plugin_mini_curve_display_t; 116 | 117 | enum clap_mini_curve_display_change_flags { 118 | // Informs the host that the curve content changed. 119 | // Can only be called if the curve is observed and is static. 120 | CLAP_MINI_CURVE_DISPLAY_CURVE_CHANGED = 1 << 0, 121 | 122 | // Informs the host that the curve axis name changed. 123 | // Can only be called if the curve is observed. 124 | CLAP_MINI_CURVE_DISPLAY_AXIS_NAME_CHANGED = 1 << 1, 125 | }; 126 | 127 | typedef struct clap_host_mini_curve_display { 128 | // Fills in the given clap_mini_display_curve_hints_t structure and returns 129 | // true if successful. If not, return false. 130 | // [main-thread] 131 | bool(CLAP_ABI *get_hints)(const clap_host_t *host, 132 | uint32_t kind, 133 | clap_mini_curve_display_curve_hints_t *hints); 134 | 135 | // Mark the curve as being static or dynamic. 136 | // The curve is initially considered as static, though the plugin should explicitely 137 | // initialize this state. 138 | // 139 | // When static, the curve changes will be notified by calling host->changed(). 140 | // When dynamic, the curve is constantly changing and the host is expected to 141 | // periodically re-render. 142 | // 143 | // [main-thread] 144 | void(CLAP_ABI *set_dynamic)(const clap_host_t *host, bool is_dynamic); 145 | 146 | // See clap_mini_curve_display_change_flags 147 | // [main-thread] 148 | void(CLAP_ABI *changed)(const clap_host_t *host, uint32_t flags); 149 | } clap_host_mini_curve_display_t; 150 | 151 | #ifdef __cplusplus 152 | } 153 | #endif 154 | -------------------------------------------------------------------------------- /include/clap/ext/draft/project-location.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../color.h" 4 | #include "../../plugin.h" 5 | #include "../../string-sizes.h" 6 | 7 | // This extension allows a host to tell the plugin more about its position 8 | // within a project or session. 9 | 10 | static CLAP_CONSTEXPR const char CLAP_EXT_PROJECT_LOCATION[] = "clap.project-location/2"; 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | enum clap_project_location_kind { 17 | // Represents a document/project/session. 18 | CLAP_PROJECT_LOCATION_PROJECT = 1, 19 | 20 | // Represents a group of tracks. 21 | // It can contain track groups, tracks, and devices (post processing). 22 | // The first device within a track group has the index of 23 | // the last track or track group within this group + 1. 24 | CLAP_PROJECT_LOCATION_TRACK_GROUP = 2, 25 | 26 | // Represents a single track. 27 | // It contains devices (serial). 28 | CLAP_PROJECT_LOCATION_TRACK = 3, 29 | 30 | // Represents a single device. 31 | // It can contain other nested device chains. 32 | CLAP_PROJECT_LOCATION_DEVICE = 4, 33 | 34 | // Represents a nested device chain (serial). 35 | // Its parent must be a device. 36 | // It contains other devices. 37 | CLAP_PROJECT_LOCATION_NESTED_DEVICE_CHAIN = 5, 38 | }; 39 | 40 | enum clap_project_location_track_kind { 41 | // This track is an instrument track. 42 | CLAP_PROJECT_LOCATION_INSTUMENT_TRACK = 1, 43 | 44 | // This track is an audio track. 45 | CLAP_PROJECT_LOCATION_AUDIO_TRACK = 2, 46 | 47 | // This track is both an instrument and audio track. 48 | CLAP_PROJECT_LOCATION_HYBRID_TRACK = 3, 49 | 50 | // This track is a return track. 51 | CLAP_PROJECT_LOCATION_RETURN_TRACK = 4, 52 | 53 | // This track is a master track. 54 | // Each group have a master track for processing the sum of all its children tracks. 55 | CLAP_PROJECT_LOCATION_MASTER_TRACK = 5, 56 | }; 57 | 58 | enum clap_project_location_flags { 59 | CLAP_PROJECT_LOCATION_HAS_INDEX = 1 << 0, 60 | CLAP_PROJECT_LOCATION_HAS_COLOR = 1 << 1, 61 | }; 62 | 63 | typedef struct clap_project_location_element { 64 | // A bit-mask, see clap_project_location_flags. 65 | uint64_t flags; 66 | 67 | // Kind of the element, must be one of the CLAP_PROJECT_LOCATION_* values. 68 | uint32_t kind; 69 | 70 | // Only relevant if kind is CLAP_PLUGIN_LOCATION_TRACK. 71 | // see enum CLAP_PROJECT_LOCATION_track_kind. 72 | uint32_t track_kind; 73 | 74 | // Index within the parent element. 75 | // Only usable if CLAP_PROJECT_LOCATION_HAS_INDEX is set in flags. 76 | uint32_t index; 77 | 78 | // Internal ID of the element. 79 | // This is not intended for display to the user, 80 | // but rather to give the host a potential quick way for lookups. 81 | char id[CLAP_PATH_SIZE]; 82 | 83 | // User friendly name of the element. 84 | char name[CLAP_NAME_SIZE]; 85 | 86 | // Color for this element. 87 | // Only usable if CLAP_PROJECT_LOCATION_HAS_COLOR is set in flags. 88 | clap_color_t color; 89 | } clap_project_location_element_t; 90 | 91 | typedef struct clap_plugin_project_location { 92 | // Called by the host when the location of the plugin instance changes. 93 | // 94 | // The last item in this array always refers to the device itself, and as 95 | // such is expected to be of kind CLAP_PLUGIN_LOCATION_DEVICE. 96 | // The first item in this array always refers to the project this device is in and must be of 97 | // kind CLAP_PROJECT_LOCATION_PROJECT. The path is expected to be something like: PROJECT > 98 | // TRACK_GROUP+ > TRACK > (DEVICE > NESTED_DEVICE_CHAIN)* > DEVICE 99 | // 100 | // [main-thread] 101 | void(CLAP_ABI *set)(const clap_plugin_t *plugin, 102 | const clap_project_location_element_t *path, 103 | uint32_t num_elements); 104 | } clap_plugin_project_location_t; 105 | 106 | #ifdef __cplusplus 107 | } 108 | #endif 109 | -------------------------------------------------------------------------------- /include/clap/ext/draft/resource-directory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../plugin.h" 4 | 5 | static CLAP_CONSTEXPR const char CLAP_EXT_RESOURCE_DIRECTORY[] = "clap.resource-directory/1"; 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | /// @page Resource Directory 12 | /// 13 | /// This extension provides a way for the plugin to store its resources as file in a directory 14 | /// provided by the host and recover them later on. 15 | /// 16 | /// The plugin **must** store relative path in its state toward resource directories. 17 | /// 18 | /// Resource sharing: 19 | /// - shared directory is shared among all plugin instances, hence mostly appropriate for read-only 20 | /// content 21 | /// -> suitable for read-only content 22 | /// - exclusive directory is exclusive to the plugin instance 23 | /// -> if the plugin, then its exclusive directory must be duplicated too 24 | /// -> suitable for read-write content 25 | /// 26 | /// Keeping the shared directory clean: 27 | /// - to avoid clashes in the shared directory, plugins are encouraged to organize their files in 28 | /// sub-folders, for example create one subdirectory using the vendor name 29 | /// - don't use symbolic links or hard links which points outside of the directory 30 | /// 31 | /// Resource life-time: 32 | /// - exclusive folder content is managed by the plugin instance 33 | /// - exclusive folder content is deleted when the plugin instance is removed from the project 34 | /// - shared folder content isn't managed by the host, until all plugins using the shared directory 35 | /// are removed from the project 36 | /// 37 | /// Note for the host 38 | /// - try to use the filesystem's copy-on-write feature when possible for reducing exclusive folder 39 | /// space usage on duplication 40 | /// - host can "garbage collect" the files in the shared folder using: 41 | /// clap_plugin_resource_directory.get_files_count() 42 | /// clap_plugin_resource_directory.get_file_path() 43 | /// but be **very** careful before deleting any resources 44 | 45 | typedef struct clap_plugin_resource_directory { 46 | // Sets the directory in which the plugin can save its resources. 47 | // The directory remains valid until it is overridden or the plugin is destroyed. 48 | // If path is null or blank, it clears the directory location. 49 | // path must be absolute. 50 | // [main-thread] 51 | void(CLAP_ABI *set_directory)(const clap_plugin_t *plugin, const char *path, bool is_shared); 52 | 53 | // Asks the plugin to put its resources into the resource directory. 54 | // It is not necessary to collect files which belongs to the plugin's 55 | // factory content unless the param all is true. 56 | // [main-thread] 57 | void(CLAP_ABI *collect)(const clap_plugin_t *plugin, bool all); 58 | 59 | // Returns the number of files used by the plugin in the shared resource folder. 60 | // [main-thread] 61 | uint32_t(CLAP_ABI *get_files_count)(const clap_plugin_t *plugin); 62 | 63 | // Retrieves relative file path to the resource directory. 64 | // @param path writable memory to store the path 65 | // @param path_size number of available bytes in path 66 | // Returns the number of bytes in the path, or -1 on error 67 | // [main-thread] 68 | int32_t(CLAP_ABI *get_file_path)(const clap_plugin_t *plugin, 69 | uint32_t index, 70 | char *path, 71 | uint32_t path_size); 72 | } clap_plugin_resource_directory_t; 73 | 74 | typedef struct clap_host_resource_directory { 75 | // Request the host to setup a resource directory with the specified sharing. 76 | // Returns true if the host will perform the request. 77 | // [main-thread] 78 | bool(CLAP_ABI *request_directory)(const clap_host_t *host, bool is_shared); 79 | 80 | // Tell the host that the resource directory of the specified sharing is no longer required. 81 | // If is_shared = false, then the host may delete the directory content. 82 | // [main-thread] 83 | void(CLAP_ABI *release_directory)(const clap_host_t *host, bool is_shared); 84 | } clap_host_resource_directory_t; 85 | 86 | #ifdef __cplusplus 87 | } 88 | #endif 89 | -------------------------------------------------------------------------------- /include/clap/ext/draft/scratch-memory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../plugin.h" 4 | 5 | // This extension lets the plugin request "scratch" memory from the host. 6 | // 7 | // The scratch memory is thread-local, and can be accessed during 8 | // `clap_plugin->process()` and `clap_plugin_thread_pool->exec()`; 9 | // its content is not persistent between callbacks. 10 | // 11 | // The motivation for this extension is to allow the plugin host 12 | // to "share" a single scratch buffer across multiple plugin 13 | // instances. 14 | // 15 | // For example, imagine the host needs to process N plugins 16 | // in sequence, and each plugin requires 10K of scratch memory. 17 | // If each plugin pre-allocates its own scratch memory, then N * 10K 18 | // of memory is being allocated in total. However, if each plugin 19 | // requests 10K of scratch memory from the host, then the host can 20 | // allocate a single 10K scratch buffer, and make it available to all 21 | // plugins. 22 | // 23 | // This optimization may allow for reduced memory usage and improved 24 | // CPU cache usage. 25 | 26 | static CLAP_CONSTEXPR const char CLAP_EXT_SCRATCH_MEMORY[] = "clap.scratch-memory/1"; 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | typedef struct clap_host_scratch_memory { 33 | // Asks the host to reserve scratch memory. 34 | // 35 | // The plugin may call this method multiple times (for 36 | // example, gradually decreasing the amount of scratch 37 | // being asked for until the host returns true), however, 38 | // the plugin should avoid calling this method un-neccesarily 39 | // since the host implementation may be relatively expensive. 40 | // If the plugin calls `reserve()` multiple times, then the 41 | // last call invalidates all previous calls. 42 | // 43 | // De-activating the plugin releases the scratch memory. 44 | // 45 | // `max_concurrency_hint` is an optional hint which indicates 46 | // the maximum number of threads concurrently accessing the scratch memory. 47 | // Set to 0 if unspecified. 48 | // 49 | // Returns true on success. 50 | // 51 | // [main-thread & being-activated] 52 | bool(CLAP_ABI *reserve)(const clap_host_t *host, 53 | uint32_t scratch_size_bytes, 54 | uint32_t max_concurrency_hint); 55 | 56 | // Returns a pointer to the "thread-local" scratch memory. 57 | // 58 | // If the scratch memory wasn't successfully reserved, returns NULL. 59 | // 60 | // If the plugin crosses `max_concurrency_hint`, then the return value 61 | // is either NULL or a valid scratch memory pointer. 62 | // 63 | // This method may only be called by the plugin from the audio thread, 64 | // (i.e. during the process() or thread_pool.exec() callback), and 65 | // the provided memory is only valid until the plugin returns from 66 | // that callback. The plugin must not hold any references to data 67 | // that lives in the scratch memory after returning from the callback, 68 | // as that data will likely be over-written by another plugin using 69 | // the same scratch memory. 70 | // 71 | // The provided memory is not initialized, and may have been used 72 | // by other plugin instances, so the plugin must correctly initialize 73 | // the memory when using it. 74 | // 75 | // The provided memory is owned by the host, so the plugin must not 76 | // free the memory. 77 | // 78 | // If the plugin wants to share the same scratch memory pointer with 79 | // many threads, it must access the the scratch at the beginning of the 80 | // `process()` callback, cache the returned pointer before calling 81 | // `clap_host_thread_pool->request_exec()` and clear the cached pointer 82 | // before returning from `process()`. 83 | // 84 | // [audio-thread] 85 | void *(CLAP_ABI *access)(const clap_host_t *host); 86 | } clap_host_scratch_memory_t; 87 | 88 | #ifdef __cplusplus 89 | } 90 | #endif 91 | -------------------------------------------------------------------------------- /include/clap/ext/draft/transport-control.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../plugin.h" 4 | 5 | // This extension lets the plugin submit transport requests to the host. 6 | // The host has no obligation to execute these requests, so the interface may be 7 | // partially working. 8 | 9 | static CLAP_CONSTEXPR const char CLAP_EXT_TRANSPORT_CONTROL[] = "clap.transport-control/1"; 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | typedef struct clap_host_transport_control { 16 | // Jumps back to the start point and starts the transport 17 | // [main-thread] 18 | void(CLAP_ABI *request_start)(const clap_host_t *host); 19 | 20 | // Stops the transport, and jumps to the start point 21 | // [main-thread] 22 | void(CLAP_ABI *request_stop)(const clap_host_t *host); 23 | 24 | // If not playing, starts the transport from its current position 25 | // [main-thread] 26 | void(CLAP_ABI *request_continue)(const clap_host_t *host); 27 | 28 | // If playing, stops the transport at the current position 29 | // [main-thread] 30 | void(CLAP_ABI *request_pause)(const clap_host_t *host); 31 | 32 | // Equivalent to what "space bar" does with most DAWs 33 | // [main-thread] 34 | void(CLAP_ABI *request_toggle_play)(const clap_host_t *host); 35 | 36 | // Jumps the transport to the given position. 37 | // Does not start the transport. 38 | // [main-thread] 39 | void(CLAP_ABI *request_jump)(const clap_host_t *host, clap_beattime position); 40 | 41 | // Sets the loop region 42 | // [main-thread] 43 | void(CLAP_ABI *request_loop_region)(const clap_host_t *host, 44 | clap_beattime start, 45 | clap_beattime duration); 46 | 47 | // Toggles looping 48 | // [main-thread] 49 | void(CLAP_ABI *request_toggle_loop)(const clap_host_t *host); 50 | 51 | // Enables/Disables looping 52 | // [main-thread] 53 | void(CLAP_ABI *request_enable_loop)(const clap_host_t *host, bool is_enabled); 54 | 55 | // Enables/Disables recording 56 | // [main-thread] 57 | void(CLAP_ABI *request_record)(const clap_host_t *host, bool is_recording); 58 | 59 | // Toggles recording 60 | // [main-thread] 61 | void(CLAP_ABI *request_toggle_record)(const clap_host_t *host); 62 | } clap_host_transport_control_t; 63 | 64 | #ifdef __cplusplus 65 | } 66 | #endif 67 | -------------------------------------------------------------------------------- /include/clap/ext/draft/triggers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../plugin.h" 4 | #include "../../events.h" 5 | #include "../../string-sizes.h" 6 | 7 | static CLAP_CONSTEXPR const char CLAP_EXT_TRIGGERS[] = "clap.triggers/1"; 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | /// @page Trigger events 14 | /// 15 | /// This extension enables the plugin to expose a set of triggers to the host. 16 | /// 17 | /// Some examples for triggers: 18 | /// - trigger an envelope which is independent of the notes 19 | /// - trigger a sample-and-hold unit (maybe even per-voice) 20 | 21 | enum { 22 | // Does this trigger support per note automations? 23 | CLAP_TRIGGER_IS_AUTOMATABLE_PER_NOTE_ID = 1 << 0, 24 | 25 | // Does this trigger support per key automations? 26 | CLAP_TRIGGER_IS_AUTOMATABLE_PER_KEY = 1 << 1, 27 | 28 | // Does this trigger support per channel automations? 29 | CLAP_TRIGGER_IS_AUTOMATABLE_PER_CHANNEL = 1 << 2, 30 | 31 | // Does this trigger support per port automations? 32 | CLAP_TRIGGER_IS_AUTOMATABLE_PER_PORT = 1 << 3, 33 | }; 34 | typedef uint32_t clap_trigger_info_flags; 35 | 36 | // Given that this extension is still draft, it'll use the event-registry and its own event 37 | // namespace until we stabilize it. 38 | // 39 | // #include 40 | // 41 | // uint16_t CLAP_EXT_TRIGGER_EVENT_SPACE_ID = UINT16_MAX; 42 | // if (host_event_registry->query(host, CLAP_EXT_TRIGGERS, &CLAP_EXT_TRIGGER_EVENT_SPACE_ID)) { 43 | // /* we can use trigger events */ 44 | // } 45 | // 46 | // /* later on */ 47 | // clap_event_trigger ev; 48 | // ev.header.space_id = CLAP_EXT_TRIGGER_EVENT_SPACE_ID; 49 | // ev.header.type = CLAP_EVENT_TRIGGER; 50 | 51 | enum { CLAP_EVENT_TRIGGER = 0 }; 52 | 53 | typedef struct clap_event_trigger { 54 | clap_event_header_t header; 55 | 56 | // target trigger 57 | clap_id trigger_id; // @ref clap_trigger_info.id 58 | void *cookie; // @ref clap_trigger_info.cookie 59 | 60 | // target a specific note_id, port, key and channel, -1 for global 61 | int32_t note_id; 62 | int16_t port_index; 63 | int16_t channel; 64 | int16_t key; 65 | } clap_event_trigger_t; 66 | 67 | /* This describes a trigger */ 68 | typedef struct clap_trigger_info { 69 | // stable trigger identifier, it must never change. 70 | clap_id id; 71 | 72 | clap_trigger_info_flags flags; 73 | 74 | // in analogy to clap_param_info.cookie 75 | void *cookie; 76 | 77 | // displayable name 78 | char name[CLAP_NAME_SIZE]; 79 | 80 | // the module path containing the trigger, eg:"sequencers/seq1" 81 | // '/' will be used as a separator to show a tree like structure. 82 | char module[CLAP_PATH_SIZE]; 83 | } clap_trigger_info_t; 84 | 85 | typedef struct clap_plugin_triggers { 86 | // Returns the number of triggers. 87 | // [main-thread] 88 | uint32_t(CLAP_ABI *count)(const clap_plugin_t *plugin); 89 | 90 | // Copies the trigger's info to trigger_info and returns true on success. 91 | // [main-thread] 92 | bool(CLAP_ABI *get_info)(const clap_plugin_t *plugin, 93 | uint32_t index, 94 | clap_trigger_info_t *trigger_info); 95 | } clap_plugin_triggers_t; 96 | 97 | enum { 98 | // The trigger info did change, use this flag for: 99 | // - name change 100 | // - module change 101 | // New info takes effect immediately. 102 | CLAP_TRIGGER_RESCAN_INFO = 1 << 0, 103 | 104 | // Invalidates everything the host knows about triggers. 105 | // It can only be used while the plugin is deactivated. 106 | // If the plugin is activated use clap_host->restart() and delay any change until the host calls 107 | // clap_plugin->deactivate(). 108 | // 109 | // You must use this flag if: 110 | // - some triggers were added or removed. 111 | // - some triggers had critical changes: 112 | // - is_per_note (flag) 113 | // - is_per_key (flag) 114 | // - is_per_channel (flag) 115 | // - is_per_port (flag) 116 | // - cookie 117 | CLAP_TRIGGER_RESCAN_ALL = 1 << 1, 118 | }; 119 | typedef uint32_t clap_trigger_rescan_flags; 120 | 121 | enum { 122 | // Clears all possible references to a trigger 123 | CLAP_TRIGGER_CLEAR_ALL = 1 << 0, 124 | 125 | // Clears all automations to a trigger 126 | CLAP_TRIGGER_CLEAR_AUTOMATIONS = 1 << 1, 127 | }; 128 | typedef uint32_t clap_trigger_clear_flags; 129 | 130 | typedef struct clap_host_triggers { 131 | // Rescan the full list of triggers according to the flags. 132 | // [main-thread] 133 | void(CLAP_ABI *rescan)(const clap_host_t *host, clap_trigger_rescan_flags flags); 134 | 135 | // Clears references to a trigger. 136 | // [main-thread] 137 | void(CLAP_ABI *clear)(const clap_host_t *host, 138 | clap_id trigger_id, 139 | clap_trigger_clear_flags flags); 140 | } clap_host_triggers_t; 141 | 142 | #ifdef __cplusplus 143 | } 144 | #endif 145 | -------------------------------------------------------------------------------- /include/clap/ext/draft/tuning.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../plugin.h" 4 | #include "../../events.h" 5 | #include "../../string-sizes.h" 6 | 7 | static CLAP_CONSTEXPR const char CLAP_EXT_TUNING[] = "clap.tuning/2"; 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | // Use clap_host_event_registry->query(host, CLAP_EXT_TUNING, &space_id) to know the event space. 14 | // 15 | // This event defines the tuning to be used on the given port/channel. 16 | typedef struct clap_event_tuning { 17 | clap_event_header_t header; 18 | 19 | int16_t port_index; // -1 global 20 | int16_t channel; // 0..15, -1 global 21 | clap_id tunning_id; 22 | } clap_event_tuning_t; 23 | 24 | typedef struct clap_tuning_info { 25 | clap_id tuning_id; 26 | char name[CLAP_NAME_SIZE]; 27 | bool is_dynamic; // true if the values may vary with time 28 | } clap_tuning_info_t; 29 | 30 | typedef struct clap_plugin_tuning { 31 | // Called when a tuning is added or removed from the pool. 32 | // [main-thread] 33 | void(CLAP_ABI *changed)(const clap_plugin_t *plugin); 34 | } clap_plugin_tuning_t; 35 | 36 | // This extension provides a dynamic tuning table to the plugin. 37 | typedef struct clap_host_tuning { 38 | // Gets the relative tuning in semitones against equal temperament with A4=440Hz. 39 | // The plugin may query the tuning at a rate that makes sense for *low* frequency modulations. 40 | // 41 | // If the tuning_id is not found or equals to CLAP_INVALID_ID, 42 | // then the function shall gracefully return a sensible value. 43 | // 44 | // sample_offset is the sample offset from the beginning of the current process block. 45 | // 46 | // should_play(...) should be checked before calling this function. 47 | // 48 | // [audio-thread & in-process] 49 | double(CLAP_ABI *get_relative)(const clap_host_t *host, 50 | clap_id tuning_id, 51 | int32_t channel, 52 | int32_t key, 53 | uint32_t sample_offset); 54 | 55 | // Returns true if the note should be played. 56 | // [audio-thread & in-process] 57 | bool(CLAP_ABI *should_play)(const clap_host_t *host, 58 | clap_id tuning_id, 59 | int32_t channel, 60 | int32_t key); 61 | 62 | // Returns the number of tunings in the pool. 63 | // [main-thread] 64 | uint32_t(CLAP_ABI *get_tuning_count)(const clap_host_t *host); 65 | 66 | // Gets info about a tuning 67 | // Returns true on success and stores the result into info. 68 | // [main-thread] 69 | bool(CLAP_ABI *get_info)(const clap_host_t *host, 70 | uint32_t tuning_index, 71 | clap_tuning_info_t *info); 72 | } clap_host_tuning_t; 73 | 74 | #ifdef __cplusplus 75 | } 76 | #endif 77 | -------------------------------------------------------------------------------- /include/clap/ext/draft/undo.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../plugin.h" 4 | #include "../../stream.h" 5 | 6 | static CLAP_CONSTEXPR const char CLAP_EXT_UNDO[] = "clap.undo/4"; 7 | static CLAP_CONSTEXPR const char CLAP_EXT_UNDO_CONTEXT[] = "clap.undo_context/4"; 8 | static CLAP_CONSTEXPR const char CLAP_EXT_UNDO_DELTA[] = "clap.undo_delta/4"; 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /// @page Undo 15 | /// 16 | /// This extension enables the plugin to merge its undo history with the host. 17 | /// This leads to a single undo history shared by the host and many plugins. 18 | /// 19 | /// Calling host->undo() or host->redo() is equivalent to clicking undo/redo within the host's GUI. 20 | /// 21 | /// If the plugin uses this interface then its undo and redo should be entirely delegated to 22 | /// the host; clicking in the plugin's UI undo or redo is equivalent to clicking undo or redo in the 23 | /// host's UI. 24 | /// 25 | /// Some changes are long running changes, for example a mouse interaction will begin editing some 26 | /// complex data and it may take multiple events and a long duration to complete the change. 27 | /// In such case the plugin will call host->begin_change() to indicate the beginning of a long 28 | /// running change and complete the change by calling host->change_made(). 29 | /// 30 | /// The host may group changes together: 31 | /// [---------------------------------] 32 | /// ^-T0 ^-T1 ^-T2 ^-T3 33 | /// Here a long running change C0 begin at T0. 34 | /// A instantaneous change C1 at T1, and another one C2 at T2. 35 | /// Then at T3 the long running change is completed. 36 | /// The host will then create a single undo step that will merge all the changes into C0. 37 | /// 38 | /// This leads to another important consideration: starting a long running change without 39 | /// terminating is **VERY BAD**, because while a change is running it is impossible to call undo or 40 | /// redo. 41 | /// 42 | /// Rationale: multiple designs were considered and this one has the benefit of having a single undo 43 | /// history. This simplifies the host implementation, leading to less bugs, a more robust design 44 | /// and maybe an easier experience for the user because there's a single undo context versus one 45 | /// for the host and one for each plugin instance. 46 | /// 47 | /// This extension tries to make it as easy as possible for the plugin to hook into the host undo 48 | /// and make it efficient when possible by using deltas. The plugin interfaces are all optional, and 49 | /// the plugin can for a minimal implementation, just use the host interface and call 50 | /// host->change_made() without providing a delta. This is enough for the host to know that it can 51 | /// capture a plugin state for the undo step. 52 | 53 | typedef struct clap_undo_delta_properties { 54 | // If true, then the plugin will provide deltas in host->change_made(). 55 | // If false, then all clap_undo_delta_properties's attributes become irrelevant. 56 | bool has_delta; 57 | 58 | // If true, then the deltas can be stored on disk and re-used in the future as long as the plugin 59 | // is compatible with the given format_version. 60 | // 61 | // If false, then format_version must be set to CLAP_INVALID_ID. 62 | bool are_deltas_persistent; 63 | 64 | // This represents the delta format version that the plugin is currently using. 65 | // Use CLAP_INVALID_ID for invalid value. 66 | clap_id format_version; 67 | } clap_undo_delta_properties_t; 68 | 69 | // Use CLAP_EXT_UNDO_DELTA. 70 | // This is an optional interface, using deltas is an optimization versus making a state snapshot. 71 | typedef struct clap_plugin_undo_delta { 72 | // Asks the plugin the delta properties. 73 | // [main-thread] 74 | void(CLAP_ABI *get_delta_properties)(const clap_plugin_t *plugin, 75 | clap_undo_delta_properties_t *properties); 76 | 77 | // Asks the plugin if it can apply a delta using the given format version. 78 | // Returns true if it is possible. 79 | // [main-thread] 80 | bool(CLAP_ABI *can_use_delta_format_version)(const clap_plugin_t *plugin, 81 | clap_id format_version); 82 | 83 | // Undo using the delta. 84 | // Returns true on success. 85 | // 86 | // [main-thread] 87 | bool(CLAP_ABI *undo)(const clap_plugin_t *plugin, 88 | clap_id format_version, 89 | const void *delta, 90 | size_t delta_size); 91 | 92 | // Redo using the delta. 93 | // Returns true on success. 94 | // 95 | // [main-thread] 96 | bool(CLAP_ABI *redo)(const clap_plugin_t *plugin, 97 | clap_id format_version, 98 | const void *delta, 99 | size_t delta_size); 100 | } clap_plugin_undo_delta_t; 101 | 102 | // Use CLAP_EXT_UNDO_CONTEXT. 103 | // This is an optional interface, that the plugin can implement in order to know about 104 | // the current undo context. 105 | typedef struct clap_plugin_undo_context { 106 | // Indicate if it is currently possible to perform an undo or redo operation. 107 | // [main-thread & plugin-subscribed-to-undo-context] 108 | void(CLAP_ABI *set_can_undo)(const clap_plugin_t *plugin, bool can_undo); 109 | void(CLAP_ABI *set_can_redo)(const clap_plugin_t *plugin, bool can_redo); 110 | 111 | // Sets the name of the next undo or redo step. 112 | // name: null terminated string. 113 | // [main-thread & plugin-subscribed-to-undo-context] 114 | void(CLAP_ABI *set_undo_name)(const clap_plugin_t *plugin, const char *name); 115 | void(CLAP_ABI *set_redo_name)(const clap_plugin_t *plugin, const char *name); 116 | } clap_plugin_undo_context_t; 117 | 118 | // Use CLAP_EXT_UNDO. 119 | typedef struct clap_host_undo { 120 | // Begins a long running change. 121 | // The plugin must not call this twice: there must be either a call to cancel_change() or 122 | // change_made() before calling begin_change() again. 123 | // [main-thread] 124 | void(CLAP_ABI *begin_change)(const clap_host_t *host); 125 | 126 | // Cancels a long running change. 127 | // cancel_change() must not be called without a preceding begin_change(). 128 | // [main-thread] 129 | void(CLAP_ABI *cancel_change)(const clap_host_t *host); 130 | 131 | // Completes an undoable change. 132 | // At the moment of this function call, plugin_state->save() would include the current change. 133 | // 134 | // name: mandatory null terminated string describing the change, this is displayed to the user 135 | // 136 | // delta: optional, it is a binary blobs used to perform the undo and redo. When not available 137 | // the host will save the plugin state and use state->load() to perform undo and redo. 138 | // The plugin must be able to perform a redo operation using the delta, though the undo operation 139 | // is only possible if delta_can_undo is true. 140 | // 141 | // Note: the provided delta may be used for incremental state saving and crash recovery. The 142 | // plugin can indicate a format version id and the validity lifetime for the binary blobs. 143 | // The host can use these to verify the compatibility before applying the delta. 144 | // If the plugin is unable to use a delta, a notification should be provided to the user and 145 | // the crash recovery should perform a best effort job, at least restoring the latest saved 146 | // state. 147 | // 148 | // Special case: for objects with shared and synchronized state, changes shouldn't be reported 149 | // as the host already knows about it. 150 | // For example, plugin parameter changes shouldn't produce a call to change_made(). 151 | // 152 | // Note: if the plugin asked for this interface, then host_state->mark_dirty() will not create an 153 | // implicit undo step. 154 | // 155 | // Note: if the plugin did load a preset or did something that leads to a large delta, 156 | // it may consider not producing a delta (pass null) and let the host make a state snapshot 157 | // instead. 158 | // 159 | // Note: if a plugin is producing a lot of changes within a small amount of time, the host 160 | // may merge them into a single undo step. 161 | // 162 | // [main-thread] 163 | void(CLAP_ABI *change_made)(const clap_host_t *host, 164 | const char *name, 165 | const void *delta, 166 | size_t delta_size, 167 | bool delta_can_undo); 168 | 169 | // Asks the host to perform the next undo or redo step. 170 | // 171 | // Note: this maybe a complex and asynchronous operation, which may complete after 172 | // this function returns. 173 | // 174 | // Note: the host may ignore this request if there is no undo/redo step to perform, 175 | // or if the host is unable to perform undo/redo at the time (eg: a long running 176 | // change is going on). 177 | // 178 | // [main-thread] 179 | void(CLAP_ABI *request_undo)(const clap_host_t *host); 180 | void(CLAP_ABI *request_redo)(const clap_host_t *host); 181 | 182 | // Subscribes to or unsubscribes from undo context info. 183 | // 184 | // This method helps reducing the number of calls the host has to perform when updating 185 | // the undo context info. Consider a large project with 1000+ plugins, we don't want to 186 | // call 1000+ times update, while the plugin may only need the context info if its GUI 187 | // is shown and it wants to display undo/redo info. 188 | // 189 | // Initial state is unsubscribed. 190 | // 191 | // is_subscribed: set to true to receive context info 192 | // 193 | // It is mandatory for the plugin to implement CLAP_EXT_UNDO_CONTEXT when using this method. 194 | // 195 | // [main-thread] 196 | void(CLAP_ABI *set_wants_context_updates)(const clap_host_t *host, bool is_subscribed); 197 | } clap_host_undo_t; 198 | 199 | #ifdef __cplusplus 200 | } 201 | #endif 202 | -------------------------------------------------------------------------------- /include/clap/ext/event-registry.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../plugin.h" 4 | 5 | static CLAP_CONSTEXPR const char CLAP_EXT_EVENT_REGISTRY[] = "clap.event-registry"; 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | typedef struct clap_host_event_registry { 12 | // Queries an event space id. 13 | // The space id 0 is reserved for CLAP's core events. See CLAP_CORE_EVENT_SPACE. 14 | // 15 | // Return false and sets *space_id to UINT16_MAX if the space name is unknown to the host. 16 | // [main-thread] 17 | bool(CLAP_ABI *query)(const clap_host_t *host, const char *space_name, uint16_t *space_id); 18 | } clap_host_event_registry_t; 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif 23 | -------------------------------------------------------------------------------- /include/clap/ext/gui.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../plugin.h" 4 | 5 | /// @page GUI 6 | /// 7 | /// This extension defines how the plugin will present its GUI. 8 | /// 9 | /// There are two approaches: 10 | /// 1. the plugin creates a window and embeds it into the host's window 11 | /// 2. the plugin creates a floating window 12 | /// 13 | /// Embedding the window gives more control to the host, and feels more integrated. 14 | /// Floating window are sometimes the only option due to technical limitations. 15 | /// 16 | /// The Embedding protocol is by far the most common, supported by all hosts to date, 17 | /// and a plugin author should support at least that case. 18 | /// 19 | /// Showing the GUI works as follow: 20 | /// 1. clap_plugin_gui->is_api_supported(), check what can work 21 | /// 2. clap_plugin_gui->create(), allocates gui resources 22 | /// 3. if the plugin window is floating 23 | /// 4. -> clap_plugin_gui->set_transient() 24 | /// 5. -> clap_plugin_gui->suggest_title() 25 | /// 6. else 26 | /// 7. -> clap_plugin_gui->set_scale() 27 | /// 8. -> clap_plugin_gui->can_resize() 28 | /// 9. -> if resizable and has known size from previous session, clap_plugin_gui->set_size() 29 | /// 10. -> else clap_plugin_gui->get_size(), gets initial size 30 | /// 11. -> clap_plugin_gui->set_parent() 31 | /// 12. clap_plugin_gui->show() 32 | /// 13. clap_plugin_gui->hide()/show() ... 33 | /// 14. clap_plugin_gui->destroy() when done with the gui 34 | /// 35 | /// Resizing the window (initiated by the plugin, if embedded): 36 | /// 1. Plugins calls clap_host_gui->request_resize() 37 | /// 2. If the host returns true the new size is accepted, 38 | /// the host doesn't have to call clap_plugin_gui->set_size(). 39 | /// If the host returns false, the new size is rejected. 40 | /// 41 | /// Resizing the window (drag, if embedded)): 42 | /// 1. Only possible if clap_plugin_gui->can_resize() returns true 43 | /// 2. Mouse drag -> new_size 44 | /// 3. clap_plugin_gui->adjust_size(new_size) -> working_size 45 | /// 4. clap_plugin_gui->set_size(working_size) 46 | 47 | static CLAP_CONSTEXPR const char CLAP_EXT_GUI[] = "clap.gui"; 48 | 49 | // If your windowing API is not listed here, please open an issue and we'll figure it out. 50 | // https://github.com/free-audio/clap/issues/new 51 | 52 | // uses physical size 53 | // embed using https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setparent 54 | static const CLAP_CONSTEXPR char CLAP_WINDOW_API_WIN32[] = "win32"; 55 | 56 | // uses logical size, don't call clap_plugin_gui->set_scale() 57 | static const CLAP_CONSTEXPR char CLAP_WINDOW_API_COCOA[] = "cocoa"; 58 | 59 | // uses physical size 60 | // embed using https://specifications.freedesktop.org/xembed-spec/xembed-spec-latest.html 61 | static const CLAP_CONSTEXPR char CLAP_WINDOW_API_X11[] = "x11"; 62 | 63 | // uses physical size 64 | // embed is currently not supported, use floating windows 65 | static const CLAP_CONSTEXPR char CLAP_WINDOW_API_WAYLAND[] = "wayland"; 66 | 67 | #ifdef __cplusplus 68 | extern "C" { 69 | #endif 70 | 71 | typedef void *clap_hwnd; 72 | typedef void *clap_nsview; 73 | typedef unsigned long clap_xwnd; 74 | 75 | // Represent a window reference. 76 | typedef struct clap_window { 77 | const char *api; // one of CLAP_WINDOW_API_XXX 78 | union { 79 | clap_nsview cocoa; 80 | clap_xwnd x11; 81 | clap_hwnd win32; 82 | void *ptr; // for anything defined outside of clap 83 | }; 84 | } clap_window_t; 85 | 86 | // Information to improve window resizing when initiated by the host or window manager. 87 | typedef struct clap_gui_resize_hints { 88 | bool can_resize_horizontally; 89 | bool can_resize_vertically; 90 | 91 | // if both horizontal and vertical resize are available, do we preserve the 92 | // aspect ratio, and if so, what is the width x height aspect ratio to preserve. 93 | // These flags are unused if can_resize_horizontally or vertically are false, 94 | // and ratios are unused if preserve is false. 95 | bool preserve_aspect_ratio; 96 | uint32_t aspect_ratio_width; 97 | uint32_t aspect_ratio_height; 98 | } clap_gui_resize_hints_t; 99 | 100 | // Size (width, height) is in pixels; the corresponding windowing system extension is 101 | // responsible for defining if it is physical pixels or logical pixels. 102 | typedef struct clap_plugin_gui { 103 | // Returns true if the requested gui api is supported, either in floating (plugin-created) 104 | // or non-floating (embedded) mode. 105 | // [main-thread] 106 | bool(CLAP_ABI *is_api_supported)(const clap_plugin_t *plugin, const char *api, bool is_floating); 107 | 108 | // Returns true if the plugin has a preferred api. 109 | // The host has no obligation to honor the plugin preference, this is just a hint. 110 | // The const char **api variable should be explicitly assigned as a pointer to 111 | // one of the CLAP_WINDOW_API_ constants defined above, not strcopied. 112 | // [main-thread] 113 | bool(CLAP_ABI *get_preferred_api)(const clap_plugin_t *plugin, 114 | const char **api, 115 | bool *is_floating); 116 | 117 | // Create and allocate all resources necessary for the gui. 118 | // 119 | // If is_floating is true, then the window will not be managed by the host. The plugin 120 | // can set its window to stays above the parent window, see set_transient(). 121 | // api may be null or blank for floating window. 122 | // 123 | // If is_floating is false, then the plugin has to embed its window into the parent window, see 124 | // set_parent(). 125 | // 126 | // After this call, the GUI may not be visible yet; don't forget to call show(). 127 | // 128 | // Returns true if the GUI is successfully created. 129 | // [main-thread] 130 | bool(CLAP_ABI *create)(const clap_plugin_t *plugin, const char *api, bool is_floating); 131 | 132 | // Free all resources associated with the gui. 133 | // [main-thread] 134 | void(CLAP_ABI *destroy)(const clap_plugin_t *plugin); 135 | 136 | // Set the absolute GUI scaling factor, and override any OS info. 137 | // Should not be used if the windowing api relies upon logical pixels. 138 | // 139 | // If the plugin prefers to work out the scaling factor itself by querying the OS directly, 140 | // then ignore the call. 141 | // 142 | // scale = 2 means 200% scaling. 143 | // 144 | // Returns true if the scaling could be applied 145 | // Returns false if the call was ignored, or the scaling could not be applied. 146 | // [main-thread] 147 | bool(CLAP_ABI *set_scale)(const clap_plugin_t *plugin, double scale); 148 | 149 | // Get the current size of the plugin UI. 150 | // clap_plugin_gui->create() must have been called prior to asking the size. 151 | // 152 | // Returns true if the plugin could get the size. 153 | // [main-thread] 154 | bool(CLAP_ABI *get_size)(const clap_plugin_t *plugin, uint32_t *width, uint32_t *height); 155 | 156 | // Returns true if the window is resizeable (mouse drag). 157 | // [main-thread & !floating] 158 | bool(CLAP_ABI *can_resize)(const clap_plugin_t *plugin); 159 | 160 | // Returns true if the plugin can provide hints on how to resize the window. 161 | // [main-thread & !floating] 162 | bool(CLAP_ABI *get_resize_hints)(const clap_plugin_t *plugin, clap_gui_resize_hints_t *hints); 163 | 164 | // If the plugin gui is resizable, then the plugin will calculate the closest 165 | // usable size which fits in the given size. 166 | // This method does not change the size. 167 | // 168 | // Returns true if the plugin could adjust the given size. 169 | // [main-thread & !floating] 170 | bool(CLAP_ABI *adjust_size)(const clap_plugin_t *plugin, uint32_t *width, uint32_t *height); 171 | 172 | // Sets the window size. 173 | // 174 | // Returns true if the plugin could resize its window to the given size. 175 | // [main-thread & !floating] 176 | bool(CLAP_ABI *set_size)(const clap_plugin_t *plugin, uint32_t width, uint32_t height); 177 | 178 | // Embeds the plugin window into the given window. 179 | // 180 | // Returns true on success. 181 | // [main-thread & !floating] 182 | bool(CLAP_ABI *set_parent)(const clap_plugin_t *plugin, const clap_window_t *window); 183 | 184 | // Set the plugin floating window to stay above the given window. 185 | // 186 | // Returns true on success. 187 | // [main-thread & floating] 188 | bool(CLAP_ABI *set_transient)(const clap_plugin_t *plugin, const clap_window_t *window); 189 | 190 | // Suggests a window title. Only for floating windows. 191 | // 192 | // [main-thread & floating] 193 | void(CLAP_ABI *suggest_title)(const clap_plugin_t *plugin, const char *title); 194 | 195 | // Show the window. 196 | // 197 | // Returns true on success. 198 | // [main-thread] 199 | bool(CLAP_ABI *show)(const clap_plugin_t *plugin); 200 | 201 | // Hide the window, this method does not free the resources, it just hides 202 | // the window content. Yet it may be a good idea to stop painting timers. 203 | // 204 | // Returns true on success. 205 | // [main-thread] 206 | bool(CLAP_ABI *hide)(const clap_plugin_t *plugin); 207 | } clap_plugin_gui_t; 208 | 209 | typedef struct clap_host_gui { 210 | // The host should call get_resize_hints() again. 211 | // [thread-safe & !floating] 212 | void(CLAP_ABI *resize_hints_changed)(const clap_host_t *host); 213 | 214 | // Request the host to resize the client area to width, height. 215 | // Return true if the new size is accepted, false otherwise. 216 | // The host doesn't have to call set_size(). 217 | // 218 | // Note: if not called from the main thread, then a return value simply means that the host 219 | // acknowledged the request and will process it asynchronously. If the request then can't be 220 | // satisfied then the host will call set_size() to revert the operation. 221 | // [thread-safe & !floating] 222 | bool(CLAP_ABI *request_resize)(const clap_host_t *host, uint32_t width, uint32_t height); 223 | 224 | // Request the host to show the plugin gui. 225 | // Return true on success, false otherwise. 226 | // [thread-safe] 227 | bool(CLAP_ABI *request_show)(const clap_host_t *host); 228 | 229 | // Request the host to hide the plugin gui. 230 | // Return true on success, false otherwise. 231 | // [thread-safe] 232 | bool(CLAP_ABI *request_hide)(const clap_host_t *host); 233 | 234 | // The floating window has been closed, or the connection to the gui has been lost. 235 | // 236 | // If was_destroyed is true, then the host must call clap_plugin_gui->destroy() to acknowledge 237 | // the gui destruction. 238 | // [thread-safe] 239 | void(CLAP_ABI *closed)(const clap_host_t *host, bool was_destroyed); 240 | } clap_host_gui_t; 241 | 242 | #ifdef __cplusplus 243 | } 244 | #endif 245 | -------------------------------------------------------------------------------- /include/clap/ext/latency.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../plugin.h" 4 | 5 | static CLAP_CONSTEXPR const char CLAP_EXT_LATENCY[] = "clap.latency"; 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | typedef struct clap_plugin_latency { 12 | // Returns the plugin latency in samples. 13 | // [main-thread & (being-activated | active)] 14 | uint32_t(CLAP_ABI *get)(const clap_plugin_t *plugin); 15 | } clap_plugin_latency_t; 16 | 17 | typedef struct clap_host_latency { 18 | // Tell the host that the latency changed. 19 | // The latency is only allowed to change during plugin->activate. 20 | // If the plugin is activated, call host->request_restart() 21 | // [main-thread & being-activated] 22 | void(CLAP_ABI *changed)(const clap_host_t *host); 23 | } clap_host_latency_t; 24 | 25 | #ifdef __cplusplus 26 | } 27 | #endif 28 | -------------------------------------------------------------------------------- /include/clap/ext/log.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../plugin.h" 4 | 5 | static CLAP_CONSTEXPR const char CLAP_EXT_LOG[] = "clap.log"; 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | enum { 12 | CLAP_LOG_DEBUG = 0, 13 | CLAP_LOG_INFO = 1, 14 | CLAP_LOG_WARNING = 2, 15 | CLAP_LOG_ERROR = 3, 16 | CLAP_LOG_FATAL = 4, 17 | 18 | // These severities should be used to report misbehaviour. 19 | // The plugin one can be used by a layer between the plugin and the host. 20 | CLAP_LOG_HOST_MISBEHAVING = 5, 21 | CLAP_LOG_PLUGIN_MISBEHAVING = 6, 22 | }; 23 | typedef int32_t clap_log_severity; 24 | 25 | typedef struct clap_host_log { 26 | // Log a message through the host. 27 | // [thread-safe] 28 | void(CLAP_ABI *log)(const clap_host_t *host, clap_log_severity severity, const char *msg); 29 | } clap_host_log_t; 30 | 31 | #ifdef __cplusplus 32 | } 33 | #endif 34 | -------------------------------------------------------------------------------- /include/clap/ext/note-name.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../plugin.h" 4 | #include "../string-sizes.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | static CLAP_CONSTEXPR const char CLAP_EXT_NOTE_NAME[] = "clap.note-name"; 11 | 12 | typedef struct clap_note_name { 13 | char name[CLAP_NAME_SIZE]; 14 | int16_t port; // -1 for every port 15 | int16_t key; // -1 for every key 16 | int16_t channel; // -1 for every channel 17 | } clap_note_name_t; 18 | 19 | typedef struct clap_plugin_note_name { 20 | // Return the number of note names 21 | // [main-thread] 22 | uint32_t(CLAP_ABI *count)(const clap_plugin_t *plugin); 23 | 24 | // Returns true on success and stores the result into note_name 25 | // [main-thread] 26 | bool(CLAP_ABI *get)(const clap_plugin_t *plugin, uint32_t index, clap_note_name_t *note_name); 27 | } clap_plugin_note_name_t; 28 | 29 | typedef struct clap_host_note_name { 30 | // Informs the host that the note names have changed. 31 | // [main-thread] 32 | void(CLAP_ABI *changed)(const clap_host_t *host); 33 | } clap_host_note_name_t; 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif 38 | -------------------------------------------------------------------------------- /include/clap/ext/note-ports.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../plugin.h" 4 | #include "../string-sizes.h" 5 | 6 | /// @page Note Ports 7 | /// 8 | /// This extension provides a way for the plugin to describe its current note ports. 9 | /// If the plugin does not implement this extension, it won't have note input or output. 10 | /// The plugin is only allowed to change its note ports configuration while it is deactivated. 11 | 12 | static CLAP_CONSTEXPR const char CLAP_EXT_NOTE_PORTS[] = "clap.note-ports"; 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | enum clap_note_dialect { 19 | // Uses clap_event_note and clap_event_note_expression. 20 | CLAP_NOTE_DIALECT_CLAP = 1 << 0, 21 | 22 | // Uses clap_event_midi, no polyphonic expression 23 | CLAP_NOTE_DIALECT_MIDI = 1 << 1, 24 | 25 | // Uses clap_event_midi, with polyphonic expression (MPE) 26 | CLAP_NOTE_DIALECT_MIDI_MPE = 1 << 2, 27 | 28 | // Uses clap_event_midi2 29 | CLAP_NOTE_DIALECT_MIDI2 = 1 << 3, 30 | }; 31 | 32 | typedef struct clap_note_port_info { 33 | // id identifies a port and must be stable. 34 | // id may overlap between input and output ports. 35 | clap_id id; 36 | uint32_t supported_dialects; // bitfield, see clap_note_dialect 37 | uint32_t preferred_dialect; // one value of clap_note_dialect 38 | char name[CLAP_NAME_SIZE]; // displayable name, i18n? 39 | } clap_note_port_info_t; 40 | 41 | // The note ports scan has to be done while the plugin is deactivated. 42 | typedef struct clap_plugin_note_ports { 43 | // Number of ports, for either input or output. 44 | // [main-thread] 45 | uint32_t(CLAP_ABI *count)(const clap_plugin_t *plugin, bool is_input); 46 | 47 | // Get info about a note port. 48 | // Returns true on success and stores the result into info. 49 | // [main-thread] 50 | bool(CLAP_ABI *get)(const clap_plugin_t *plugin, 51 | uint32_t index, 52 | bool is_input, 53 | clap_note_port_info_t *info); 54 | } clap_plugin_note_ports_t; 55 | 56 | enum { 57 | // The ports have changed, the host shall perform a full scan of the ports. 58 | // This flag can only be used if the plugin is not active. 59 | // If the plugin active, call host->request_restart() and then call rescan() 60 | // when the host calls deactivate() 61 | CLAP_NOTE_PORTS_RESCAN_ALL = 1 << 0, 62 | 63 | // The ports name did change, the host can scan them right away. 64 | CLAP_NOTE_PORTS_RESCAN_NAMES = 1 << 1, 65 | }; 66 | 67 | typedef struct clap_host_note_ports { 68 | // Query which dialects the host supports 69 | // [main-thread] 70 | uint32_t(CLAP_ABI *supported_dialects)(const clap_host_t *host); 71 | 72 | // Rescan the full list of note ports according to the flags. 73 | // [main-thread] 74 | void(CLAP_ABI *rescan)(const clap_host_t *host, uint32_t flags); 75 | } clap_host_note_ports_t; 76 | 77 | #ifdef __cplusplus 78 | } 79 | #endif 80 | -------------------------------------------------------------------------------- /include/clap/ext/param-indication.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "params.h" 4 | #include "../color.h" 5 | 6 | // This extension lets the host tell the plugin to display a little color based indication on the 7 | // parameter. This can be used to indicate: 8 | // - a physical controller is mapped to a parameter 9 | // - the parameter is current playing an automation 10 | // - the parameter is overriding the automation 11 | // - etc... 12 | // 13 | // The color semantic depends upon the host here and the goal is to have a consistent experience 14 | // across all plugins. 15 | 16 | static CLAP_CONSTEXPR const char CLAP_EXT_PARAM_INDICATION[] = "clap.param-indication/4"; 17 | 18 | // The latest draft is 100% compatible. 19 | // This compat ID may be removed in 2026. 20 | static CLAP_CONSTEXPR const char CLAP_EXT_PARAM_INDICATION_COMPAT[] = "clap.param-indication.draft/4"; 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | enum { 27 | // The host doesn't have an automation for this parameter 28 | CLAP_PARAM_INDICATION_AUTOMATION_NONE = 0, 29 | 30 | // The host has an automation for this parameter, but it isn't playing it 31 | CLAP_PARAM_INDICATION_AUTOMATION_PRESENT = 1, 32 | 33 | // The host is playing an automation for this parameter 34 | CLAP_PARAM_INDICATION_AUTOMATION_PLAYING = 2, 35 | 36 | // The host is recording an automation on this parameter 37 | CLAP_PARAM_INDICATION_AUTOMATION_RECORDING = 3, 38 | 39 | // The host should play an automation for this parameter, but the user has started to adjust this 40 | // parameter and is overriding the automation playback 41 | CLAP_PARAM_INDICATION_AUTOMATION_OVERRIDING = 4, 42 | }; 43 | 44 | typedef struct clap_plugin_param_indication { 45 | // Sets or clears a mapping indication. 46 | // 47 | // has_mapping: does the parameter currently has a mapping? 48 | // color: if set, the color to use to highlight the control in the plugin GUI 49 | // label: if set, a small string to display on top of the knob which identifies the hardware 50 | // controller description: if set, a string which can be used in a tooltip, which describes the 51 | // current mapping 52 | // 53 | // Parameter indications should not be saved in the plugin context, and are off by default. 54 | // [main-thread] 55 | void(CLAP_ABI *set_mapping)(const clap_plugin_t *plugin, 56 | clap_id param_id, 57 | bool has_mapping, 58 | const clap_color_t *color, 59 | const char *label, 60 | const char *description); 61 | 62 | // Sets or clears an automation indication. 63 | // 64 | // automation_state: current automation state for the given parameter 65 | // color: if set, the color to use to display the automation indication in the plugin GUI 66 | // 67 | // Parameter indications should not be saved in the plugin context, and are off by default. 68 | // [main-thread] 69 | void(CLAP_ABI *set_automation)(const clap_plugin_t *plugin, 70 | clap_id param_id, 71 | uint32_t automation_state, 72 | const clap_color_t *color); 73 | } clap_plugin_param_indication_t; 74 | 75 | #ifdef __cplusplus 76 | } 77 | #endif 78 | -------------------------------------------------------------------------------- /include/clap/ext/posix-fd-support.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../plugin.h" 4 | 5 | // This extension let your plugin hook itself into the host select/poll/epoll/kqueue reactor. 6 | // This is useful to handle asynchronous I/O on the main thread. 7 | static CLAP_CONSTEXPR const char CLAP_EXT_POSIX_FD_SUPPORT[] = "clap.posix-fd-support"; 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | enum { 14 | // IO events flags, they can be used to form a mask which describes: 15 | // - which events you are interested in (register_fd/modify_fd) 16 | // - which events happened (on_fd) 17 | CLAP_POSIX_FD_READ = 1 << 0, 18 | CLAP_POSIX_FD_WRITE = 1 << 1, 19 | CLAP_POSIX_FD_ERROR = 1 << 2, 20 | }; 21 | typedef uint32_t clap_posix_fd_flags_t; 22 | 23 | typedef struct clap_plugin_posix_fd_support { 24 | // This callback is "level-triggered". 25 | // It means that a writable fd will continuously produce "on_fd()" events; 26 | // don't forget using modify_fd() to remove the write notification once you're 27 | // done writing. 28 | // 29 | // [main-thread] 30 | void(CLAP_ABI *on_fd)(const clap_plugin_t *plugin, int fd, clap_posix_fd_flags_t flags); 31 | } clap_plugin_posix_fd_support_t; 32 | 33 | typedef struct clap_host_posix_fd_support { 34 | // Returns true on success. 35 | // [main-thread] 36 | bool(CLAP_ABI *register_fd)(const clap_host_t *host, int fd, clap_posix_fd_flags_t flags); 37 | 38 | // Returns true on success. 39 | // [main-thread] 40 | bool(CLAP_ABI *modify_fd)(const clap_host_t *host, int fd, clap_posix_fd_flags_t flags); 41 | 42 | // Returns true on success. 43 | // [main-thread] 44 | bool(CLAP_ABI *unregister_fd)(const clap_host_t *host, int fd); 45 | } clap_host_posix_fd_support_t; 46 | 47 | #ifdef __cplusplus 48 | } 49 | #endif 50 | -------------------------------------------------------------------------------- /include/clap/ext/preset-load.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../plugin.h" 4 | 5 | static CLAP_CONSTEXPR const char CLAP_EXT_PRESET_LOAD[] = "clap.preset-load/2"; 6 | 7 | // The latest draft is 100% compatible. 8 | // This compat ID may be removed in 2026. 9 | static CLAP_CONSTEXPR const char CLAP_EXT_PRESET_LOAD_COMPAT[] = "clap.preset-load.draft/2"; 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | typedef struct clap_plugin_preset_load { 16 | // Loads a preset in the plugin native preset file format from a location. 17 | // The preset discovery provider defines the location and load_key to be passed to this function. 18 | // Returns true on success. 19 | // [main-thread] 20 | bool(CLAP_ABI *from_location)(const clap_plugin_t *plugin, 21 | uint32_t location_kind, 22 | const char *location, 23 | const char *load_key); 24 | } clap_plugin_preset_load_t; 25 | 26 | typedef struct clap_host_preset_load { 27 | // Called if clap_plugin_preset_load.load() failed. 28 | // os_error: the operating system error, if applicable. If not applicable set it to a non-error 29 | // value, eg: 0 on unix and Windows. 30 | // 31 | // [main-thread] 32 | void(CLAP_ABI *on_error)(const clap_host_t *host, 33 | uint32_t location_kind, 34 | const char *location, 35 | const char *load_key, 36 | int32_t os_error, 37 | const char *msg); 38 | 39 | // Informs the host that the following preset has been loaded. 40 | // This contributes to keep in sync the host preset browser and plugin preset browser. 41 | // If the preset was loaded from a container file, then the load_key must be set, otherwise it 42 | // must be null. 43 | // 44 | // [main-thread] 45 | void(CLAP_ABI *loaded)(const clap_host_t *host, 46 | uint32_t location_kind, 47 | const char *location, 48 | const char *load_key); 49 | } clap_host_preset_load_t; 50 | 51 | #ifdef __cplusplus 52 | } 53 | #endif 54 | -------------------------------------------------------------------------------- /include/clap/ext/remote-controls.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../plugin.h" 4 | #include "../string-sizes.h" 5 | 6 | // This extension let the plugin provide a structured way of mapping parameters to an hardware 7 | // controller. 8 | // 9 | // This is done by providing a set of remote control pages organized by section. 10 | // A page contains up to 8 controls, which references parameters using param_id. 11 | // 12 | // |`- [section:main] 13 | // | `- [name:main] performance controls 14 | // |`- [section:osc] 15 | // | |`- [name:osc1] osc1 page 16 | // | |`- [name:osc2] osc2 page 17 | // | |`- [name:osc-sync] osc sync page 18 | // | `- [name:osc-noise] osc noise page 19 | // |`- [section:filter] 20 | // | |`- [name:flt1] filter 1 page 21 | // | `- [name:flt2] filter 2 page 22 | // |`- [section:env] 23 | // | |`- [name:env1] env1 page 24 | // | `- [name:env2] env2 page 25 | // |`- [section:lfo] 26 | // | |`- [name:lfo1] env1 page 27 | // | `- [name:lfo2] env2 page 28 | // `- etc... 29 | // 30 | // One possible workflow is to have a set of buttons, which correspond to a section. 31 | // Pressing that button once gets you to the first page of the section. 32 | // Press it again to cycle through the section's pages. 33 | 34 | static CLAP_CONSTEXPR const char CLAP_EXT_REMOTE_CONTROLS[] = "clap.remote-controls/2"; 35 | 36 | // The latest draft is 100% compatible 37 | // This compat ID may be removed in 2026. 38 | static CLAP_CONSTEXPR const char CLAP_EXT_REMOTE_CONTROLS_COMPAT[] = "clap.remote-controls.draft/2"; 39 | 40 | #ifdef __cplusplus 41 | extern "C" { 42 | #endif 43 | 44 | enum { CLAP_REMOTE_CONTROLS_COUNT = 8 }; 45 | 46 | typedef struct clap_remote_controls_page { 47 | char section_name[CLAP_NAME_SIZE]; 48 | clap_id page_id; 49 | char page_name[CLAP_NAME_SIZE]; 50 | clap_id param_ids[CLAP_REMOTE_CONTROLS_COUNT]; 51 | 52 | // This is used to separate device pages versus preset pages. 53 | // If true, then this page is specific to this preset. 54 | bool is_for_preset; 55 | } clap_remote_controls_page_t; 56 | 57 | typedef struct clap_plugin_remote_controls { 58 | // Returns the number of pages. 59 | // [main-thread] 60 | uint32_t(CLAP_ABI *count)(const clap_plugin_t *plugin); 61 | 62 | // Get a page by index. 63 | // Returns true on success and stores the result into page. 64 | // [main-thread] 65 | bool(CLAP_ABI *get)(const clap_plugin_t *plugin, 66 | uint32_t page_index, 67 | clap_remote_controls_page_t *page); 68 | } clap_plugin_remote_controls_t; 69 | 70 | typedef struct clap_host_remote_controls { 71 | // Informs the host that the remote controls have changed. 72 | // [main-thread] 73 | void(CLAP_ABI *changed)(const clap_host_t *host); 74 | 75 | // Suggest a page to the host because it corresponds to what the user is currently editing in the 76 | // plugin's GUI. 77 | // [main-thread] 78 | void(CLAP_ABI *suggest_page)(const clap_host_t *host, clap_id page_id); 79 | } clap_host_remote_controls_t; 80 | 81 | #ifdef __cplusplus 82 | } 83 | #endif 84 | -------------------------------------------------------------------------------- /include/clap/ext/render.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../plugin.h" 4 | 5 | static CLAP_CONSTEXPR const char CLAP_EXT_RENDER[] = "clap.render"; 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | enum { 12 | // Default setting, for "realtime" processing 13 | CLAP_RENDER_REALTIME = 0, 14 | 15 | // For processing without realtime pressure 16 | // The plugin may use more expensive algorithms for higher sound quality. 17 | CLAP_RENDER_OFFLINE = 1, 18 | }; 19 | typedef int32_t clap_plugin_render_mode; 20 | 21 | // The render extension is used to let the plugin know if it has "realtime" 22 | // pressure to process. 23 | // 24 | // If this information does not influence your rendering code, then don't 25 | // implement this extension. 26 | typedef struct clap_plugin_render { 27 | // Returns true if the plugin has a hard requirement to process in real-time. 28 | // This is especially useful for plugin acting as a proxy to an hardware device. 29 | // [main-thread] 30 | bool(CLAP_ABI *has_hard_realtime_requirement)(const clap_plugin_t *plugin); 31 | 32 | // Returns true if the rendering mode could be applied. 33 | // [main-thread] 34 | bool(CLAP_ABI *set)(const clap_plugin_t *plugin, clap_plugin_render_mode mode); 35 | } clap_plugin_render_t; 36 | 37 | #ifdef __cplusplus 38 | } 39 | #endif 40 | -------------------------------------------------------------------------------- /include/clap/ext/state-context.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../plugin.h" 4 | #include "../stream.h" 5 | 6 | /// @page state-context extension 7 | /// @brief extended state handling 8 | /// 9 | /// This extension lets the host save and load the plugin state with different semantics depending 10 | /// on the context. 11 | /// 12 | /// Briefly, when loading a preset or duplicating a device, the plugin may want to partially load 13 | /// the state and initialize certain things differently, like handling limited resources or fixed 14 | /// connections to external hardware resources. 15 | /// 16 | /// Save and Load operations may have a different context. 17 | /// All three operations should be equivalent: 18 | /// 1. clap_plugin_state_context.load(clap_plugin_state.save(), CLAP_STATE_CONTEXT_FOR_PRESET) 19 | /// 2. clap_plugin_state.load(clap_plugin_state_context.save(CLAP_STATE_CONTEXT_FOR_PRESET)) 20 | /// 3. clap_plugin_state_context.load( 21 | /// clap_plugin_state_context.save(CLAP_STATE_CONTEXT_FOR_PRESET), 22 | /// CLAP_STATE_CONTEXT_FOR_PRESET) 23 | /// 24 | /// If in doubt, fallback to clap_plugin_state. 25 | /// 26 | /// If the plugin implements CLAP_EXT_STATE_CONTEXT then it is mandatory to also implement 27 | /// CLAP_EXT_STATE. 28 | /// 29 | /// It is unspecified which context is equivalent to clap_plugin_state.{save,load}() 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | static CLAP_CONSTEXPR const char CLAP_EXT_STATE_CONTEXT[] = "clap.state-context/2"; 36 | 37 | enum clap_plugin_state_context_type { 38 | // suitable for storing and loading a state as a preset 39 | CLAP_STATE_CONTEXT_FOR_PRESET = 1, 40 | 41 | // suitable for duplicating a plugin instance 42 | CLAP_STATE_CONTEXT_FOR_DUPLICATE = 2, 43 | 44 | // suitable for storing and loading a state within a project/song 45 | CLAP_STATE_CONTEXT_FOR_PROJECT = 3, 46 | }; 47 | 48 | typedef struct clap_plugin_state_context { 49 | // Saves the plugin state into stream, according to context_type. 50 | // Returns true if the state was correctly saved. 51 | // 52 | // Note that the result may be loaded by both clap_plugin_state.load() and 53 | // clap_plugin_state_context.load(). 54 | // [main-thread] 55 | bool(CLAP_ABI *save)(const clap_plugin_t *plugin, 56 | const clap_ostream_t *stream, 57 | uint32_t context_type); 58 | 59 | // Loads the plugin state from stream, according to context_type. 60 | // Returns true if the state was correctly restored. 61 | // 62 | // Note that the state may have been saved by clap_plugin_state.save() or 63 | // clap_plugin_state_context.save() with a different context_type. 64 | // [main-thread] 65 | bool(CLAP_ABI *load)(const clap_plugin_t *plugin, 66 | const clap_istream_t *stream, 67 | uint32_t context_type); 68 | } clap_plugin_state_context_t; 69 | 70 | #ifdef __cplusplus 71 | } 72 | #endif 73 | -------------------------------------------------------------------------------- /include/clap/ext/state.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../plugin.h" 4 | #include "../stream.h" 5 | 6 | /// @page State 7 | /// @brief state management 8 | /// 9 | /// Plugins can implement this extension to save and restore both parameter 10 | /// values and non-parameter state. This is used to persist a plugin's state 11 | /// between project reloads, when duplicating and copying plugin instances, and 12 | /// for host-side preset management. 13 | /// 14 | /// If you need to know if the save/load operation is meant for duplicating a plugin 15 | /// instance, for saving/loading a plugin preset or while saving/loading the project 16 | /// then consider implementing CLAP_EXT_STATE_CONTEXT in addition to CLAP_EXT_STATE. 17 | 18 | static CLAP_CONSTEXPR const char CLAP_EXT_STATE[] = "clap.state"; 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | typedef struct clap_plugin_state { 25 | // Saves the plugin state into stream. 26 | // Returns true if the state was correctly saved. 27 | // [main-thread] 28 | bool(CLAP_ABI *save)(const clap_plugin_t *plugin, const clap_ostream_t *stream); 29 | 30 | // Loads the plugin state from stream. 31 | // Returns true if the state was correctly restored. 32 | // [main-thread] 33 | bool(CLAP_ABI *load)(const clap_plugin_t *plugin, const clap_istream_t *stream); 34 | } clap_plugin_state_t; 35 | 36 | typedef struct clap_host_state { 37 | // Tell the host that the plugin state has changed and should be saved again. 38 | // If a parameter value changes, then it is implicit that the state is dirty. 39 | // [main-thread] 40 | void(CLAP_ABI *mark_dirty)(const clap_host_t *host); 41 | } clap_host_state_t; 42 | 43 | #ifdef __cplusplus 44 | } 45 | #endif 46 | -------------------------------------------------------------------------------- /include/clap/ext/surround.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../plugin.h" 4 | 5 | // This extension can be used to specify the channel mapping used by the plugin. 6 | // 7 | // To have consistent surround features across all the plugin instances, 8 | // here is the proposed workflow: 9 | // 1. the plugin queries the host preferred channel mapping and 10 | // adjusts its configuration to match it. 11 | // 2. the host checks how the plugin is effectively configured and honors it. 12 | // 13 | // If the host decides to change the project's surround setup: 14 | // 1. deactivate the plugin 15 | // 2. host calls clap_plugin_surround->changed() 16 | // 3. plugin calls clap_host_surround->get_preferred_channel_map() 17 | // 4. plugin eventually calls clap_host_surround->changed() 18 | // 5. host calls clap_plugin_surround->get_channel_map() if changed 19 | // 6. host activates the plugin and can start processing audio 20 | // 21 | // If the plugin wants to change its surround setup: 22 | // 1. call host->request_restart() if the plugin is active 23 | // 2. once deactivated plugin calls clap_host_surround->changed() 24 | // 3. host calls clap_plugin_surround->get_channel_map() 25 | // 4. host activates the plugin and can start processing audio 26 | 27 | static CLAP_CONSTEXPR const char CLAP_EXT_SURROUND[] = "clap.surround/4"; 28 | 29 | // The latest draft is 100% compatible. 30 | // This compat ID may be removed in 2026. 31 | static CLAP_CONSTEXPR const char CLAP_EXT_SURROUND_COMPAT[] = "clap.surround.draft/4"; 32 | 33 | static CLAP_CONSTEXPR const char CLAP_PORT_SURROUND[] = "surround"; 34 | 35 | #ifdef __cplusplus 36 | extern "C" { 37 | #endif 38 | 39 | enum { 40 | CLAP_SURROUND_FL = 0, // Front Left 41 | CLAP_SURROUND_FR = 1, // Front Right 42 | CLAP_SURROUND_FC = 2, // Front Center 43 | CLAP_SURROUND_LFE = 3, // Low Frequency 44 | CLAP_SURROUND_BL = 4, // Back (Rear) Left 45 | CLAP_SURROUND_BR = 5, // Back (Rear) Right 46 | CLAP_SURROUND_FLC = 6, // Front Left of Center 47 | CLAP_SURROUND_FRC = 7, // Front Right of Center 48 | CLAP_SURROUND_BC = 8, // Back (Rear) Center 49 | CLAP_SURROUND_SL = 9, // Side Left 50 | CLAP_SURROUND_SR = 10, // Side Right 51 | CLAP_SURROUND_TC = 11, // Top (Height) Center 52 | CLAP_SURROUND_TFL = 12, // Top (Height) Front Left 53 | CLAP_SURROUND_TFC = 13, // Top (Height) Front Center 54 | CLAP_SURROUND_TFR = 14, // Top (Height) Front Right 55 | CLAP_SURROUND_TBL = 15, // Top (Height) Back (Rear) Left 56 | CLAP_SURROUND_TBC = 16, // Top (Height) Back (Rear) Center 57 | CLAP_SURROUND_TBR = 17, // Top (Height) Back (Rear) Right 58 | CLAP_SURROUND_TSL = 18, // Top (Height) Side Left 59 | CLAP_SURROUND_TSR = 19, // Top (Height) Side Right 60 | }; 61 | 62 | typedef struct clap_plugin_surround { 63 | // Checks if a given channel mask is supported. 64 | // The channel mask is a bitmask, for example: 65 | // (1 << CLAP_SURROUND_FL) | (1 << CLAP_SURROUND_FR) | ... 66 | // [main-thread] 67 | bool(CLAP_ABI *is_channel_mask_supported)(const clap_plugin_t *plugin, uint64_t channel_mask); 68 | 69 | // Stores the surround identifier of each channel into the channel_map array. 70 | // Returns the number of elements stored in channel_map. 71 | // channel_map_capacity must be greater or equal to the channel count of the given port. 72 | // [main-thread] 73 | uint32_t(CLAP_ABI *get_channel_map)(const clap_plugin_t *plugin, 74 | bool is_input, 75 | uint32_t port_index, 76 | uint8_t *channel_map, 77 | uint32_t channel_map_capacity); 78 | } clap_plugin_surround_t; 79 | 80 | typedef struct clap_host_surround { 81 | // Informs the host that the channel map has changed. 82 | // The channel map can only change when the plugin is de-activated. 83 | // [main-thread] 84 | void(CLAP_ABI *changed)(const clap_host_t *host); 85 | } clap_host_surround_t; 86 | 87 | #ifdef __cplusplus 88 | } 89 | #endif 90 | -------------------------------------------------------------------------------- /include/clap/ext/tail.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../plugin.h" 4 | 5 | static CLAP_CONSTEXPR const char CLAP_EXT_TAIL[] = "clap.tail"; 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | typedef struct clap_plugin_tail { 12 | // Returns tail length in samples. 13 | // Any value greater or equal to INT32_MAX implies infinite tail. 14 | // [main-thread,audio-thread] 15 | uint32_t(CLAP_ABI *get)(const clap_plugin_t *plugin); 16 | } clap_plugin_tail_t; 17 | 18 | typedef struct clap_host_tail { 19 | // Tell the host that the tail has changed. 20 | // [audio-thread] 21 | void(CLAP_ABI *changed)(const clap_host_t *host); 22 | } clap_host_tail_t; 23 | 24 | #ifdef __cplusplus 25 | } 26 | #endif 27 | -------------------------------------------------------------------------------- /include/clap/ext/thread-check.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../plugin.h" 4 | 5 | static CLAP_CONSTEXPR const char CLAP_EXT_THREAD_CHECK[] = "clap.thread-check"; 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | /// @page thread-check 12 | /// 13 | /// CLAP defines two symbolic threads: 14 | /// 15 | /// main-thread: 16 | /// This is the thread in which most of the interaction between the plugin and host happens. 17 | /// This will be the same OS thread throughout the lifetime of the plug-in. 18 | /// On macOS and Windows, this must be the thread on which gui and timer events are received 19 | /// (i.e., the main thread of the program). 20 | /// It isn't a realtime thread, yet this thread needs to respond fast enough to allow responsive 21 | /// user interaction, so it is strongly recommended plugins run long,and expensive or blocking 22 | /// tasks such as preset indexing or asset loading in dedicated background threads started by the 23 | /// plugin. 24 | /// 25 | /// audio-thread: 26 | /// This thread can be used for realtime audio processing. Its execution should be as 27 | /// deterministic as possible to meet the audio interface's deadline (can be <1ms). There are a 28 | /// known set of operations that should be avoided: malloc() and free(), contended locks and 29 | /// mutexes, I/O, waiting, and so forth. 30 | /// 31 | /// The audio-thread is symbolic, there isn't one OS thread that remains the 32 | /// audio-thread for the plugin lifetime. A host is may opt to have a 33 | /// thread pool and the plugin.process() call may be scheduled on different OS threads over time. 34 | /// However, the host must guarantee that single plugin instance will not be two audio-threads 35 | /// at the same time. 36 | /// 37 | /// Functions marked with [audio-thread] **ARE NOT CONCURRENT**. The host may mark any OS thread, 38 | /// including the main-thread as the audio-thread, as long as it can guarantee that only one OS 39 | /// thread is the audio-thread at a time in a plugin instance. The audio-thread can be seen as a 40 | /// concurrency guard for all functions marked with [audio-thread]. 41 | /// 42 | /// The real-time constraint on the [audio-thread] interacts closely with the render extension. 43 | /// If a plugin doesn't implement render, then that plugin must have all [audio-thread] functions 44 | /// meet the real time standard. If the plugin does implement render, and returns true when 45 | /// render mode is set to real-time or if the plugin advertises a hard realtime requirement, it 46 | /// must implement realtime constraints. Hosts also provide functions marked [audio-thread]. 47 | /// These can be safely called by a plugin in the audio thread. Therefore hosts must either (1) 48 | /// implement those functions meeting the real-time constraints or (2) not process plugins which 49 | /// advertise a hard realtime constraint or don't implement the render extension. Hosts which 50 | /// provide [audio-thread] functions outside these conditions may experience inconsistent or 51 | /// inaccurate rendering. 52 | /// 53 | /// Clap also tags some functions as [thread-safe]. Functions tagged as [thread-safe] can be called 54 | /// from any thread unless explicitly counter-indicated (for instance [thread-safe, !audio-thread]) 55 | /// and may be called concurrently. 56 | 57 | // This interface is useful to do runtime checks and make 58 | // sure that the functions are called on the correct threads. 59 | // It is highly recommended that hosts implement this extension. 60 | typedef struct clap_host_thread_check { 61 | // Returns true if "this" thread is the main thread. 62 | // [thread-safe] 63 | bool(CLAP_ABI *is_main_thread)(const clap_host_t *host); 64 | 65 | // Returns true if "this" thread is one of the audio threads. 66 | // [thread-safe] 67 | bool(CLAP_ABI *is_audio_thread)(const clap_host_t *host); 68 | } clap_host_thread_check_t; 69 | 70 | #ifdef __cplusplus 71 | } 72 | #endif 73 | -------------------------------------------------------------------------------- /include/clap/ext/thread-pool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../plugin.h" 4 | 5 | /// @page 6 | /// 7 | /// This extension lets the plugin use the host's thread pool. 8 | /// 9 | /// The plugin must provide @ref clap_plugin_thread_pool, and the host may provide @ref 10 | /// clap_host_thread_pool. If it doesn't, the plugin should process its data by its own means. In 11 | /// the worst case, a single threaded for-loop. 12 | /// 13 | /// Simple example with N voices to process 14 | /// 15 | /// @code 16 | /// void myplug_thread_pool_exec(const clap_plugin *plugin, uint32_t voice_index) 17 | /// { 18 | /// compute_voice(plugin, voice_index); 19 | /// } 20 | /// 21 | /// void myplug_process(const clap_plugin *plugin, const clap_process *process) 22 | /// { 23 | /// ... 24 | /// bool didComputeVoices = false; 25 | /// if (host_thread_pool && host_thread_pool.exec) 26 | /// didComputeVoices = host_thread_pool.request_exec(host, plugin, N); 27 | /// 28 | /// if (!didComputeVoices) 29 | /// for (uint32_t i = 0; i < N; ++i) 30 | /// myplug_thread_pool_exec(plugin, i); 31 | /// ... 32 | /// } 33 | /// @endcode 34 | /// 35 | /// Be aware that using a thread pool may break hard real-time rules due to the thread 36 | /// synchronization involved. 37 | /// 38 | /// If the host knows that it is running under hard real-time pressure it may decide to not 39 | /// provide this interface. 40 | 41 | static CLAP_CONSTEXPR const char CLAP_EXT_THREAD_POOL[] = "clap.thread-pool"; 42 | 43 | #ifdef __cplusplus 44 | extern "C" { 45 | #endif 46 | 47 | typedef struct clap_plugin_thread_pool { 48 | // Called by the thread pool 49 | void(CLAP_ABI *exec)(const clap_plugin_t *plugin, uint32_t task_index); 50 | } clap_plugin_thread_pool_t; 51 | 52 | typedef struct clap_host_thread_pool { 53 | // Schedule num_tasks jobs in the host thread pool. 54 | // It can't be called concurrently or from the thread pool. 55 | // Will block until all the tasks are processed. 56 | // This must be used exclusively for realtime processing within the process call. 57 | // Returns true if the host did execute all the tasks, false if it rejected the request. 58 | // The host should check that the plugin is within the process call, and if not, reject the exec 59 | // request. 60 | // [audio-thread] 61 | bool(CLAP_ABI *request_exec)(const clap_host_t *host, uint32_t num_tasks); 62 | } clap_host_thread_pool_t; 63 | 64 | #ifdef __cplusplus 65 | } 66 | #endif 67 | -------------------------------------------------------------------------------- /include/clap/ext/timer-support.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../plugin.h" 4 | 5 | static CLAP_CONSTEXPR const char CLAP_EXT_TIMER_SUPPORT[] = "clap.timer-support"; 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | typedef struct clap_plugin_timer_support { 12 | // [main-thread] 13 | void(CLAP_ABI *on_timer)(const clap_plugin_t *plugin, clap_id timer_id); 14 | } clap_plugin_timer_support_t; 15 | 16 | typedef struct clap_host_timer_support { 17 | // Registers a periodic timer. 18 | // The host may adjust the period if it is under a certain threshold. 19 | // 30 Hz should be allowed. 20 | // Returns true on success. 21 | // [main-thread] 22 | bool(CLAP_ABI *register_timer)(const clap_host_t *host, uint32_t period_ms, clap_id *timer_id); 23 | 24 | // Returns true on success. 25 | // [main-thread] 26 | bool(CLAP_ABI *unregister_timer)(const clap_host_t *host, clap_id timer_id); 27 | } clap_host_timer_support_t; 28 | 29 | #ifdef __cplusplus 30 | } 31 | #endif 32 | -------------------------------------------------------------------------------- /include/clap/ext/track-info.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../plugin.h" 4 | #include "../color.h" 5 | #include "../string-sizes.h" 6 | 7 | // This extension let the plugin query info about the track it's in. 8 | // It is useful when the plugin is created, to initialize some parameters (mix, dry, wet) 9 | // and pick a suitable configuration regarding audio port type and channel count. 10 | 11 | static CLAP_CONSTEXPR const char CLAP_EXT_TRACK_INFO[] = "clap.track-info/1"; 12 | 13 | // The latest draft is 100% compatible. 14 | // This compat ID may be removed in 2026. 15 | static CLAP_CONSTEXPR const char CLAP_EXT_TRACK_INFO_COMPAT[] = "clap.track-info.draft/1"; 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | enum { 22 | CLAP_TRACK_INFO_HAS_TRACK_NAME = (1 << 0), 23 | CLAP_TRACK_INFO_HAS_TRACK_COLOR = (1 << 1), 24 | CLAP_TRACK_INFO_HAS_AUDIO_CHANNEL = (1 << 2), 25 | 26 | // This plugin is on a return track, initialize with wet 100% 27 | CLAP_TRACK_INFO_IS_FOR_RETURN_TRACK = (1 << 3), 28 | 29 | // This plugin is on a bus track, initialize with appropriate settings for bus processing 30 | CLAP_TRACK_INFO_IS_FOR_BUS = (1 << 4), 31 | 32 | // This plugin is on the master, initialize with appropriate settings for channel processing 33 | CLAP_TRACK_INFO_IS_FOR_MASTER = (1 << 5), 34 | }; 35 | 36 | typedef struct clap_track_info { 37 | uint64_t flags; // see the flags above 38 | 39 | // track name, available if flags contain CLAP_TRACK_INFO_HAS_TRACK_NAME 40 | char name[CLAP_NAME_SIZE]; 41 | 42 | // track color, available if flags contain CLAP_TRACK_INFO_HAS_TRACK_COLOR 43 | clap_color_t color; 44 | 45 | // available if flags contain CLAP_TRACK_INFO_HAS_AUDIO_CHANNEL 46 | // see audio-ports.h, struct clap_audio_port_info to learn how to use channel count and port type 47 | int32_t audio_channel_count; 48 | const char *audio_port_type; 49 | } clap_track_info_t; 50 | 51 | typedef struct clap_plugin_track_info { 52 | // Called when the info changes. 53 | // [main-thread] 54 | void(CLAP_ABI *changed)(const clap_plugin_t *plugin); 55 | } clap_plugin_track_info_t; 56 | 57 | typedef struct clap_host_track_info { 58 | // Get info about the track the plugin belongs to. 59 | // Returns true on success and stores the result into info. 60 | // [main-thread] 61 | bool(CLAP_ABI *get)(const clap_host_t *host, clap_track_info_t *info); 62 | } clap_host_track_info_t; 63 | 64 | #ifdef __cplusplus 65 | } 66 | #endif 67 | -------------------------------------------------------------------------------- /include/clap/ext/voice-info.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../plugin.h" 4 | 5 | // This extension indicates the number of voices the synthesizer has. 6 | // It is useful for the host when performing polyphonic modulations, 7 | // because the host needs its own voice management and should try to follow 8 | // what the plugin is doing: 9 | // - make the host's voice pool coherent with what the plugin has 10 | // - turn the host's voice management to mono when the plugin is mono 11 | 12 | static CLAP_CONSTEXPR const char CLAP_EXT_VOICE_INFO[] = "clap.voice-info"; 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | enum { 19 | // Allows the host to send overlapping NOTE_ON events. 20 | // The plugin will then rely upon the note_id to distinguish between them. 21 | CLAP_VOICE_INFO_SUPPORTS_OVERLAPPING_NOTES = 1 << 0, 22 | }; 23 | 24 | typedef struct clap_voice_info { 25 | // voice_count is the current number of voices that the patch can use 26 | // voice_capacity is the number of voices allocated voices 27 | // voice_count should not be confused with the number of active voices. 28 | // 29 | // 1 <= voice_count <= voice_capacity 30 | // 31 | // For example, a synth can have a capacity of 8 voices, but be configured 32 | // to only use 4 voices: {count: 4, capacity: 8}. 33 | // 34 | // If the voice_count is 1, then the synth is working in mono and the host 35 | // can decide to only use global modulation mapping. 36 | uint32_t voice_count; 37 | uint32_t voice_capacity; 38 | 39 | uint64_t flags; 40 | } clap_voice_info_t; 41 | 42 | typedef struct clap_plugin_voice_info { 43 | // gets the voice info, returns true on success 44 | // [main-thread && active] 45 | bool(CLAP_ABI *get)(const clap_plugin_t *plugin, clap_voice_info_t *info); 46 | } clap_plugin_voice_info_t; 47 | 48 | typedef struct clap_host_voice_info { 49 | // informs the host that the voice info has changed 50 | // [main-thread] 51 | void(CLAP_ABI *changed)(const clap_host_t *host); 52 | } clap_host_voice_info_t; 53 | 54 | #ifdef __cplusplus 55 | } 56 | #endif 57 | -------------------------------------------------------------------------------- /include/clap/factory/draft/plugin-invalidation.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../private/std.h" 4 | #include "../../private/macros.h" 5 | 6 | // Use it to retrieve const clap_plugin_invalidation_factory_t* from 7 | // clap_plugin_entry.get_factory() 8 | static const CLAP_CONSTEXPR char CLAP_PLUGIN_INVALIDATION_FACTORY_ID[] = 9 | "clap.plugin-invalidation-factory/1"; 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | typedef struct clap_plugin_invalidation_source { 16 | // Directory containing the file(s) to scan, must be absolute 17 | const char *directory; 18 | 19 | // globing pattern, in the form *.dll 20 | const char *filename_glob; 21 | 22 | // should the directory be scanned recursively? 23 | bool recursive_scan; 24 | } clap_plugin_invalidation_source_t; 25 | 26 | // Used to figure out when a plugin needs to be scanned again. 27 | // Imagine a situation with a single entry point: my-plugin.clap which then scans itself 28 | // a set of "sub-plugins". New plugin may be available even if my-plugin.clap file doesn't change. 29 | // This interfaces solves this issue and gives a way to the host to monitor additional files. 30 | typedef struct clap_plugin_invalidation_factory { 31 | // Get the number of invalidation source. 32 | uint32_t(CLAP_ABI *count)(const struct clap_plugin_invalidation_factory *factory); 33 | 34 | // Get the invalidation source by its index. 35 | // [thread-safe] 36 | const clap_plugin_invalidation_source_t *(CLAP_ABI *get)( 37 | const struct clap_plugin_invalidation_factory *factory, uint32_t index); 38 | 39 | // In case the host detected a invalidation event, it can call refresh() to let the 40 | // plugin_entry update the set of plugins available. 41 | // If the function returned false, then the plugin needs to be reloaded. 42 | bool(CLAP_ABI *refresh)(const struct clap_plugin_invalidation_factory *factory); 43 | } clap_plugin_invalidation_factory_t; 44 | 45 | #ifdef __cplusplus 46 | } 47 | #endif 48 | -------------------------------------------------------------------------------- /include/clap/factory/draft/plugin-state-converter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../id.h" 4 | #include "../../universal-plugin-id.h" 5 | #include "../../stream.h" 6 | #include "../../version.h" 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | typedef struct clap_plugin_state_converter_descriptor { 13 | clap_version_t clap_version; 14 | 15 | clap_universal_plugin_id_t src_plugin_id; 16 | clap_universal_plugin_id_t dst_plugin_id; 17 | 18 | const char *id; // eg: "com.u-he.diva-converter", mandatory 19 | const char *name; // eg: "Diva Converter", mandatory 20 | const char *vendor; // eg: "u-he" 21 | const char *version; // eg: 1.1.5 22 | const char *description; // eg: "Official state converter for u-he Diva." 23 | } clap_plugin_state_converter_descriptor_t; 24 | 25 | // This interface provides a mechanism for the host to convert a plugin state and its automation 26 | // points to a new plugin. 27 | // 28 | // This is useful to convert from one plugin ABI to another one. 29 | // This is also useful to offer an upgrade path: from EQ version 1 to EQ version 2. 30 | // This can also be used to convert the state of a plugin that isn't maintained anymore into 31 | // another plugin that would be similar. 32 | typedef struct clap_plugin_state_converter { 33 | const clap_plugin_state_converter_descriptor_t *desc; 34 | 35 | void *converter_data; 36 | 37 | // Destroy the converter. 38 | void (*destroy)(struct clap_plugin_state_converter *converter); 39 | 40 | // Converts the input state to a state usable by the destination plugin. 41 | // 42 | // error_buffer is a place holder of error_buffer_size bytes for storing a null-terminated 43 | // error message in case of failure, which can be displayed to the user. 44 | // 45 | // Returns true on success. 46 | // [thread-safe] 47 | bool (*convert_state)(struct clap_plugin_state_converter *converter, 48 | const clap_istream_t *src, 49 | const clap_ostream_t *dst, 50 | char *error_buffer, 51 | size_t error_buffer_size); 52 | 53 | // Converts a normalized value. 54 | // Returns true on success. 55 | // [thread-safe] 56 | bool (*convert_normalized_value)(struct clap_plugin_state_converter *converter, 57 | clap_id src_param_id, 58 | double src_normalized_value, 59 | clap_id *dst_param_id, 60 | double *dst_normalized_value); 61 | 62 | // Converts a plain value. 63 | // Returns true on success. 64 | // [thread-safe] 65 | bool (*convert_plain_value)(struct clap_plugin_state_converter *converter, 66 | clap_id src_param_id, 67 | double src_plain_value, 68 | clap_id *dst_param_id, 69 | double *dst_plain_value); 70 | } clap_plugin_state_converter_t; 71 | 72 | // Factory identifier 73 | static CLAP_CONSTEXPR const char CLAP_PLUGIN_STATE_CONVERTER_FACTORY_ID[] = 74 | "clap.plugin-state-converter-factory/1"; 75 | 76 | // List all the plugin state converters available in the current DSO. 77 | typedef struct clap_plugin_state_converter_factory { 78 | // Get the number of converters. 79 | // [thread-safe] 80 | uint32_t (*count)(const struct clap_plugin_state_converter_factory *factory); 81 | 82 | // Retrieves a plugin state converter descriptor by its index. 83 | // Returns null in case of error. 84 | // The descriptor must not be freed. 85 | // [thread-safe] 86 | const clap_plugin_state_converter_descriptor_t *(*get_descriptor)( 87 | const struct clap_plugin_state_converter_factory *factory, uint32_t index); 88 | 89 | // Create a plugin state converter by its converter_id. 90 | // The returned pointer must be freed by calling converter->destroy(converter); 91 | // Returns null in case of error. 92 | // [thread-safe] 93 | clap_plugin_state_converter_t *(*create)( 94 | const struct clap_plugin_state_converter_factory *factory, const char *converter_id); 95 | } clap_plugin_state_converter_factory_t; 96 | 97 | #ifdef __cplusplus 98 | } 99 | #endif 100 | -------------------------------------------------------------------------------- /include/clap/factory/plugin-factory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../plugin.h" 4 | 5 | // Use it to retrieve const clap_plugin_factory_t* from 6 | // clap_plugin_entry.get_factory() 7 | static const CLAP_CONSTEXPR char CLAP_PLUGIN_FACTORY_ID[] = "clap.plugin-factory"; 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | // Every method must be thread-safe. 14 | // It is very important to be able to scan the plugin as quickly as possible. 15 | // 16 | // The host may use clap_plugin_invalidation_factory to detect filesystem changes 17 | // which may change the factory's content. 18 | typedef struct clap_plugin_factory { 19 | // Get the number of plugins available. 20 | // [thread-safe] 21 | uint32_t(CLAP_ABI *get_plugin_count)(const struct clap_plugin_factory *factory); 22 | 23 | // Retrieves a plugin descriptor by its index. 24 | // Returns null in case of error. 25 | // The descriptor must not be freed. 26 | // [thread-safe] 27 | const clap_plugin_descriptor_t *(CLAP_ABI *get_plugin_descriptor)( 28 | const struct clap_plugin_factory *factory, uint32_t index); 29 | 30 | // Create a clap_plugin by its plugin_id. 31 | // The returned pointer must be freed by calling plugin->destroy(plugin); 32 | // The plugin is not allowed to use the host callbacks in the create method. 33 | // Returns null in case of error. 34 | // [thread-safe] 35 | const clap_plugin_t *(CLAP_ABI *create_plugin)(const struct clap_plugin_factory *factory, 36 | const clap_host_t *host, 37 | const char *plugin_id); 38 | } clap_plugin_factory_t; 39 | 40 | #ifdef __cplusplus 41 | } 42 | #endif 43 | -------------------------------------------------------------------------------- /include/clap/fixedpoint.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "private/std.h" 4 | #include "private/macros.h" 5 | 6 | /// We use fixed point representation of beat time and seconds time 7 | /// Usage: 8 | /// double x = ...; // in beats 9 | /// clap_beattime y = round(CLAP_BEATTIME_FACTOR * x); 10 | 11 | // This will never change 12 | static const CLAP_CONSTEXPR int64_t CLAP_BEATTIME_FACTOR = 1LL << 31; 13 | static const CLAP_CONSTEXPR int64_t CLAP_SECTIME_FACTOR = 1LL << 31; 14 | 15 | typedef int64_t clap_beattime; 16 | typedef int64_t clap_sectime; 17 | -------------------------------------------------------------------------------- /include/clap/host.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "version.h" 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | typedef struct clap_host { 10 | clap_version_t clap_version; // initialized to CLAP_VERSION 11 | 12 | void *host_data; // reserved pointer for the host 13 | 14 | // name and version are mandatory. 15 | const char *name; // eg: "Bitwig Studio" 16 | const char *vendor; // eg: "Bitwig GmbH" 17 | const char *url; // eg: "https://bitwig.com" 18 | const char *version; // eg: "4.3", see plugin.h for advice on how to format the version 19 | 20 | // Query an extension. 21 | // The returned pointer is owned by the host. 22 | // It is forbidden to call it before plugin->init(). 23 | // You can call it within plugin->init() call, and after. 24 | // [thread-safe] 25 | const void *(CLAP_ABI *get_extension)(const struct clap_host *host, const char *extension_id); 26 | 27 | // Request the host to deactivate and then reactivate the plugin. 28 | // The operation may be delayed by the host. 29 | // [thread-safe] 30 | void(CLAP_ABI *request_restart)(const struct clap_host *host); 31 | 32 | // Request the host to activate and start processing the plugin. 33 | // This is useful if you have external IO and need to wake up the plugin from "sleep". 34 | // [thread-safe] 35 | void(CLAP_ABI *request_process)(const struct clap_host *host); 36 | 37 | // Request the host to schedule a call to plugin->on_main_thread(plugin) on the main thread. 38 | // This callback should be called as soon as practicable, usually in the host application's next 39 | // available main thread time slice. Typically callbacks occur within 33ms / 30hz. 40 | // Despite this guidance, plugins should not make assumptions about the exactness of timing for 41 | // a main thread callback, but hosts should endeavour to be prompt. For example, in high load 42 | // situations the environment may starve the gui/main thread in favor of audio processing, 43 | // leading to substantially longer latencies for the callback than the indicative times given 44 | // here. 45 | // [thread-safe] 46 | void(CLAP_ABI *request_callback)(const struct clap_host *host); 47 | } clap_host_t; 48 | 49 | #ifdef __cplusplus 50 | } 51 | #endif 52 | -------------------------------------------------------------------------------- /include/clap/id.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "private/std.h" 4 | #include "private/macros.h" 5 | 6 | typedef uint32_t clap_id; 7 | 8 | static const CLAP_CONSTEXPR clap_id CLAP_INVALID_ID = UINT32_MAX; 9 | -------------------------------------------------------------------------------- /include/clap/plugin-features.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // This file provides a set of standard plugin features meant to be used 4 | // within clap_plugin_descriptor.features. 5 | // 6 | // For practical reasons we'll avoid spaces and use `-` instead to facilitate 7 | // scripts that generate the feature array. 8 | // 9 | // Non-standard features should be formatted as follow: "$namespace:$feature" 10 | 11 | ///////////////////// 12 | // Plugin category // 13 | ///////////////////// 14 | 15 | // Add this feature if your plugin can process note events and then produce audio 16 | #define CLAP_PLUGIN_FEATURE_INSTRUMENT "instrument" 17 | 18 | // Add this feature if your plugin is an audio effect 19 | #define CLAP_PLUGIN_FEATURE_AUDIO_EFFECT "audio-effect" 20 | 21 | // Add this feature if your plugin is a note effect or a note generator/sequencer 22 | #define CLAP_PLUGIN_FEATURE_NOTE_EFFECT "note-effect" 23 | 24 | // Add this feature if your plugin converts audio to notes 25 | #define CLAP_PLUGIN_FEATURE_NOTE_DETECTOR "note-detector" 26 | 27 | // Add this feature if your plugin is an analyzer 28 | #define CLAP_PLUGIN_FEATURE_ANALYZER "analyzer" 29 | 30 | ///////////////////////// 31 | // Plugin sub-category // 32 | ///////////////////////// 33 | 34 | #define CLAP_PLUGIN_FEATURE_SYNTHESIZER "synthesizer" 35 | #define CLAP_PLUGIN_FEATURE_SAMPLER "sampler" 36 | #define CLAP_PLUGIN_FEATURE_DRUM "drum" // For single drum 37 | #define CLAP_PLUGIN_FEATURE_DRUM_MACHINE "drum-machine" 38 | 39 | #define CLAP_PLUGIN_FEATURE_FILTER "filter" 40 | #define CLAP_PLUGIN_FEATURE_PHASER "phaser" 41 | #define CLAP_PLUGIN_FEATURE_EQUALIZER "equalizer" 42 | #define CLAP_PLUGIN_FEATURE_DEESSER "de-esser" 43 | #define CLAP_PLUGIN_FEATURE_PHASE_VOCODER "phase-vocoder" 44 | #define CLAP_PLUGIN_FEATURE_GRANULAR "granular" 45 | #define CLAP_PLUGIN_FEATURE_FREQUENCY_SHIFTER "frequency-shifter" 46 | #define CLAP_PLUGIN_FEATURE_PITCH_SHIFTER "pitch-shifter" 47 | 48 | #define CLAP_PLUGIN_FEATURE_DISTORTION "distortion" 49 | #define CLAP_PLUGIN_FEATURE_TRANSIENT_SHAPER "transient-shaper" 50 | #define CLAP_PLUGIN_FEATURE_COMPRESSOR "compressor" 51 | #define CLAP_PLUGIN_FEATURE_EXPANDER "expander" 52 | #define CLAP_PLUGIN_FEATURE_GATE "gate" 53 | #define CLAP_PLUGIN_FEATURE_LIMITER "limiter" 54 | 55 | #define CLAP_PLUGIN_FEATURE_FLANGER "flanger" 56 | #define CLAP_PLUGIN_FEATURE_CHORUS "chorus" 57 | #define CLAP_PLUGIN_FEATURE_DELAY "delay" 58 | #define CLAP_PLUGIN_FEATURE_REVERB "reverb" 59 | 60 | #define CLAP_PLUGIN_FEATURE_TREMOLO "tremolo" 61 | #define CLAP_PLUGIN_FEATURE_GLITCH "glitch" 62 | 63 | #define CLAP_PLUGIN_FEATURE_UTILITY "utility" 64 | #define CLAP_PLUGIN_FEATURE_PITCH_CORRECTION "pitch-correction" 65 | #define CLAP_PLUGIN_FEATURE_RESTORATION "restoration" // repair the sound 66 | 67 | #define CLAP_PLUGIN_FEATURE_MULTI_EFFECTS "multi-effects" 68 | 69 | #define CLAP_PLUGIN_FEATURE_MIXING "mixing" 70 | #define CLAP_PLUGIN_FEATURE_MASTERING "mastering" 71 | 72 | //////////////////////// 73 | // Audio Capabilities // 74 | //////////////////////// 75 | 76 | #define CLAP_PLUGIN_FEATURE_MONO "mono" 77 | #define CLAP_PLUGIN_FEATURE_STEREO "stereo" 78 | #define CLAP_PLUGIN_FEATURE_SURROUND "surround" 79 | #define CLAP_PLUGIN_FEATURE_AMBISONIC "ambisonic" 80 | -------------------------------------------------------------------------------- /include/clap/plugin.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "private/macros.h" 4 | #include "host.h" 5 | #include "process.h" 6 | #include "plugin-features.h" 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | typedef struct clap_plugin_descriptor { 13 | clap_version_t clap_version; // initialized to CLAP_VERSION 14 | 15 | // Mandatory fields must be set and must not be blank. 16 | // Otherwise the fields can be null or blank, though it is safer to make them blank. 17 | // 18 | // Some indications regarding id and version 19 | // - id is an arbitrary string which should be unique to your plugin, 20 | // we encourage you to use a reverse URI eg: "com.u-he.diva" 21 | // - version is an arbitrary string which describes a plugin, 22 | // it is useful for the host to understand and be able to compare two different 23 | // version strings, so here is a regex like expression which is likely to be 24 | // understood by most hosts: MAJOR(.MINOR(.REVISION)?)?( (Alpha|Beta) XREV)? 25 | const char *id; // eg: "com.u-he.diva", mandatory 26 | const char *name; // eg: "Diva", mandatory 27 | const char *vendor; // eg: "u-he" 28 | const char *url; // eg: "https://u-he.com/products/diva/" 29 | const char *manual_url; // eg: "https://dl.u-he.com/manuals/plugins/diva/Diva-user-guide.pdf" 30 | const char *support_url; // eg: "https://u-he.com/support/" 31 | const char *version; // eg: "1.4.4" 32 | const char *description; // eg: "The spirit of analogue" 33 | 34 | // Arbitrary list of keywords. 35 | // They can be matched by the host indexer and used to classify the plugin. 36 | // The array of pointers must be null terminated. 37 | // For some standard features see plugin-features.h 38 | const char *const *features; 39 | } clap_plugin_descriptor_t; 40 | 41 | typedef struct clap_plugin { 42 | const clap_plugin_descriptor_t *desc; 43 | 44 | void *plugin_data; // reserved pointer for the plugin 45 | 46 | // Must be called after creating the plugin. 47 | // If init returns false, the host must destroy the plugin instance. 48 | // If init returns true, then the plugin is initialized and in the deactivated state. 49 | // Unlike in `plugin-factory::create_plugin`, in init you have complete access to the host 50 | // and host extensions, so clap related setup activities should be done here rather than in 51 | // create_plugin. 52 | // [main-thread] 53 | bool(CLAP_ABI *init)(const struct clap_plugin *plugin); 54 | 55 | // Free the plugin and its resources. 56 | // It is required to deactivate the plugin prior to this call. 57 | // [main-thread & !active] 58 | void(CLAP_ABI *destroy)(const struct clap_plugin *plugin); 59 | 60 | // Activate and deactivate the plugin. 61 | // In this call the plugin may allocate memory and prepare everything needed for the process 62 | // call. The process's sample rate will be constant and process's frame count will included in 63 | // the [min, max] range, which is bounded by [1, INT32_MAX]. 64 | // In this call the plugin may call host-provided methods marked [being-activated]. 65 | // Once activated the latency and port configuration must remain constant, until deactivation. 66 | // Returns true on success. 67 | // [main-thread & !active] 68 | bool(CLAP_ABI *activate)(const struct clap_plugin *plugin, 69 | double sample_rate, 70 | uint32_t min_frames_count, 71 | uint32_t max_frames_count); 72 | // [main-thread & active] 73 | void(CLAP_ABI *deactivate)(const struct clap_plugin *plugin); 74 | 75 | // Call start processing before processing. 76 | // Returns true on success. 77 | // [audio-thread & active & !processing] 78 | bool(CLAP_ABI *start_processing)(const struct clap_plugin *plugin); 79 | 80 | // Call stop processing before sending the plugin to sleep. 81 | // [audio-thread & active & processing] 82 | void(CLAP_ABI *stop_processing)(const struct clap_plugin *plugin); 83 | 84 | // - Clears all buffers, performs a full reset of the processing state (filters, oscillators, 85 | // envelopes, lfo, ...) and kills all voices. 86 | // - The parameter's value remain unchanged. 87 | // - clap_process.steady_time may jump backward. 88 | // 89 | // [audio-thread & active] 90 | void(CLAP_ABI *reset)(const struct clap_plugin *plugin); 91 | 92 | // process audio, events, ... 93 | // All the pointers coming from clap_process_t and its nested attributes, 94 | // are valid until process() returns. 95 | // [audio-thread & active & processing] 96 | clap_process_status(CLAP_ABI *process)(const struct clap_plugin *plugin, 97 | const clap_process_t *process); 98 | 99 | // Query an extension. 100 | // The returned pointer is owned by the plugin. 101 | // It is forbidden to call it before plugin->init(). 102 | // You can call it within plugin->init() call, and after. 103 | // [thread-safe] 104 | const void *(CLAP_ABI *get_extension)(const struct clap_plugin *plugin, const char *id); 105 | 106 | // Called by the host on the main thread in response to a previous call to: 107 | // host->request_callback(host); 108 | // [main-thread] 109 | void(CLAP_ABI *on_main_thread)(const struct clap_plugin *plugin); 110 | } clap_plugin_t; 111 | 112 | #ifdef __cplusplus 113 | } 114 | #endif 115 | -------------------------------------------------------------------------------- /include/clap/private/macros.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Define CLAP_EXPORT 4 | #if !defined(CLAP_EXPORT) 5 | # if defined _WIN32 || defined __CYGWIN__ 6 | # ifdef __GNUC__ 7 | # define CLAP_EXPORT __attribute__((dllexport)) 8 | # else 9 | # define CLAP_EXPORT __declspec(dllexport) 10 | # endif 11 | # else 12 | # if __GNUC__ >= 4 || defined(__clang__) 13 | # define CLAP_EXPORT __attribute__((visibility("default"))) 14 | # else 15 | # define CLAP_EXPORT 16 | # endif 17 | # endif 18 | #endif 19 | 20 | #if !defined(CLAP_ABI) 21 | # if defined _WIN32 || defined __CYGWIN__ 22 | # define CLAP_ABI __cdecl 23 | # else 24 | # define CLAP_ABI 25 | # endif 26 | #endif 27 | 28 | #if defined(_MSVC_LANG) 29 | # define CLAP_CPLUSPLUS _MSVC_LANG 30 | #elif defined(__cplusplus) 31 | # define CLAP_CPLUSPLUS __cplusplus 32 | #endif 33 | 34 | #if defined(CLAP_CPLUSPLUS) && CLAP_CPLUSPLUS >= 201103L 35 | # define CLAP_HAS_CXX11 36 | # define CLAP_CONSTEXPR constexpr 37 | #else 38 | # define CLAP_CONSTEXPR 39 | #endif 40 | 41 | #if defined(CLAP_CPLUSPLUS) && CLAP_CPLUSPLUS >= 201703L 42 | # define CLAP_HAS_CXX17 43 | # define CLAP_NODISCARD [[nodiscard]] 44 | #else 45 | # define CLAP_NODISCARD 46 | #endif 47 | 48 | #if defined(CLAP_CPLUSPLUS) && CLAP_CPLUSPLUS >= 202002L 49 | # define CLAP_HAS_CXX20 50 | #endif 51 | -------------------------------------------------------------------------------- /include/clap/private/std.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "macros.h" 4 | 5 | #ifdef CLAP_HAS_CXX11 6 | # include 7 | #else 8 | # include 9 | #endif 10 | 11 | #ifdef __cplusplus 12 | # include 13 | #else 14 | # include 15 | # include 16 | #endif 17 | -------------------------------------------------------------------------------- /include/clap/process.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "events.h" 4 | #include "audio-buffer.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | enum { 11 | // Processing failed. The output buffer must be discarded. 12 | CLAP_PROCESS_ERROR = 0, 13 | 14 | // Processing succeeded, keep processing. 15 | CLAP_PROCESS_CONTINUE = 1, 16 | 17 | // Processing succeeded, keep processing if the output is not quiet. 18 | CLAP_PROCESS_CONTINUE_IF_NOT_QUIET = 2, 19 | 20 | // Rely upon the plugin's tail to determine if the plugin should continue to process. 21 | // see clap_plugin_tail 22 | CLAP_PROCESS_TAIL = 3, 23 | 24 | // Processing succeeded, but no more processing is required, 25 | // until the next event or variation in audio input. 26 | CLAP_PROCESS_SLEEP = 4, 27 | }; 28 | typedef int32_t clap_process_status; 29 | 30 | typedef struct clap_process { 31 | // A steady sample time counter. 32 | // This field can be used to calculate the sleep duration between two process calls. 33 | // This value may be specific to this plugin instance and have no relation to what 34 | // other plugin instances may receive. 35 | // 36 | // Set to -1 if not available, otherwise the value must be greater or equal to 0, 37 | // and must be increased by at least `frames_count` for the next call to process. 38 | int64_t steady_time; 39 | 40 | // Number of frames to process 41 | uint32_t frames_count; 42 | 43 | // time info at sample 0 44 | // If null, then this is a free running host, no transport events will be provided 45 | const clap_event_transport_t *transport; 46 | 47 | // Audio buffers, they must have the same count as specified 48 | // by clap_plugin_audio_ports->count(). 49 | // The index maps to clap_plugin_audio_ports->get(). 50 | // Input buffer and its contents are read-only. 51 | const clap_audio_buffer_t *audio_inputs; 52 | clap_audio_buffer_t *audio_outputs; 53 | uint32_t audio_inputs_count; 54 | uint32_t audio_outputs_count; 55 | 56 | // The input event list can't be modified. 57 | // Input read-only event list. The host will deliver these sorted in sample order. 58 | const clap_input_events_t *in_events; 59 | 60 | // Output event list. The plugin must insert events in sample sorted order when inserting events 61 | const clap_output_events_t *out_events; 62 | } clap_process_t; 63 | 64 | #ifdef __cplusplus 65 | } 66 | #endif 67 | -------------------------------------------------------------------------------- /include/clap/stream.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "private/std.h" 4 | #include "private/macros.h" 5 | 6 | /// @page Streams 7 | /// 8 | /// ## Notes on using streams 9 | /// 10 | /// When working with `clap_istream` and `clap_ostream` objects to load and save 11 | /// state, it is important to keep in mind that the host may limit the number of 12 | /// bytes that can be read or written at a time. The return values for the 13 | /// stream read and write functions indicate how many bytes were actually read 14 | /// or written. You need to use a loop to ensure that you read or write the 15 | /// entirety of your state. Don't forget to also consider the negative return 16 | /// values for the end of file and IO error codes. 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | typedef struct clap_istream { 23 | void *ctx; // reserved pointer for the stream 24 | 25 | // returns the number of bytes read; 0 indicates end of file and -1 a read error 26 | int64_t(CLAP_ABI *read)(const struct clap_istream *stream, void *buffer, uint64_t size); 27 | } clap_istream_t; 28 | 29 | typedef struct clap_ostream { 30 | void *ctx; // reserved pointer for the stream 31 | 32 | // returns the number of bytes written; -1 on write error 33 | int64_t(CLAP_ABI *write)(const struct clap_ostream *stream, const void *buffer, uint64_t size); 34 | } clap_ostream_t; 35 | 36 | #ifdef __cplusplus 37 | } 38 | #endif 39 | -------------------------------------------------------------------------------- /include/clap/string-sizes.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | enum { 8 | // String capacity for names that can be displayed to the user. 9 | CLAP_NAME_SIZE = 256, 10 | 11 | // String capacity for describing a path, like a parameter in a module hierarchy or path within a 12 | // set of nested track groups. 13 | // 14 | // This is not suited for describing a file path on the disk, as NTFS allows up to 32K long 15 | // paths. 16 | CLAP_PATH_SIZE = 1024, 17 | }; 18 | 19 | #ifdef __cplusplus 20 | } 21 | #endif 22 | -------------------------------------------------------------------------------- /include/clap/timestamp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "private/std.h" 4 | #include "private/macros.h" 5 | 6 | // This type defines a timestamp: the number of seconds since UNIX EPOCH. 7 | // See C's time_t time(time_t *). 8 | typedef uint64_t clap_timestamp; 9 | 10 | // Value for unknown timestamp. 11 | static const CLAP_CONSTEXPR clap_timestamp CLAP_TIMESTAMP_UNKNOWN = 0; 12 | -------------------------------------------------------------------------------- /include/clap/universal-plugin-id.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Pair of plugin ABI and plugin identifier. 4 | // 5 | // If you want to represent other formats please send us an update to the comment with the 6 | // name of the abi and the representation of the id. 7 | typedef struct clap_universal_plugin_id { 8 | // The plugin ABI name, in lowercase and null-terminated. 9 | // eg: "clap", "vst3", "vst2", "au", ... 10 | const char *abi; 11 | 12 | // The plugin ID, null-terminated and formatted as follows: 13 | // 14 | // CLAP: use the plugin id 15 | // eg: "com.u-he.diva" 16 | // 17 | // AU: format the string like "type:subt:manu" 18 | // eg: "aumu:SgXT:VmbA" 19 | // 20 | // VST2: print the id as a signed 32-bits integer 21 | // eg: "-4382976" 22 | // 23 | // VST3: print the id as a standard UUID 24 | // eg: "123e4567-e89b-12d3-a456-426614174000" 25 | const char *id; 26 | } clap_universal_plugin_id_t; 27 | -------------------------------------------------------------------------------- /include/clap/version.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "private/macros.h" 4 | #include "private/std.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | typedef struct clap_version { 11 | // This is the major ABI and API design 12 | // Version 0.X.Y correspond to the development stage, API and ABI are not stable 13 | // Version 1.X.Y correspond to the release stage, API and ABI are stable 14 | uint32_t major; 15 | uint32_t minor; 16 | uint32_t revision; 17 | } clap_version_t; 18 | 19 | #ifdef __cplusplus 20 | } 21 | #endif 22 | 23 | #define CLAP_VERSION_MAJOR 1 24 | #define CLAP_VERSION_MINOR 2 25 | #define CLAP_VERSION_REVISION 6 26 | 27 | #define CLAP_VERSION_INIT \ 28 | { (uint32_t)CLAP_VERSION_MAJOR, (uint32_t)CLAP_VERSION_MINOR, (uint32_t)CLAP_VERSION_REVISION } 29 | 30 | #define CLAP_VERSION_LT(maj,min,rev) ((CLAP_VERSION_MAJOR < (maj)) || \ 31 | ((maj) == CLAP_VERSION_MAJOR && CLAP_VERSION_MINOR < (min)) || \ 32 | ((maj) == CLAP_VERSION_MAJOR && (min) == CLAP_VERSION_MINOR && CLAP_VERSION_REVISION < (rev))) 33 | #define CLAP_VERSION_EQ(maj,min,rev) (((maj) == CLAP_VERSION_MAJOR) && ((min) == CLAP_VERSION_MINOR) && ((rev) == CLAP_VERSION_REVISION)) 34 | #define CLAP_VERSION_GE(maj,min,rev) (!CLAP_VERSION_LT(maj,min,rev)) 35 | 36 | static const CLAP_CONSTEXPR clap_version_t CLAP_VERSION = CLAP_VERSION_INIT; 37 | 38 | CLAP_NODISCARD static inline CLAP_CONSTEXPR bool 39 | clap_version_is_compatible(const clap_version_t v) { 40 | // versions 0.x.y were used during development stage and aren't compatible 41 | return v.major >= 1; 42 | } 43 | -------------------------------------------------------------------------------- /src/linux-my_plug.version: -------------------------------------------------------------------------------- 1 | MY_PLUG_ABI_1.0 { 2 | global: 3 | clap_entry; 4 | local: 5 | *; 6 | }; 7 | -------------------------------------------------------------------------------- /src/macos-symbols.txt: -------------------------------------------------------------------------------- 1 | _clap_entry 2 | -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // The purpose of this file is to check that all headers compile 4 | int main(int argc, char **argv) { 5 | (void)argc; 6 | (void)argv; 7 | const clap_version_t m = CLAP_VERSION; 8 | return !clap_version_is_compatible(m); 9 | } 10 | -------------------------------------------------------------------------------- /src/main.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // The purpose of this file is to check that all headers compile 4 | 5 | #if CLAP_VERSION_LT(CLAP_VERSION_MAJOR, CLAP_VERSION_MINOR, CLAP_VERSION_REVISION) 6 | #error CLAP_VERSION_LT is inconsistent 7 | #endif 8 | 9 | #if !CLAP_VERSION_EQ(CLAP_VERSION_MAJOR, CLAP_VERSION_MINOR, CLAP_VERSION_REVISION) 10 | #error CLAP_VERSION_EQ is inconsistent 11 | #endif 12 | 13 | #if CLAP_VERSION_EQ(CLAP_VERSION_MAJOR + 1, CLAP_VERSION_MINOR, CLAP_VERSION_REVISION) 14 | #error CLAP_VERSION_EQ is inconsistent (MAJOR) 15 | #endif 16 | #if CLAP_VERSION_EQ(CLAP_VERSION_MAJOR, CLAP_VERSION_MINOR + 1, CLAP_VERSION_REVISION) 17 | #error CLAP_VERSION_EQ is inconsistent (MINOR) 18 | #endif 19 | #if CLAP_VERSION_EQ(CLAP_VERSION_MAJOR, CLAP_VERSION_MINOR, CLAP_VERSION_REVISION + 1) 20 | #error CLAP_VERSION_EQ is inconsistent (REVISION) 21 | #endif 22 | 23 | #if !CLAP_VERSION_GE(CLAP_VERSION_MAJOR, CLAP_VERSION_MINOR, CLAP_VERSION_REVISION) 24 | #error CLAP_VERSION_GE is inconsistent 25 | #endif 26 | 27 | #if CLAP_VERSION_LT(1,1,5) 28 | #error CLAP_VERSION_GE was inroduced in 1.1.5 so we should be later than that version. 29 | #endif 30 | 31 | #if !CLAP_VERSION_LT(CLAP_VERSION_MAJOR + 1, CLAP_VERSION_MINOR, CLAP_VERSION_REVISION) 32 | #error CLAP_VERSION_LT is inconsistent (MAJOR) 33 | #endif 34 | #if !CLAP_VERSION_LT(CLAP_VERSION_MAJOR, CLAP_VERSION_MINOR + 1, CLAP_VERSION_REVISION) 35 | #error CLAP_VERSION_LT is inconsistent (MINOR) 36 | #endif 37 | #if !CLAP_VERSION_LT(CLAP_VERSION_MAJOR, CLAP_VERSION_MINOR, CLAP_VERSION_REVISION + 1) 38 | #error CLAP_VERSION_LT is inconsistent (REVISION) 39 | #endif 40 | 41 | #if CLAP_VERSION_LT(CLAP_VERSION_MAJOR - 1, CLAP_VERSION_MINOR, CLAP_VERSION_REVISION) 42 | #error CLAP_VERSION_LT is inconsistent (MAJOR) 43 | #endif 44 | #if CLAP_VERSION_LT(CLAP_VERSION_MAJOR, CLAP_VERSION_MINOR - 1, CLAP_VERSION_REVISION) 45 | #error CLAP_VERSION_LT is inconsistent (MINOR) 46 | #endif 47 | #if CLAP_VERSION_LT(CLAP_VERSION_MAJOR, CLAP_VERSION_MINOR, CLAP_VERSION_REVISION - 1) 48 | #error CLAP_VERSION_LT is inconsistent (REVISION) 49 | #endif 50 | 51 | #if (CLAP_COMPILE_TEST_CXX_VERSION >= 11) && ! defined(CLAP_HAS_CXX11) 52 | #error CLAP_HAS_CXX11 is not defined correctly 53 | #endif 54 | 55 | #if (CLAP_COMPILE_TEST_CXX_VERSION >= 17) && ! defined(CLAP_HAS_CXX17) 56 | #error CLAP_HAS_CXX17 is not defined correctly 57 | #endif 58 | 59 | #if (CLAP_COMPILE_TEST_CXX_VERSION >= 20) && ! defined(CLAP_HAS_CXX20) 60 | #error CLAP_HAS_CXX20 is not defined correctly 61 | #endif 62 | 63 | static const CLAP_CONSTEXPR clap_version m = CLAP_VERSION; 64 | 65 | int main(int, char **) { 66 | return !clap_version_is_compatible(m); 67 | } 68 | -------------------------------------------------------------------------------- /src/plugin-template.c: -------------------------------------------------------------------------------- 1 | // This file is here to demonstrate how to wire a CLAP plugin 2 | // You can use it as a starting point, however if you are implementing a C++ 3 | // plugin, I'd encourage you to use the C++ glue layer instead: 4 | // https://github.com/free-audio/clap-helpers/blob/main/include/clap/helpers/plugin.hh 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #if __STDC_VERSION__ >= 201112L && !defined (__STDC_NO_THREADS__) && defined (CLAP_HAS_THREADS_H) 12 | # define CLAP_HAS_THREAD 13 | # include 14 | #endif 15 | 16 | #include 17 | 18 | static const clap_plugin_descriptor_t s_my_plug_desc = { 19 | .clap_version = CLAP_VERSION_INIT, 20 | .id = "com.your-company.YourPlugin", 21 | .name = "Plugin Name", 22 | .vendor = "Vendor", 23 | .url = "https://your-domain.com/your-plugin", 24 | .manual_url = "https://your-domain.com/your-plugin/manual", 25 | .support_url = "https://your-domain.com/support", 26 | .version = "1.4.2", 27 | .description = "The plugin description.", 28 | .features = (const char *[]){CLAP_PLUGIN_FEATURE_INSTRUMENT, CLAP_PLUGIN_FEATURE_STEREO, NULL}, 29 | }; 30 | 31 | typedef struct { 32 | clap_plugin_t plugin; 33 | const clap_host_t *host; 34 | const clap_host_latency_t *host_latency; 35 | const clap_host_log_t *host_log; 36 | const clap_host_thread_check_t *host_thread_check; 37 | const clap_host_state_t *host_state; 38 | 39 | uint32_t latency; 40 | } my_plug_t; 41 | 42 | ///////////////////////////// 43 | // clap_plugin_audio_ports // 44 | ///////////////////////////// 45 | 46 | static uint32_t my_plug_audio_ports_count(const clap_plugin_t *plugin, bool is_input) { 47 | // We just declare 1 audio input and 1 audio output 48 | return 1; 49 | } 50 | 51 | static bool my_plug_audio_ports_get(const clap_plugin_t *plugin, 52 | uint32_t index, 53 | bool is_input, 54 | clap_audio_port_info_t *info) { 55 | if (index > 0) 56 | return false; 57 | info->id = 0; 58 | snprintf(info->name, sizeof(info->name), "%s", "My Port Name"); 59 | info->channel_count = 2; 60 | info->flags = CLAP_AUDIO_PORT_IS_MAIN; 61 | info->port_type = CLAP_PORT_STEREO; 62 | info->in_place_pair = CLAP_INVALID_ID; 63 | return true; 64 | } 65 | 66 | static const clap_plugin_audio_ports_t s_my_plug_audio_ports = { 67 | .count = my_plug_audio_ports_count, 68 | .get = my_plug_audio_ports_get, 69 | }; 70 | 71 | //////////////////////////// 72 | // clap_plugin_note_ports // 73 | //////////////////////////// 74 | 75 | static uint32_t my_plug_note_ports_count(const clap_plugin_t *plugin, bool is_input) { 76 | // We just declare 1 note input 77 | return 1; 78 | } 79 | 80 | static bool my_plug_note_ports_get(const clap_plugin_t *plugin, 81 | uint32_t index, 82 | bool is_input, 83 | clap_note_port_info_t *info) { 84 | if (index > 0) 85 | return false; 86 | info->id = 0; 87 | snprintf(info->name, sizeof(info->name), "%s", "My Port Name"); 88 | info->supported_dialects = 89 | CLAP_NOTE_DIALECT_CLAP | CLAP_NOTE_DIALECT_MIDI_MPE | CLAP_NOTE_DIALECT_MIDI2; 90 | info->preferred_dialect = CLAP_NOTE_DIALECT_CLAP; 91 | return true; 92 | } 93 | 94 | static const clap_plugin_note_ports_t s_my_plug_note_ports = { 95 | .count = my_plug_note_ports_count, 96 | .get = my_plug_note_ports_get, 97 | }; 98 | 99 | ////////////////// 100 | // clap_latency // 101 | ////////////////// 102 | 103 | uint32_t my_plug_latency_get(const clap_plugin_t *plugin) { 104 | my_plug_t *plug = plugin->plugin_data; 105 | return plug->latency; 106 | } 107 | 108 | static const clap_plugin_latency_t s_my_plug_latency = { 109 | .get = my_plug_latency_get, 110 | }; 111 | 112 | //////////////// 113 | // clap_state // 114 | //////////////// 115 | 116 | bool my_plug_state_save(const clap_plugin_t *plugin, const clap_ostream_t *stream) { 117 | my_plug_t *plug = plugin->plugin_data; 118 | // TODO: write the state into stream 119 | return true; 120 | } 121 | 122 | bool my_plug_state_load(const clap_plugin_t *plugin, const clap_istream_t *stream) { 123 | my_plug_t *plug = plugin->plugin_data; 124 | // TODO: read the state from stream 125 | return true; 126 | } 127 | 128 | static const clap_plugin_state_t s_my_plug_state = { 129 | .save = my_plug_state_save, 130 | .load = my_plug_state_load, 131 | }; 132 | 133 | ///////////////// 134 | // clap_plugin // 135 | ///////////////// 136 | 137 | static bool my_plug_init(const struct clap_plugin *plugin) { 138 | my_plug_t *plug = plugin->plugin_data; 139 | 140 | // Fetch host's extensions here 141 | // Make sure to check that the interface functions are not null pointers 142 | plug->host_log = (const clap_host_log_t *)plug->host->get_extension(plug->host, CLAP_EXT_LOG); 143 | plug->host_thread_check = (const clap_host_thread_check_t *)plug->host->get_extension(plug->host, CLAP_EXT_THREAD_CHECK); 144 | plug->host_latency = (const clap_host_latency_t *)plug->host->get_extension(plug->host, CLAP_EXT_LATENCY); 145 | plug->host_state = (const clap_host_state_t *)plug->host->get_extension(plug->host, CLAP_EXT_STATE); 146 | return true; 147 | } 148 | 149 | static void my_plug_destroy(const struct clap_plugin *plugin) { 150 | my_plug_t *plug = plugin->plugin_data; 151 | free(plug); 152 | } 153 | 154 | static bool my_plug_activate(const struct clap_plugin *plugin, 155 | double sample_rate, 156 | uint32_t min_frames_count, 157 | uint32_t max_frames_count) { 158 | return true; 159 | } 160 | 161 | static void my_plug_deactivate(const struct clap_plugin *plugin) {} 162 | 163 | static bool my_plug_start_processing(const struct clap_plugin *plugin) { return true; } 164 | 165 | static void my_plug_stop_processing(const struct clap_plugin *plugin) {} 166 | 167 | static void my_plug_reset(const struct clap_plugin *plugin) {} 168 | 169 | static void my_plug_process_event(my_plug_t *plug, const clap_event_header_t *hdr) { 170 | if (hdr->space_id == CLAP_CORE_EVENT_SPACE_ID) { 171 | switch (hdr->type) { 172 | case CLAP_EVENT_NOTE_ON: { 173 | const clap_event_note_t *ev = (const clap_event_note_t *)hdr; 174 | // TODO: handle note on 175 | break; 176 | } 177 | 178 | case CLAP_EVENT_NOTE_OFF: { 179 | const clap_event_note_t *ev = (const clap_event_note_t *)hdr; 180 | // TODO: handle note off 181 | break; 182 | } 183 | 184 | case CLAP_EVENT_NOTE_CHOKE: { 185 | const clap_event_note_t *ev = (const clap_event_note_t *)hdr; 186 | // TODO: handle note choke 187 | break; 188 | } 189 | 190 | case CLAP_EVENT_NOTE_EXPRESSION: { 191 | const clap_event_note_expression_t *ev = (const clap_event_note_expression_t *)hdr; 192 | // TODO: handle note expression 193 | break; 194 | } 195 | 196 | case CLAP_EVENT_PARAM_VALUE: { 197 | const clap_event_param_value_t *ev = (const clap_event_param_value_t *)hdr; 198 | // TODO: handle parameter change 199 | break; 200 | } 201 | 202 | case CLAP_EVENT_PARAM_MOD: { 203 | const clap_event_param_mod_t *ev = (const clap_event_param_mod_t *)hdr; 204 | // TODO: handle parameter modulation 205 | break; 206 | } 207 | 208 | case CLAP_EVENT_TRANSPORT: { 209 | const clap_event_transport_t *ev = (const clap_event_transport_t *)hdr; 210 | // TODO: handle transport event 211 | break; 212 | } 213 | 214 | case CLAP_EVENT_MIDI: { 215 | const clap_event_midi_t *ev = (const clap_event_midi_t *)hdr; 216 | // TODO: handle MIDI event 217 | break; 218 | } 219 | 220 | case CLAP_EVENT_MIDI_SYSEX: { 221 | const clap_event_midi_sysex_t *ev = (const clap_event_midi_sysex_t *)hdr; 222 | // TODO: handle MIDI Sysex event 223 | break; 224 | } 225 | 226 | case CLAP_EVENT_MIDI2: { 227 | const clap_event_midi2_t *ev = (const clap_event_midi2_t *)hdr; 228 | // TODO: handle MIDI2 event 229 | break; 230 | } 231 | } 232 | } 233 | } 234 | 235 | static clap_process_status my_plug_process(const struct clap_plugin *plugin, 236 | const clap_process_t *process) { 237 | my_plug_t *plug = plugin->plugin_data; 238 | const uint32_t nframes = process->frames_count; 239 | const uint32_t nev = process->in_events->size(process->in_events); 240 | uint32_t ev_index = 0; 241 | uint32_t next_ev_frame = nev > 0 ? 0 : nframes; 242 | 243 | for (uint32_t i = 0; i < nframes;) { 244 | /* handle every events that happrens at the frame "i" */ 245 | while (ev_index < nev && next_ev_frame == i) { 246 | const clap_event_header_t *hdr = process->in_events->get(process->in_events, ev_index); 247 | if (hdr->time != i) { 248 | next_ev_frame = hdr->time; 249 | break; 250 | } 251 | 252 | my_plug_process_event(plug, hdr); 253 | ++ev_index; 254 | 255 | if (ev_index == nev) { 256 | // we reached the end of the event list 257 | next_ev_frame = nframes; 258 | break; 259 | } 260 | } 261 | 262 | /* process every samples until the next event */ 263 | for (; i < next_ev_frame; ++i) { 264 | // fetch input samples 265 | const float in_l = process->audio_inputs[0].data32[0][i]; 266 | const float in_r = process->audio_inputs[0].data32[1][i]; 267 | 268 | /* TODO: process samples, here we simply swap left and right channels */ 269 | const float out_l = in_r; 270 | const float out_r = in_l; 271 | 272 | // store output samples 273 | process->audio_outputs[0].data32[0][i] = out_l; 274 | process->audio_outputs[0].data32[1][i] = out_r; 275 | } 276 | } 277 | 278 | return CLAP_PROCESS_CONTINUE; 279 | } 280 | 281 | static const void *my_plug_get_extension(const struct clap_plugin *plugin, const char *id) { 282 | if (!strcmp(id, CLAP_EXT_LATENCY)) 283 | return &s_my_plug_latency; 284 | if (!strcmp(id, CLAP_EXT_AUDIO_PORTS)) 285 | return &s_my_plug_audio_ports; 286 | if (!strcmp(id, CLAP_EXT_NOTE_PORTS)) 287 | return &s_my_plug_note_ports; 288 | if (!strcmp(id, CLAP_EXT_STATE)) 289 | return &s_my_plug_state; 290 | // TODO: add support to CLAP_EXT_PARAMS 291 | return NULL; 292 | } 293 | 294 | static void my_plug_on_main_thread(const struct clap_plugin *plugin) {} 295 | 296 | clap_plugin_t *my_plug_create(const clap_host_t *host) { 297 | my_plug_t *p = calloc(1, sizeof(*p)); 298 | p->host = host; 299 | p->plugin.desc = &s_my_plug_desc; 300 | p->plugin.plugin_data = p; 301 | p->plugin.init = my_plug_init; 302 | p->plugin.destroy = my_plug_destroy; 303 | p->plugin.activate = my_plug_activate; 304 | p->plugin.deactivate = my_plug_deactivate; 305 | p->plugin.start_processing = my_plug_start_processing; 306 | p->plugin.stop_processing = my_plug_stop_processing; 307 | p->plugin.reset = my_plug_reset; 308 | p->plugin.process = my_plug_process; 309 | p->plugin.get_extension = my_plug_get_extension; 310 | p->plugin.on_main_thread = my_plug_on_main_thread; 311 | 312 | // Don't call into the host here 313 | 314 | return &p->plugin; 315 | } 316 | 317 | ///////////////////////// 318 | // clap_plugin_factory // 319 | ///////////////////////// 320 | 321 | static struct { 322 | const clap_plugin_descriptor_t *desc; 323 | clap_plugin_t *(CLAP_ABI *create)(const clap_host_t *host); 324 | } s_plugins[] = { 325 | { 326 | .desc = &s_my_plug_desc, 327 | .create = my_plug_create, 328 | }, 329 | }; 330 | 331 | static uint32_t plugin_factory_get_plugin_count(const struct clap_plugin_factory *factory) { 332 | return sizeof(s_plugins) / sizeof(s_plugins[0]); 333 | } 334 | 335 | static const clap_plugin_descriptor_t * 336 | plugin_factory_get_plugin_descriptor(const struct clap_plugin_factory *factory, uint32_t index) { 337 | return s_plugins[index].desc; 338 | } 339 | 340 | static const clap_plugin_t *plugin_factory_create_plugin(const struct clap_plugin_factory *factory, 341 | const clap_host_t *host, 342 | const char *plugin_id) { 343 | if (!clap_version_is_compatible(host->clap_version)) { 344 | return NULL; 345 | } 346 | 347 | const int N = sizeof(s_plugins) / sizeof(s_plugins[0]); 348 | for (int i = 0; i < N; ++i) 349 | if (!strcmp(plugin_id, s_plugins[i].desc->id)) 350 | return s_plugins[i].create(host); 351 | 352 | return NULL; 353 | } 354 | 355 | static const clap_plugin_factory_t s_plugin_factory = { 356 | .get_plugin_count = plugin_factory_get_plugin_count, 357 | .get_plugin_descriptor = plugin_factory_get_plugin_descriptor, 358 | .create_plugin = plugin_factory_create_plugin, 359 | }; 360 | 361 | //////////////// 362 | // clap_entry // 363 | //////////////// 364 | 365 | static bool entry_init(const char *plugin_path) { 366 | // perform the plugin initialization 367 | return true; 368 | } 369 | 370 | static void entry_deinit(void) { 371 | // perform the plugin de-initialization 372 | } 373 | 374 | #ifdef CLAP_HAS_THREAD 375 | static mtx_t g_entry_lock; 376 | static once_flag g_entry_once = ONCE_FLAG_INIT; 377 | #endif 378 | 379 | static int g_entry_init_counter = 0; 380 | 381 | #ifdef CLAP_HAS_THREAD 382 | // Initializes the necessary mutex for the entry guard 383 | static void entry_init_guard_init(void) { 384 | mtx_init(&g_entry_lock, mtx_plain); 385 | } 386 | #endif 387 | 388 | // Thread safe init counter 389 | static bool entry_init_guard(const char *plugin_path) { 390 | #ifdef CLAP_HAS_THREAD 391 | call_once(&g_entry_once, entry_init_guard_init); 392 | 393 | mtx_lock(&g_entry_lock); 394 | #endif 395 | 396 | const int cnt = ++g_entry_init_counter; 397 | assert(cnt > 0); 398 | 399 | bool succeed = true; 400 | if (cnt == 1) { 401 | succeed = entry_init(plugin_path); 402 | if (!succeed) 403 | g_entry_init_counter = 0; 404 | } 405 | 406 | #ifdef CLAP_HAS_THREAD 407 | mtx_unlock(&g_entry_lock); 408 | #endif 409 | 410 | return succeed; 411 | } 412 | 413 | // Thread safe deinit counter 414 | static void entry_deinit_guard(void) { 415 | #ifdef CLAP_HAS_THREAD 416 | call_once(&g_entry_once, entry_init_guard_init); 417 | 418 | mtx_lock(&g_entry_lock); 419 | #endif 420 | 421 | const int cnt = --g_entry_init_counter; 422 | assert(cnt >= 0); 423 | 424 | bool succeed = true; 425 | if (cnt == 0) 426 | entry_deinit(); 427 | 428 | #ifdef CLAP_HAS_THREAD 429 | mtx_unlock(&g_entry_lock); 430 | #endif 431 | } 432 | 433 | static const void *entry_get_factory(const char *factory_id) { 434 | #ifdef CLAP_HAS_THREAD 435 | call_once(&g_entry_once, entry_init_guard_init); 436 | #endif 437 | 438 | assert(g_entry_init_counter > 0); 439 | if (g_entry_init_counter <= 0) 440 | return NULL; 441 | 442 | if (!strcmp(factory_id, CLAP_PLUGIN_FACTORY_ID)) 443 | return &s_plugin_factory; 444 | return NULL; 445 | } 446 | 447 | // This symbol will be resolved by the host 448 | CLAP_EXPORT const clap_plugin_entry_t clap_entry = { 449 | .clap_version = CLAP_VERSION_INIT, 450 | .init = entry_init_guard, 451 | .deinit = entry_deinit_guard, 452 | .get_factory = entry_get_factory, 453 | }; 454 | -------------------------------------------------------------------------------- /src/plugins.plist.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${MACOSX_BUNDLE_EXECUTABLE_NAME} 9 | CFBundleGetInfoString 10 | ${MACOSX_BUNDLE_INFO_STRING} 11 | CFBundleIconFile 12 | ${MACOSX_BUNDLE_ICON_FILE} 13 | CFBundleIdentifier 14 | ${MACOSX_BUNDLE_GUI_IDENTIFIER} 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleLongVersionString 18 | ${MACOSX_BUNDLE_LONG_VERSION_STRING} 19 | CFBundleName 20 | ${MACOSX_BUNDLE_BUNDLE_NAME} 21 | CFBundlePackageType 22 | BNDL 23 | CFBundleShortVersionString 24 | ${MACOSX_BUNDLE_SHORT_VERSION_STRING} 25 | CFBundleSignature 26 | ???? 27 | CFBundleVersion 28 | ${MACOSX_BUNDLE_BUNDLE_VERSION} 29 | CSResourcesFileMapped 30 | 31 | NSHumanReadableCopyright 32 | ${MACOSX_BUNDLE_COPYRIGHT} 33 | 34 | 35 | --------------------------------------------------------------------------------