diff --git a/README.md b/README.md
index 8d01e26..30e5976 100644
--- a/README.md
+++ b/README.md
@@ -26,7 +26,7 @@ New features, performance improvements, easier setup.
-[**🟣 Brisk**](https://github.com/brisklib/brisk) is a modern, cross-platform C++ framework for efficient GUI development.
A fresh approach to creating GUI apps in C++. *(GPL/Commercial)*
+[**🟣 Brisk**](https://github.com/brisklib/brisk) is a cross-platform C++20 GUI framework featuring MVVM architecture, reactive capabilities, and scalable, accelerated GPU rendering. *(GPL/Commercial)*
[**🟢 CxxDox**](https://github.com/kfrlib/cxxdox) — C++ documentation generator. *(MIT)*
diff --git a/include/kfr/capi.h b/include/kfr/capi.h
index b96d1a4..e21a877 100644
--- a/include/kfr/capi.h
+++ b/include/kfr/capi.h
@@ -27,16 +27,19 @@
#include
#include
+
#if defined __STDC_IEC_559_COMPLEX__ && !defined KFR_NO_C_COMPLEX_TYPES
#include
#endif
+// Architecture detection
#if defined(_M_IX86) || defined(__i386__) || defined(_M_X64) || defined(__x86_64__)
#define KFR_ARCH_IS_X86 1
#elif defined(__arm__) || defined(__arm64__) || defined(_M_ARM) || defined(__aarch64__)
#define KFR_ARCH_IS_ARM 1
#endif
+// Calling convention definition
#if defined(_M_X64) || defined(__x86_64__)
#define KFR_CDECL
#else
@@ -49,13 +52,14 @@
#endif
#endif
+// DLL export/import macros
#ifdef _WIN32
#ifdef KFR_BUILDING_DLL
#define KFR_API_SPEC KFR_CDECL __declspec(dllexport)
#else
#define KFR_API_SPEC KFR_CDECL __declspec(dllimport)
#endif
-#else // !WIN32
+#else
#ifdef KFR_BUILDING_DLL
#define KFR_API_SPEC KFR_CDECL __attribute__((visibility("default")))
#else
@@ -68,188 +72,582 @@ extern "C"
{
#endif
- enum
- {
- KFR_ARCH_X86 = 0,
- KFR_ARCH_SSE2 = 1,
- KFR_ARCH_SSE3 = 2,
- KFR_ARCH_SSSE3 = 3,
- KFR_ARCH_SSE41 = 4,
- KFR_ARCH_SSE42 = 5,
- KFR_ARCH_AVX = 6,
- KFR_ARCH_AVX2 = 7,
- KFR_ARCH_AVX512 = 8,
- };
-
+/// Supported architectures enumeration
+enum
+{
+ KFR_ARCH_X86 = 0,
+ KFR_ARCH_SSE2 = 1,
+ KFR_ARCH_SSE3 = 2,
+ KFR_ARCH_SSSE3 = 3,
+ KFR_ARCH_SSE41 = 4,
+ KFR_ARCH_SSE42 = 5,
+ KFR_ARCH_AVX = 6,
+ KFR_ARCH_AVX2 = 7,
+ KFR_ARCH_AVX512 = 8,
+};
+
+/// Library version definitions
#define KFR_HEADERS_VERSION 60000
- KFR_API_SPEC const char* kfr_version_string();
- KFR_API_SPEC uint32_t kfr_version();
- KFR_API_SPEC const char* kfr_enabled_archs();
- KFR_API_SPEC int kfr_current_arch();
+/// @brief Returns the library version as a string.
+KFR_API_SPEC const char* kfr_version_string();
+
+/// @brief Returns the library version as an integer.
+KFR_API_SPEC uint32_t kfr_version();
- KFR_API_SPEC const char* kfr_last_error();
+/// @brief Returns the list of enabled architectures as a string.
+KFR_API_SPEC const char* kfr_enabled_archs();
+
+/// @brief Returns the current architecture in use.
+KFR_API_SPEC int kfr_current_arch();
+
+/// @brief Returns the last error message.
+KFR_API_SPEC const char* kfr_last_error();
+
+/// Typedefs for single and double precision floating points
+typedef float kfr_f32;
+typedef double kfr_f64;
- typedef float kfr_f32;
- typedef double kfr_f64;
#if defined __STDC_IEC_559_COMPLEX__ && !defined KFR_NO_C_COMPLEX_TYPES
- typedef float _Complex kfr_c32;
- typedef double _Complex kfr_c64;
+typedef float _Complex kfr_c32;
+typedef double _Complex kfr_c64;
#define KFR_COMPLEX_SIZE_MULTIPLIER 1
#else
typedef float kfr_c32;
typedef double kfr_c64;
#define KFR_COMPLEX_SIZE_MULTIPLIER 2
#endif
- typedef size_t kfr_size_t;
- typedef int32_t kfr_int32_t;
+typedef size_t kfr_size_t;
+typedef int32_t kfr_int32_t;
+
+/// Macro to define opaque structures for different DFT, DCT, and filter plans
#define KFR_OPAQUE_STRUCT(NAME) \
typedef struct NAME \
{ \
int opaque; \
} NAME;
- KFR_OPAQUE_STRUCT(KFR_DFT_PLAN_F32)
- KFR_OPAQUE_STRUCT(KFR_DFT_PLAN_F64)
+KFR_OPAQUE_STRUCT(KFR_DFT_PLAN_F32)
+KFR_OPAQUE_STRUCT(KFR_DFT_PLAN_F64)
- KFR_OPAQUE_STRUCT(KFR_DFT_REAL_PLAN_F32)
- KFR_OPAQUE_STRUCT(KFR_DFT_REAL_PLAN_F64)
+KFR_OPAQUE_STRUCT(KFR_DFT_REAL_PLAN_F32)
+KFR_OPAQUE_STRUCT(KFR_DFT_REAL_PLAN_F64)
- KFR_OPAQUE_STRUCT(KFR_DCT_PLAN_F32)
- KFR_OPAQUE_STRUCT(KFR_DCT_PLAN_F64)
+KFR_OPAQUE_STRUCT(KFR_DCT_PLAN_F32)
+KFR_OPAQUE_STRUCT(KFR_DCT_PLAN_F64)
- KFR_OPAQUE_STRUCT(KFR_FILTER_F32)
- KFR_OPAQUE_STRUCT(KFR_FILTER_F64)
+KFR_OPAQUE_STRUCT(KFR_FILTER_F32)
+KFR_OPAQUE_STRUCT(KFR_FILTER_F64)
- KFR_OPAQUE_STRUCT(KFR_FILTER_C32)
- KFR_OPAQUE_STRUCT(KFR_FILTER_C64)
-
- // Memory allocation
+KFR_OPAQUE_STRUCT(KFR_FILTER_C32)
+KFR_OPAQUE_STRUCT(KFR_FILTER_C64)
+/// Default memory alignment
#define KFR_DEFAULT_ALIGNMENT 64
- KFR_API_SPEC void* kfr_allocate(size_t size);
- KFR_API_SPEC void* kfr_allocate_aligned(size_t size, size_t alignment);
- KFR_API_SPEC void* kfr_reallocate(void* ptr, size_t new_size);
- KFR_API_SPEC void* kfr_reallocate_aligned(void* ptr, size_t new_size, size_t alignment);
- KFR_API_SPEC void* kfr_add_ref(void* ptr);
- KFR_API_SPEC void kfr_release(void* ptr);
- KFR_API_SPEC void kfr_deallocate(void* ptr);
- KFR_API_SPEC size_t kfr_allocated_size(void* ptr);
+/// @brief Allocates memory of specified size.
+KFR_API_SPEC void* kfr_allocate(size_t size);
- typedef enum KFR_DFT_PACK_FORMAT
- {
- Perm = 0,
- CCs = 1
- } KFR_DFT_PACK_FORMAT;
+/// @brief Allocates aligned memory of specified size and alignment.
+KFR_API_SPEC void* kfr_allocate_aligned(size_t size, size_t alignment);
- // Complex DFT plans
+/// @brief Reallocates memory to new size.
+KFR_API_SPEC void* kfr_reallocate(void* ptr, size_t new_size);
- KFR_API_SPEC KFR_DFT_PLAN_F32* kfr_dft_create_plan_f32(size_t size);
- KFR_API_SPEC KFR_DFT_PLAN_F64* kfr_dft_create_plan_f64(size_t size);
+/// @brief Reallocates aligned memory to new size and alignment.
+KFR_API_SPEC void* kfr_reallocate_aligned(void* ptr, size_t new_size, size_t alignment);
- KFR_API_SPEC void kfr_dft_dump_f32(KFR_DFT_PLAN_F32* plan);
- KFR_API_SPEC void kfr_dft_dump_f64(KFR_DFT_PLAN_F64* plan);
+/// @brief Adds a reference to the allocated memory.
+KFR_API_SPEC void* kfr_add_ref(void* ptr);
- KFR_API_SPEC size_t kfr_dft_get_size_f32(KFR_DFT_PLAN_F32* plan);
- KFR_API_SPEC size_t kfr_dft_get_size_f64(KFR_DFT_PLAN_F64* plan);
+/// @brief Releases a reference to the allocated memory.
+KFR_API_SPEC void kfr_release(void* ptr);
- KFR_API_SPEC size_t kfr_dft_get_temp_size_f32(KFR_DFT_PLAN_F32* plan);
- KFR_API_SPEC size_t kfr_dft_get_temp_size_f64(KFR_DFT_PLAN_F64* plan);
+/// @brief Deallocates memory.
+KFR_API_SPEC void kfr_deallocate(void* ptr);
- KFR_API_SPEC void kfr_dft_execute_f32(KFR_DFT_PLAN_F32* plan, kfr_c32* out, const kfr_c32* in,
- uint8_t* temp);
- KFR_API_SPEC void kfr_dft_execute_f64(KFR_DFT_PLAN_F64* plan, kfr_c64* out, const kfr_c64* in,
- uint8_t* temp);
+/// @brief Returns allocated memory size.
+KFR_API_SPEC size_t kfr_allocated_size(void* ptr);
- KFR_API_SPEC void kfr_dft_execute_inverse_f32(KFR_DFT_PLAN_F32* plan, kfr_c32* out, const kfr_c32* in,
- uint8_t* temp);
- KFR_API_SPEC void kfr_dft_execute_inverse_f64(KFR_DFT_PLAN_F64* plan, kfr_c64* out, const kfr_c64* in,
- uint8_t* temp);
+/// Enumeration for DFT packing format. See https://www.kfr.dev/docs/latest/dft_format/ for details
+typedef enum KFR_DFT_PACK_FORMAT
+{
+ Perm = 0,
+ CCs = 1
+} KFR_DFT_PACK_FORMAT;
+
+/**
+ * @brief Create a complex DFT plan (Single precision).
+ * @param size Size of the DFT.
+ * @return Pointer to the created DFT plan. Use `kfr_dft_delete_plan_f**` to free.
+ */
+KFR_API_SPEC KFR_DFT_PLAN_F32* kfr_dft_create_plan_f32(size_t size);
- KFR_API_SPEC void kfr_dft_delete_plan_f32(KFR_DFT_PLAN_F32* plan);
- KFR_API_SPEC void kfr_dft_delete_plan_f64(KFR_DFT_PLAN_F64* plan);
+/**
+ * @brief Create a complex DFT plan (Double precision).
+ * @param size Size of the DFT.
+ * @return Pointer to the created DFT plan. Use `kfr_dft_delete_plan_f**` to free.
+ */
+KFR_API_SPEC KFR_DFT_PLAN_F64* kfr_dft_create_plan_f64(size_t size);
- // Real DFT plans
+/**
+ * @brief Dump details of the DFT plan to stdout for inspection.
+ * @param plan Pointer to the DFT plan.
+ */
+KFR_API_SPEC void kfr_dft_dump_f32(KFR_DFT_PLAN_F32* plan);
- KFR_API_SPEC KFR_DFT_REAL_PLAN_F32* kfr_dft_real_create_plan_f32(size_t size,
- KFR_DFT_PACK_FORMAT pack_format);
- KFR_API_SPEC KFR_DFT_REAL_PLAN_F64* kfr_dft_real_create_plan_f64(size_t size,
- KFR_DFT_PACK_FORMAT pack_format);
+/**
+ * @brief Dump details of the DFT plan to stdout for inspection.
+ * @param plan Pointer to the DFT plan.
+ */
+KFR_API_SPEC void kfr_dft_dump_f64(KFR_DFT_PLAN_F64* plan);
- KFR_API_SPEC void kfr_dft_real_dump_f32(KFR_DFT_REAL_PLAN_F32* plan);
- KFR_API_SPEC void kfr_dft_real_dump_f64(KFR_DFT_REAL_PLAN_F64* plan);
+/**
+ * @brief Get the size of the DFT plan, in complex numbers.
+ * @param plan Pointer to the DFT plan.
+ * @return Size of the DFT plan as passed to kfr_dft_create_plan_f**.
+ */
+KFR_API_SPEC size_t kfr_dft_get_size_f32(KFR_DFT_PLAN_F32* plan);
- KFR_API_SPEC size_t kfr_dft_real_get_size_f32(KFR_DFT_REAL_PLAN_F32* plan);
- KFR_API_SPEC size_t kfr_dft_real_get_size_f64(KFR_DFT_REAL_PLAN_F64* plan);
+/**
+ * @brief Get the size of the DFT plan, in complex numbers.
+ * @param plan Pointer to the DFT plan.
+ * @return Size of the DFT plan as passed to kfr_dft_create_plan_f**.
+ */
+KFR_API_SPEC size_t kfr_dft_get_size_f64(KFR_DFT_PLAN_F64* plan);
+
+/**
+ * @brief Get temporary (scratch) buffer size for DFT plan.
+ * @param plan Pointer to the DFT plan.
+ * @return Temporary buffer size in bytes.
+ * @note Preallocating a byte buffer of the returned size and passing its pointer to the `kfr_dft_execute_f**`
+ * and `kfr_dft_execute_inverse_f**` functions may improve performance.
+ */
+KFR_API_SPEC size_t kfr_dft_get_temp_size_f32(KFR_DFT_PLAN_F32* plan);
+
+/**
+ * @brief Get temporary (scratch) buffer size for DFT plan.
+ * @param plan Pointer to the DFT plan.
+ * @return Temporary buffer size in bytes.
+ * @note Preallocating a byte buffer of the returned size and passing its pointer to the `kfr_dft_execute_f**`
+ * and `kfr_dft_execute_inverse_f**` functions may improve performance.
+ */
+KFR_API_SPEC size_t kfr_dft_get_temp_size_f64(KFR_DFT_PLAN_F64* plan);
+
+/**
+ * @brief Execute the complex forward DFT on `in` and write the result to `out`.
+ * @param plan Pointer to the DFT plan.
+ * @param out Pointer to the output data.
+ * @param in Pointer to the input data.
+ * @param temp Temporary (scratch) buffer. If `NULL`, scratch buffer of size `kfr_dft_get_temp_size_f**(plan)`
+ * will be allocated on stack or heap.
+ * @note No scaling is applied. This function reads $N$ complex values from `in` and writes $N$ complex values
+ * to `out`, where $N$ is the size passed to `kfr_dft_create_plan_f**`.
+ */
+KFR_API_SPEC void kfr_dft_execute_f32(KFR_DFT_PLAN_F32* plan, kfr_c32* out, const kfr_c32* in, uint8_t* temp);
+
+/**
+ * @brief Execute the complex forward DFT on `in` and write the result to `out`.
+ * @param plan Pointer to the DFT plan.
+ * @param out Pointer to the output data (frequency domain). May point to the same memory as `in` for in-place
+ * execution.
+ * @param in Pointer to the input data (time domain).
+ * @param temp Temporary (scratch) buffer. If `NULL`, scratch buffer of size `kfr_dft_get_temp_size_f**(plan)`
+ * will be allocated on stack or heap.
+ * @note No scaling is applied. This function reads $N$ complex values from `in` and writes $N$ complex values
+ * to `out`, where $N$ is the size passed to `kfr_dft_create_plan_f**`.
+ */
+KFR_API_SPEC void kfr_dft_execute_f64(KFR_DFT_PLAN_F64* plan, kfr_c64* out, const kfr_c64* in, uint8_t* temp);
+
+/**
+ * @brief Execute the inverse complex DFT on `in` and write the result to `out` for in-place execution.
+ * @param plan Pointer to the DFT plan.
+ * @param out Pointer to output data (time domain). May point to the same memory as `in` for in-place
+ * execution.
+ * @param in Pointer to input data (frequency domain).
+ * @param temp Temporary (scratch) buffer. If `NULL`, scratch buffer of size `kfr_dft_get_temp_size_f**(plan)`
+ * will be allocated on stack or heap.
+ * @note No scaling is applied. This function reads $N$ complex values from `in` and writes $N$ complex values
+ * to `out`, where $N$ is the size passed to `kfr_dft_create_plan_f**`.
+ */
+KFR_API_SPEC void kfr_dft_execute_inverse_f32(KFR_DFT_PLAN_F32* plan, kfr_c32* out, const kfr_c32* in,
+ uint8_t* temp);
+
+/**
+ * @brief Execute the inverse complex DFT on `in` and write the result to `out`.
+ * @param plan Pointer to the DFT plan.
+ * @param out Pointer to output data (time domain).
+ * @param in Pointer to input data (frequency domain).
+ * @param temp Temporary (scratch) buffer. If `NULL`, scratch buffer of size `kfr_dft_get_temp_size_f**(plan)`
+ * will be allocated on stack or heap.
+ * @note No scaling is applied. This function reads $N$ complex values from `in` and writes $N$ complex values
+ * to `out`, where $N$ is the size passed to `kfr_dft_create_plan_f**`.
+ */
+KFR_API_SPEC void kfr_dft_execute_inverse_f64(KFR_DFT_PLAN_F64* plan, kfr_c64* out, const kfr_c64* in,
+ uint8_t* temp);
+
+/**
+ * @brief Delete a complex DFT plan.
+ * @param plan Pointer to the DFT plan. May be `NULL`.
+ */
+KFR_API_SPEC void kfr_dft_delete_plan_f32(KFR_DFT_PLAN_F32* plan);
+
+/**
+ * @brief Delete a complex DFT plan.
+ * @param plan Pointer to the DFT plan. May be `NULL`.
+ */
+KFR_API_SPEC void kfr_dft_delete_plan_f64(KFR_DFT_PLAN_F64* plan);
- KFR_API_SPEC size_t kfr_dft_real_get_temp_size_f32(KFR_DFT_REAL_PLAN_F32* plan);
- KFR_API_SPEC size_t kfr_dft_real_get_temp_size_f64(KFR_DFT_REAL_PLAN_F64* plan);
+/**
+ * @brief Create a real DFT plan (Single precision).
+ * @param size Size of the real DFT. Must be even.
+ * @param pack_format Packing format for the DFT.
+ * @return Pointer to the created DFT plan. Use `kfr_dft_real_delete_plan_f**` to free.
+ */
+KFR_API_SPEC KFR_DFT_REAL_PLAN_F32* kfr_dft_real_create_plan_f32(size_t size,
+ KFR_DFT_PACK_FORMAT pack_format);
+
+/**
+ * @brief Create a real DFT plan (Double precision).
+ * @param size Size of the real DFT. Must be even.
+ * @param pack_format Packing format for the DFT.
+ * @return Pointer to the created DFT plan. Use `kfr_dft_real_delete_plan_f**` to free.
+ */
+KFR_API_SPEC KFR_DFT_REAL_PLAN_F64* kfr_dft_real_create_plan_f64(size_t size,
+ KFR_DFT_PACK_FORMAT pack_format);
+
+/**
+ * @brief Dump details of the real DFT plan to stdout for inspection.
+ * @param plan Pointer to the DFT plan.
+ */
+KFR_API_SPEC void kfr_dft_real_dump_f32(KFR_DFT_REAL_PLAN_F32* plan);
+
+/**
+ * @brief Dump details of the real DFT plan to stdout for inspection.
+ * @param plan Pointer to the DFT plan.
+ */
+KFR_API_SPEC void kfr_dft_real_dump_f64(KFR_DFT_REAL_PLAN_F64* plan);
+
+/**
+ * @brief Get the size of a real DFT plan.
+ * @param plan Pointer to the DFT plan.
+ * @return Size of the DFT as passed to `kfr_dft_real_create_plan_f**`.
+ */
+KFR_API_SPEC size_t kfr_dft_real_get_size_f32(KFR_DFT_REAL_PLAN_F32* plan);
- KFR_API_SPEC void kfr_dft_real_execute_f32(KFR_DFT_REAL_PLAN_F32* plan, kfr_c32* out, const kfr_f32* in,
- uint8_t* temp);
- KFR_API_SPEC void kfr_dft_real_execute_f64(KFR_DFT_REAL_PLAN_F64* plan, kfr_c64* out, const kfr_f64* in,
- uint8_t* temp);
+/**
+ * @brief Get the size of a real DFT plan.
+ * @param plan Pointer to the DFT plan.
+ * @return Size of the DFT as passed to `kfr_dft_real_create_plan_f**`.
+ */
+KFR_API_SPEC size_t kfr_dft_real_get_size_f64(KFR_DFT_REAL_PLAN_F64* plan);
+
+/**
+ * @brief Get temporary (scratch) buffer size for real DFT plan (Single precision).
+ * @param plan Pointer to the DFT plan.
+ * @return Temporary buffer size in bytes.
+ * @note Preallocating a byte buffer of the returned size and passing its pointer to the `kfr_dft_execute_f**`
+ * and `kfr_dft_execute_inverse_f**` functions may improve performance.
+ */
+KFR_API_SPEC size_t kfr_dft_real_get_temp_size_f32(KFR_DFT_REAL_PLAN_F32* plan);
+
+/**
+ * @brief Get temporary (scratch) buffer size for real DFT plan (Double precision).
+ * @param plan Pointer to the DFT plan.
+ * @return Temporary buffer size in bytes.
+ * @note Preallocating a byte buffer of the returned size and passing its pointer to the `kfr_dft_execute_f**`
+ * and `kfr_dft_execute_inverse_f**` functions may improve performance.
+ */
+KFR_API_SPEC size_t kfr_dft_real_get_temp_size_f64(KFR_DFT_REAL_PLAN_F64* plan);
+
+/**
+ * @brief Execute real DFT on `in` and write the result to `out`
+ * @param plan Pointer to the DFT plan.
+ * @param out Pointer to output data. May point to the same memory as `in` for in-place execution.
+ * @param in Pointer to input data.
+ * @param temp Temporary (scratch) buffer. If `NULL`, scratch buffer of size
+ * `kfr_dft_real_get_temp_size_f**(plan)` will be allocated on stack or heap.
+ * @note This function reads $N$ real values from `in` and writes $\frac{N}{2}$ (`Perm` format) or
+ * $\frac{N}{2}+1$ (`CCs` format) complex values to `out`, where $N$ is the size passed to
+ * `kfr_dft_real_create_plan_f**`.
+ */
+KFR_API_SPEC void kfr_dft_real_execute_f32(KFR_DFT_REAL_PLAN_F32* plan, kfr_c32* out, const kfr_f32* in,
+ uint8_t* temp);
+
+/**
+ * @brief Execute real DFT on `in` and write the result to `out`.
+ * @param plan Pointer to the DFT plan.
+ * @param out Pointer to output data. May point to the same memory as `in` for in-place execution.
+ * @param in Pointer to input data.
+ * @param temp Temporary (scratch) buffer. If `NULL`, scratch buffer of size
+ * `kfr_dft_real_get_temp_size_f**(plan)` will be allocated on stack or heap.
+ * @note This function reads $N$ real values from `in` and writes $\frac{N}{2}$ (`Perm` format) or
+ * $\frac{N}{2}+1$ (`CCs` format) complex values to `out`, where $N$ is the size passed to
+ * `kfr_dft_real_create_plan_f**`.
+ */
+KFR_API_SPEC void kfr_dft_real_execute_f64(KFR_DFT_REAL_PLAN_F64* plan, kfr_c64* out, const kfr_f64* in,
+ uint8_t* temp);
+
+/**
+ * @brief Execute inverse real DFT on `in` and write the result to `out`.
+ * @param plan Pointer to the DFT plan.
+ * @param out Pointer to output data. May point to the same memory as `in` for in-place execution.
+ * @param in Pointer to input data.
+ * @param temp Temporary (scratch) buffer. If `NULL`, scratch buffer of size
+ * `kfr_dft_real_get_temp_size_f**(plan)` will be allocated on stack or heap.
+ * @note This function reads $\frac{N}{2}$ (`Perm` format) or $\frac{N}{2}+1$ (`CCs` format) complex values
+ * from `in` and writes $N$ real values to `out`, where $N$ is the size passed to
+ * `kfr_dft_real_create_plan_f**`.
+ */
+KFR_API_SPEC void kfr_dft_real_execute_inverse_f32(KFR_DFT_REAL_PLAN_F32* plan, kfr_f32* out,
+ const kfr_c32* in, uint8_t* temp);
+
+/**
+ * @brief Execute inverse real DFT on `in` and write the result to `out`.
+ * @param plan Pointer to the DFT plan.
+ * @param out Pointer to output data. May point to the same memory as `in` for in-place execution.
+ * @param in Pointer to input data.
+ * @param temp Temporary (scratch) buffer. If `NULL`, scratch buffer of size
+ * `kfr_dft_real_get_temp_size_f**(plan)` will be allocated on stack or heap.
+ * @note This function reads $\frac{N}{2}$ (`Perm` format) or $\frac{N}{2}+1$ (`CCs` format) complex values
+ * from `in` and writes $N$ real values to `out`, where $N$ is the size passed to
+ * `kfr_dft_real_create_plan_f**`.
+ */
+KFR_API_SPEC void kfr_dft_real_execute_inverse_f64(KFR_DFT_REAL_PLAN_F64* plan, kfr_f64* out,
+ const kfr_c64* in, uint8_t* temp);
- KFR_API_SPEC void kfr_dft_real_execute_inverse_f32(KFR_DFT_REAL_PLAN_F32* plan, kfr_f32* out,
- const kfr_c32* in, uint8_t* temp);
- KFR_API_SPEC void kfr_dft_real_execute_inverse_f64(KFR_DFT_REAL_PLAN_F64* plan, kfr_f64* out,
- const kfr_c64* in, uint8_t* temp);
+/**
+ * @brief Delete a real DFT plan.
+ * @param plan Pointer to the DFT plan. May be `NULL`.
+ */
+KFR_API_SPEC void kfr_dft_real_delete_plan_f32(KFR_DFT_REAL_PLAN_F32* plan);
- KFR_API_SPEC void kfr_dft_real_delete_plan_f32(KFR_DFT_REAL_PLAN_F32* plan);
- KFR_API_SPEC void kfr_dft_real_delete_plan_f64(KFR_DFT_REAL_PLAN_F64* plan);
+/**
+ * @brief Delete a real DFT plan.
+ * @param plan Pointer to the DFT plan. May be `NULL`.
+ */
+KFR_API_SPEC void kfr_dft_real_delete_plan_f64(KFR_DFT_REAL_PLAN_F64* plan);
- // Discrete Cosine Transform type II plans
+/**
+ * @brief Create a DCT-II plan (Single precision).
+ * @param size Size of the DCT. Must be even.
+ * @return Pointer to the created DCT plan.
+ */
+KFR_API_SPEC KFR_DCT_PLAN_F32* kfr_dct_create_plan_f32(size_t size);
- KFR_API_SPEC KFR_DCT_PLAN_F32* kfr_dct_create_plan_f32(size_t size);
- KFR_API_SPEC KFR_DCT_PLAN_F64* kfr_dct_create_plan_f64(size_t size);
+/**
+ * @brief Create a DCT-II plan (Double precision).
+ * @param size Size of the DCT. Must be even.
+ * @return Pointer to the created DCT plan.
+ */
+KFR_API_SPEC KFR_DCT_PLAN_F64* kfr_dct_create_plan_f64(size_t size);
- KFR_API_SPEC void kfr_dct_dump_f32(KFR_DCT_PLAN_F32* plan);
- KFR_API_SPEC void kfr_dct_dump_f64(KFR_DCT_PLAN_F64* plan);
+/**
+ * @brief Dump details of the DCT plan to stdout for inspection.
+ * @param plan Pointer to the DCT plan.
+ */
+KFR_API_SPEC void kfr_dct_dump_f32(KFR_DCT_PLAN_F32* plan);
- KFR_API_SPEC size_t kfr_dct_get_size_f32(KFR_DCT_PLAN_F32* plan);
- KFR_API_SPEC size_t kfr_dct_get_size_f64(KFR_DCT_PLAN_F64* plan);
+/**
+ * @brief Dump details of the DCT plan to stdout for inspection.
+ * @param plan Pointer to the DCT plan.
+ */
+KFR_API_SPEC void kfr_dct_dump_f64(KFR_DCT_PLAN_F64* plan);
- KFR_API_SPEC size_t kfr_dct_get_temp_size_f32(KFR_DCT_PLAN_F32* plan);
- KFR_API_SPEC size_t kfr_dct_get_temp_size_f64(KFR_DCT_PLAN_F64* plan);
+/**
+ * @brief Get the size of a DCT plan.
+ * @param plan Pointer to the DCT plan.
+ * @return Size of the DCT as passed to `kfr_dct_create_plan_f**`.
+ */
+KFR_API_SPEC size_t kfr_dct_get_size_f32(KFR_DCT_PLAN_F32* plan);
- KFR_API_SPEC void kfr_dct_execute_f32(KFR_DCT_PLAN_F32* plan, kfr_f32* out, const kfr_f32* in,
- uint8_t* temp);
- KFR_API_SPEC void kfr_dct_execute_f64(KFR_DCT_PLAN_F64* plan, kfr_f64* out, const kfr_f64* in,
- uint8_t* temp);
+/**
+ * @brief Get the size of a DCT plan.
+ * @param plan Pointer to the DCT plan.
+ * @return Size of the DCT as passed to `kfr_dct_create_plan_f**`.
+ */
+KFR_API_SPEC size_t kfr_dct_get_size_f64(KFR_DCT_PLAN_F64* plan);
+
+/**
+ * @brief Get temporary (scratch) buffer size for DCT plan.
+ * @param plan Pointer to the DCT plan.
+ * @return Temporary buffer size in bytes.
+ * @note Preallocating a byte buffer of the returned size and passing its pointer to the `kfr_dct_execute_f**`
+ * and `kfr_dct_execute_inverse_f**` functions may improve performance.
+ */
+KFR_API_SPEC size_t kfr_dct_get_temp_size_f32(KFR_DCT_PLAN_F32* plan);
+
+/**
+ * @brief Get temporary (scratch) buffer size for DCT plan.
+ * @param plan Pointer to the DCT plan.
+ * @return Temporary buffer size in bytes.
+ * @note Preallocating a byte buffer of the returned size and passing its pointer to the `kfr_dct_execute_f**`
+ * and `kfr_dct_execute_inverse_f**` functions may improve performance.
+ */
+KFR_API_SPEC size_t kfr_dct_get_temp_size_f64(KFR_DCT_PLAN_F64* plan);
+
+/**
+ * @brief Execute DCT-II on `in` and write the result to `out`.
+ * @param plan Pointer to the DCT plan.
+ * @param out Pointer to output data.
+ * @param in Pointer to input data.
+ * @param temp Temporary (scratch) buffer. If `NULL`, scratch buffer of size
+ * `kfr_dct_get_temp_size_f**(plan)` will be allocated on stack or heap.
+ * @note No scaling is applied. This function read $N$ values from `in` and writes $N$ values to `out`, where
+ * $N$ is the size passed to `kfr_dct_create_plan_f**`..
+ */
+KFR_API_SPEC void kfr_dct_execute_f32(KFR_DCT_PLAN_F32* plan, kfr_f32* out, const kfr_f32* in, uint8_t* temp);
+
+/**
+ * @brief Execute DCT-II on `in` and write the result to `out`.
+ * @param plan Pointer to the DCT plan.
+ * @param out Pointer to output data.
+ * @param in Pointer to input data.
+ * @param temp Temporary (scratch) buffer. If `NULL`, scratch buffer of size
+ * `kfr_dct_get_temp_size_f**(plan)` will be allocated on stack or heap.
+ * @note No scaling is applied. This function read $N$ values from `in` and writes $N$ values to `out`, where
+ * $N$ is the size passed to `kfr_dct_create_plan_f**`..
+ */
+KFR_API_SPEC void kfr_dct_execute_f64(KFR_DCT_PLAN_F64* plan, kfr_f64* out, const kfr_f64* in, uint8_t* temp);
+
+/**
+ * @brief Execute inverse DCT-II (aka DCT-III) on `in` and write the result to `out`.
+ * @param plan Pointer to the DCT plan.
+ * @param out Pointer to output data.
+ * @param in Pointer to input data.
+ * @param temp Temporary (scratch) buffer. If `NULL`, scratch buffer of size
+ * `kfr_dct_get_temp_size_f**(plan)` will be allocated on stack or heap.
+ * @note No scaling is applied. This function read $N$ values from `in` and writes $N$ values to `out`, where
+ * $N$ is the size passed to `kfr_dct_create_plan_f**`..
+ */
+KFR_API_SPEC void kfr_dct_execute_inverse_f32(KFR_DCT_PLAN_F32* plan, kfr_f32* out, const kfr_f32* in,
+ uint8_t* temp);
+
+/**
+ * @brief Execute inverse DCT-II (aka DCT-III) on `in` and write the result to `out`.
+ * @param plan Pointer to the DCT plan.
+ * @param out Pointer to output data.
+ * @param in Pointer to input data.
+ * @param temp Temporary (scratch) buffer. If `NULL`, scratch buffer of size
+ * `kfr_dct_get_temp_size_f**(plan)` will be allocated on stack or heap.
+ * @note No scaling is applied. This function read $N$ values from `in` and writes $N$ values to `out`, where
+ * $N$ is the size passed to `kfr_dct_create_plan_f**`..
+ */
+KFR_API_SPEC void kfr_dct_execute_inverse_f64(KFR_DCT_PLAN_F64* plan, kfr_f64* out, const kfr_f64* in,
+ uint8_t* temp);
- KFR_API_SPEC void kfr_dct_execute_inverse_f32(KFR_DCT_PLAN_F32* plan, kfr_f32* out, const kfr_f32* in,
- uint8_t* temp);
- KFR_API_SPEC void kfr_dct_execute_inverse_f64(KFR_DCT_PLAN_F64* plan, kfr_f64* out, const kfr_f64* in,
- uint8_t* temp);
+/**
+ * @brief Delete a DCT plan.
+ * @param plan Pointer to the DCT plan. May be `NULL`.
+ */
+KFR_API_SPEC void kfr_dct_delete_plan_f32(KFR_DCT_PLAN_F32* plan);
- KFR_API_SPEC void kfr_dct_delete_plan_f32(KFR_DCT_PLAN_F32* plan);
- KFR_API_SPEC void kfr_dct_delete_plan_f64(KFR_DCT_PLAN_F64* plan);
+/**
+ * @brief Delete a DCT plan.
+ * @param plan Pointer to the DCT plan. May be `NULL`.
+ */
+KFR_API_SPEC void kfr_dct_delete_plan_f64(KFR_DCT_PLAN_F64* plan);
- // Filters: FIR, IIR
+/**
+ * @brief Create a FIR filter plan (Single precision).
+ * @param taps Pointer to filter taps.
+ * @param size Number of filter taps.
+ * @return Pointer to the created FIR filter plan. Use `kfr_filter_delete_plan_f**` to free.
+ */
+KFR_API_SPEC KFR_FILTER_F32* kfr_filter_create_fir_plan_f32(const kfr_f32* taps, size_t size);
- KFR_API_SPEC KFR_FILTER_F32* kfr_filter_create_fir_plan_f32(const kfr_f32* taps, size_t size);
- KFR_API_SPEC KFR_FILTER_F64* kfr_filter_create_fir_plan_f64(const kfr_f64* taps, size_t size);
+/**
+ * @brief Create a FIR filter plan (Double precision).
+ * @param taps Pointer to filter taps.
+ * @param size Number of filter taps.
+ * @return Pointer to the created FIR filter plan. Use `kfr_filter_delete_plan_f**` to free.
+ */
+KFR_API_SPEC KFR_FILTER_F64* kfr_filter_create_fir_plan_f64(const kfr_f64* taps, size_t size);
+
+/**
+ * @brief Create a convolution filter plan (Single precision).
+ * @param taps Pointer to filter taps.
+ * @param size Number of filter taps.
+ * @param block_size Size of the processing block. Must be a power of two.
+ * @return Pointer to the created convolution filter plan. Use `kfr_filter_delete_plan_f**` to free.
+ * @note Mathematically, this produces the same result as an FIR filter, but it uses the FFT overlap-add
+ technique internally to improve performance with larger filter lengths.
+ */
+KFR_API_SPEC KFR_FILTER_F32* kfr_filter_create_convolution_plan_f32(const kfr_f32* taps, size_t size,
+ size_t block_size);
+
+/**
+ * @brief Create a convolution filter plan (Double precision).
+ * @param taps Pointer to filter taps.
+ * @param size Number of filter taps.
+ * @param block_size Size of the processing block. Must be a power of two.
+ * @return Pointer to the created convolution filter plan. Use `kfr_filter_delete_plan_f**` to free.
+ * @note Mathematically, this produces the same result as an FIR filter, but it uses the FFT overlap-add
+ technique internally to improve performance with larger filter lengths.
+ */
+KFR_API_SPEC KFR_FILTER_F64* kfr_filter_create_convolution_plan_f64(const kfr_f64* taps, size_t size,
+ size_t block_size);
+
+/**
+ * @brief Create a IIR filter plan (Single precision).
+ * @param sos Pointer to second-order sections (SOS) coefficients.
+ * @param sos_count Number of second-order sections.
+ * @return Pointer to the created IIR filter plan. Use `kfr_filter_delete_plan_f**` to free.
+ */
+KFR_API_SPEC KFR_FILTER_F32* kfr_filter_create_iir_plan_f32(const kfr_f32* sos, size_t sos_count);
- KFR_API_SPEC KFR_FILTER_F32* kfr_filter_create_convolution_plan_f32(const kfr_f32* taps, size_t size,
- size_t block_size);
- KFR_API_SPEC KFR_FILTER_F64* kfr_filter_create_convolution_plan_f64(const kfr_f64* taps, size_t size,
- size_t block_size);
+/**
+ * @brief Create a IIR filter plan (Double precision).
+ * @param sos Pointer to second-order sections (SOS) coefficients.
+ * @param sos_count Number of second-order sections.
+ * @return Pointer to the created IIR filter plan. Use `kfr_filter_delete_plan_f**` to free.
+ */
+KFR_API_SPEC KFR_FILTER_F64* kfr_filter_create_iir_plan_f64(const kfr_f64* sos, size_t sos_count);
+
+/**
+ * @brief Process input data with a filter.
+ * @param plan Pointer to the filter plan.
+ * @param output Pointer to output data. May point to the same memory as `input` for in-place execution.
+ * @param input Pointer to input data.
+ * @param size Number of samples to process.
+ */
+KFR_API_SPEC void kfr_filter_process_f32(KFR_FILTER_F32* plan, kfr_f32* output, const kfr_f32* input,
+ size_t size);
+
+/**
+ * @brief Process input data with a filter.
+ * @param plan Pointer to the filter plan.
+ * @param output Pointer to output data. May point to the same memory as `input` for in-place execution.
+ * @param input Pointer to input data.
+ * @param size Number of samples to process.
+ */
+KFR_API_SPEC void kfr_filter_process_f64(KFR_FILTER_F64* plan, kfr_f64* output, const kfr_f64* input,
+ size_t size);
- KFR_API_SPEC KFR_FILTER_F32* kfr_filter_create_iir_plan_f32(const kfr_f32* sos, size_t sos_count);
- KFR_API_SPEC KFR_FILTER_F64* kfr_filter_create_iir_plan_f64(const kfr_f64* sos, size_t sos_count);
+/**
+ * @brief Reset the internal state of a filter plan, including delay line.
+ * @param plan Pointer to the filter plan.
+ */
+KFR_API_SPEC void kfr_filter_reset_f32(KFR_FILTER_F32* plan);
- KFR_API_SPEC void kfr_filter_process_f32(KFR_FILTER_F32* plan, kfr_f32* output, const kfr_f32* input,
- size_t size);
- KFR_API_SPEC void kfr_filter_process_f64(KFR_FILTER_F64* plan, kfr_f64* output, const kfr_f64* input,
- size_t size);
+/**
+ * @brief Reset the internal state of a filter plan, including delay line.
+ * @param plan Pointer to the filter plan.
+ */
+KFR_API_SPEC void kfr_filter_reset_f64(KFR_FILTER_F64* plan);
- KFR_API_SPEC void kfr_filter_reset_f32(KFR_FILTER_F32* plan);
- KFR_API_SPEC void kfr_filter_reset_f64(KFR_FILTER_F64* plan);
+/**
+ * @brief Delete a filter plan.
+ * @param plan Pointer to the filter plan. May be `NULL`.
+ */
+KFR_API_SPEC void kfr_filter_delete_plan_f32(KFR_FILTER_F32* plan);
- KFR_API_SPEC void kfr_filter_delete_plan_f32(KFR_FILTER_F32* plan);
- KFR_API_SPEC void kfr_filter_delete_plan_f64(KFR_FILTER_F64* plan);
+/**
+ * @brief Delete a filter plan.
+ * @param plan Pointer to the filter plan. May be `NULL`.
+ */
+KFR_API_SPEC void kfr_filter_delete_plan_f64(KFR_FILTER_F64* plan);
#ifdef __cplusplus
}
diff --git a/include/kfr/version.hpp b/include/kfr/version.hpp
index 01800b9..c49b92a 100644
--- a/include/kfr/version.hpp
+++ b/include/kfr/version.hpp
@@ -29,8 +29,12 @@
namespace kfr
{
-
-/// @brief Returns string representation of the KFR version (including target architecture)
+/// @brief Returns the string representation of the KFR library version, including target architecture.
+/// @return A constant character pointer to the version string.
inline static const char* library_version() { return KFR_VERSION_FULL; }
+
+/// @brief Returns the current CPU name at runtime.
+/// @return A constant character pointer to the name of the current CPU.
inline static const char* cpu_runtime() { return cpu_name(get_cpu()); }
+
} // namespace kfr