clap

CLAP Audio Plugin API
Log | Files | Refs | README | LICENSE

commit 732594d677deff37e11ba8c0455bff885a5e439a
parent 4711bddac6ee6ca048067a66a7cad50bf9691b01
Author: Alexandre BIQUE <bique.alexandre@gmail.com>
Date:   Tue, 21 Dec 2021 09:00:55 +0100

More on alignment and refactor version.h to use less preprocessor defines

Diffstat:
Minclude/clap/audio-buffer.h | 14++++++++------
Minclude/clap/entry.h | 12+++++++-----
Minclude/clap/events.h | 15++++++++-------
Minclude/clap/host.h | 5+++++
Minclude/clap/plugin-factory.h | 5+++++
Minclude/clap/plugin-invalidation.h | 7++++++-
Minclude/clap/plugin.h | 11+++++++++--
Ainclude/clap/private/align.h | 11+++++++++++
Dinclude/clap/private/align_pop.h | 2--
Dinclude/clap/private/align_push.h | 11-----------
Minclude/clap/process.h | 14++++++++++----
Minclude/clap/stream.h | 6++++++
Minclude/clap/version.h | 38++++++++++++++++++++------------------
Msrc/main.c | 4++--
Msrc/main.cc | 4++--
15 files changed, 99 insertions(+), 60 deletions(-)

diff --git a/include/clap/audio-buffer.h b/include/clap/audio-buffer.h @@ -2,23 +2,25 @@ #include <stdint.h> -#include "private/align_push.h" +#include "private/align.h" #ifdef __cplusplus extern "C" { #endif +#pragma pack(push, CLAP_PTR_ALIGN) + typedef struct clap_audio_buffer { // Either data32 or data64 pointer will be set. float ** data32; double **data64; alignas(4) uint32_t channel_count; alignas(4) uint32_t latency; // latency from/to the audio interface - uint64_t constant_mask; // mask & (1 << N) to test if channel N is constant + alignas(8) uint64_t constant_mask; // mask & (1 << N) to test if channel N is constant } clap_audio_buffer_t; +#pragma pack(pop) + #ifdef __cplusplus } -#endif - -#include "private/align_pop.h" -\ No newline at end of file +#endif +\ No newline at end of file diff --git a/include/clap/entry.h b/include/clap/entry.h @@ -3,12 +3,14 @@ #include "version.h" #include "private/macros.h" -#include "private/align_push.h" +#include "private/align.h" #ifdef __cplusplus extern "C" { #endif +#pragma pack(push, CLAP_PTR_ALIGN) + // This interface is the entry point of the dynamic library. // // Every methods must be thread-safe. @@ -41,8 +43,8 @@ typedef struct clap_plugin_entry { /* Entry point */ CLAP_EXPORT extern const clap_plugin_entry_t clap_entry; +#pragma pack(pop) + #ifdef __cplusplus } -#endif - -#include "private/align_pop.h" -\ No newline at end of file +#endif +\ No newline at end of file diff --git a/include/clap/events.h b/include/clap/events.h @@ -5,13 +5,14 @@ #include "fixedpoint.h" #include "id.h" - -#include "private/align_push.h" +#include "private/align.h" #ifdef __cplusplus extern "C" { #endif +#pragma pack(push, CLAP_PTR_ALIGN) + enum { CLAP_EVENT_NOTE_ON, // press a key; note attribute CLAP_EVENT_NOTE_OFF, // release a key; note attribute @@ -175,7 +176,7 @@ typedef struct clap_event { alignas(4) clap_event_type type; alignas(4) uint32_t time; // offset from the first sample in the process block - alignas(8) union { + union { clap_event_note_t note; clap_event_note_expression_t note_expression; clap_event_param_value_t param_value; @@ -199,8 +200,8 @@ typedef struct clap_event_list { void (*push_back)(const struct clap_event_list *list, const clap_event_t *event); } clap_event_list_t; +#pragma pack(pop) + #ifdef __cplusplus } -#endif - -#include "private/align_pop.h" -\ No newline at end of file +#endif +\ No newline at end of file diff --git a/include/clap/host.h b/include/clap/host.h @@ -1,11 +1,14 @@ #pragma once #include "version.h" +#include "private/align.h" #ifdef __cplusplus extern "C" { #endif +#pragma pack(push, CLAP_PTR_ALIGN) + typedef struct clap_host { clap_version_t clap_version; // initialized to CLAP_VERSION @@ -36,6 +39,8 @@ typedef struct clap_host { void (*request_callback)(const struct clap_host *host); } clap_host_t; +#pragma pack(pop) + #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/include/clap/plugin-factory.h b/include/clap/plugin-factory.h @@ -1,6 +1,7 @@ #pragma once #include "plugin.h" +#include "private/align.h" static const CLAP_CONSTEXPR char CLAP_PLUGIN_FACTORY_ID[] = "clap.plugin-factory"; @@ -8,6 +9,8 @@ static const CLAP_CONSTEXPR char CLAP_PLUGIN_FACTORY_ID[] = "clap.plugin-factory extern "C" { #endif +#pragma pack(push, CLAP_PTR_ALIGN) + // Every methods must be thread-safe. // It is very important to be able to scan the plugin as quickly as possible. struct clap_plugin_factory { @@ -32,6 +35,8 @@ struct clap_plugin_factory { const char *plugin_id); }; +#pragma pack(pop) + #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/include/clap/plugin-invalidation.h b/include/clap/plugin-invalidation.h @@ -4,6 +4,7 @@ #include <stdint.h> #include "private/macros.h" +#include "private/align.h" static const CLAP_CONSTEXPR char CLAP_PLUGIN_INVALIDATION_ID[] = "clap.plugin-invalidation"; @@ -11,6 +12,8 @@ static const CLAP_CONSTEXPR char CLAP_PLUGIN_INVALIDATION_ID[] = "clap.plugin-in extern "C" { #endif +#pragma pack(push) + typedef struct clap_plugin_invalidation_source { // Directory containing the file(s) to scan const char *directory; @@ -19,7 +22,7 @@ typedef struct clap_plugin_invalidation_source { const char *filename_glob; // should the directory be scanned recursively? - bool recursive_scan; + alignas(1) bool recursive_scan; } clap_plugin_invalidation_source_t; // Used to figure out when a plugin needs to be scanned again. @@ -41,6 +44,8 @@ typedef struct clap_plugin_invalidation_factory { bool (*refresh)(const struct clap_plugin_invalidation_factory *factory); } clap_plugin_invalidation_factory_t; +#pragma pack(pop) + #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/include/clap/plugin.h b/include/clap/plugin.h @@ -4,10 +4,14 @@ #include "host.h" #include "process.h" +#include "private/align.h" + #ifdef __cplusplus extern "C" { #endif +#pragma pack(push, CLAP_PTR_ALIGN) + /* bitfield * This gives an hint to the host what the plugin might do. */ enum { @@ -52,7 +56,7 @@ typedef struct clap_plugin_descriptor { // "chip;chiptune;gameboy;nintendo;sega" const char *keywords; - uint64_t plugin_type; // bitfield of clap_plugin_type + alignas(8) uint64_t plugin_type; // bitfield of clap_plugin_type } clap_plugin_descriptor_t; typedef struct clap_plugin { @@ -101,6 +105,8 @@ typedef struct clap_plugin { void (*on_main_thread)(const struct clap_plugin *plugin); } clap_plugin_t; +#pragma pack(pop) + #ifdef __cplusplus } -#endif +#endif +\ No newline at end of file diff --git a/include/clap/private/align.h b/include/clap/private/align.h @@ -0,0 +1,10 @@ +#include <stdint.h> +#include <stdalign.h> + +#if UINTPTR_MAX == UINT64_MAX +# define CLAP_PTR_ALIGN 8 +#elif UINTPTR_MAX == UINT32_MAX +# define CLAP_PTR_ALIGN 4 +#elif UINTPTR_MAX == UINT16_MAX +# define CLAP_PTR_ALIGN 2 +#endif +\ No newline at end of file diff --git a/include/clap/private/align_pop.h b/include/clap/private/align_pop.h @@ -1 +0,0 @@ -#pragma pack(pop) -\ No newline at end of file diff --git a/include/clap/private/align_push.h b/include/clap/private/align_push.h @@ -1,10 +0,0 @@ -#include <stdint.h> -#include <stdalign.h> - -#if UINTPTR_MAX == UINT64_MAX -# pragma pack(push, 8) -#elif UINTPTR_MAX == UINT32_MAX -# pragma pack(push, 4) -#elif UINTPTR_MAX == UINT16_MAX -# pragma pack(push, 2) -#endif -\ No newline at end of file diff --git a/include/clap/process.h b/include/clap/process.h @@ -3,10 +3,14 @@ #include "events.h" #include "audio-buffer.h" +#include "private/align.h" + #ifdef __cplusplus extern "C" { #endif +#pragma pack(push, CLAP_PTR_ALIGN) + enum { // Processing failed. The output buffer must be discarded. CLAP_PROCESS_ERROR = 0, @@ -24,8 +28,8 @@ enum { typedef int32_t clap_process_status; typedef struct clap_process { - uint64_t steady_time; // a steady sample time counter, requiered - uint32_t frames_count; // number of frame to process + alignas(8) uint64_t steady_time; // a steady sample time counter, requiered + alignas(4) uint32_t frames_count; // number of frame to process // time info at sample 0 // If null, then this is a free running host, no transport events will be provided @@ -39,14 +43,16 @@ typedef struct clap_process { // then it gets a default stereo input and output. const clap_audio_buffer_t *audio_inputs; const clap_audio_buffer_t *audio_outputs; - uint32_t audio_inputs_count; - uint32_t audio_outputs_count; + alignas(4) uint32_t audio_inputs_count; + alignas(4) uint32_t audio_outputs_count; /* events */ const clap_event_list_t *in_events; const clap_event_list_t *out_events; } clap_process_t; +#pragma pack(pop) + #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/include/clap/stream.h b/include/clap/stream.h @@ -2,10 +2,14 @@ #include <stdint.h> +#include "private/align.h" + #ifdef __cplusplus extern "C" { #endif +#pragma pack(push, CLAP_PTR_ALIGN) + typedef struct clap_istream { void *ctx; // reserved pointer for the stream @@ -23,6 +27,8 @@ typedef struct clap_ostream { int64_t (*write)(struct clap_ostream *stream, const void *buffer, uint64_t size); } clap_ostream_t; +#pragma pack(pop) + #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/include/clap/version.h b/include/clap/version.h @@ -4,37 +4,38 @@ #include <stdint.h> #include "private/macros.h" +#include "private/align.h" #ifdef __cplusplus extern "C" { #endif +#pragma pack(push, CLAP_PTR_ALIGN) + typedef struct clap_version { // This is the major ABI and API design // Version 0.X.Y correspond to the development stage, API and ABI are not stable // Version 1.X.Y correspont to the release stage, API and ABI are stable - uint32_t major; - uint32_t minor; - uint32_t revision; + alignas(4) uint32_t major; + alignas(4) uint32_t minor; + alignas(4) uint32_t revision; } clap_version_t; -#ifdef __cplusplus -} -#endif +#pragma pack(pop) -#define CLAP_VERSION_MAJOR ((uint32_t)0) -#define CLAP_VERSION_MINOR ((uint32_t)16) -#define CLAP_VERSION_REVISION ((uint32_t)0) +static const uint32_t CLAP_VERSION_MAJOR = 0; +static const uint32_t CLAP_VERSION_MINOR = 16; +static const uint32_t CLAP_VERSION_REVISION = 0; -#ifdef __cplusplus -# define CLAP_VERSION \ - (clap_version_t{CLAP_VERSION_MAJOR, CLAP_VERSION_MINOR, CLAP_VERSION_REVISION}) -#else -# define CLAP_VERSION \ - ((clap_version_t){CLAP_VERSION_MAJOR, CLAP_VERSION_MINOR, CLAP_VERSION_REVISION}) -#endif +static const clap_version_t CLAP_VERSION = { + CLAP_VERSION_MAJOR, CLAP_VERSION_MINOR, CLAP_VERSION_REVISION}; // For version 0, we require the same minor version because // we may still break the ABI at this point -#define clap_version_is_compatible(Version) \ - ((Version).major == CLAP_VERSION_MAJOR && (Version).minor == CLAP_VERSION_MINOR) +static inline bool clap_version_is_compatible(const clap_version_t v) { + return v.major == CLAP_VERSION_MAJOR && v.minor == CLAP_VERSION_MINOR; +} + +#ifdef __cplusplus +} +#endif +\ No newline at end of file diff --git a/src/main.c b/src/main.c @@ -4,4 +4,4 @@ clap_version_t m = CLAP_VERSION; -int main(int argc, char ** argv) { return !clap_version_is_compatible(m); } -\ No newline at end of file +int main(int argc, char **argv) { return !clap_version_is_compatible(m); } +\ No newline at end of file diff --git a/src/main.cc b/src/main.cc @@ -4,4 +4,4 @@ clap_version m = CLAP_VERSION; -int main(int argc, char **argv) { return !clap_version_is_compatible(m); } -\ No newline at end of file +int main(int, char **) { return !clap_version_is_compatible(m); } +\ No newline at end of file