aboutsummaryrefslogtreecommitdiffstats
path: root/common/pffft.h
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2023-12-09 12:35:07 -0800
committerChris Robinson <[email protected]>2023-12-09 12:35:07 -0800
commit44fbc93909a1a1d1dc26c01feb32bf13a5140234 (patch)
treea9e9c5d7d9fcf6a47e654177dbbdfb5e3b2bd155 /common/pffft.h
parentdecc10da2bdbb611cce63916f8c6f8b17ea45da1 (diff)
Be less messy with PFFFT
Remove a 1-element array for an over-allocated struct array. Also add a wrapper struct for C++.
Diffstat (limited to 'common/pffft.h')
-rw-r--r--common/pffft.h57
1 files changed, 51 insertions, 6 deletions
diff --git a/common/pffft.h b/common/pffft.h
index 9cff9e54..b31304f6 100644
--- a/common/pffft.h
+++ b/common/pffft.h
@@ -83,23 +83,27 @@
#include <stdint.h>
#ifdef __cplusplus
+#include <cstddef>
+#include <utility>
+
extern "C" {
#endif
/* opaque struct holding internal stuff (precomputed twiddle factors) this
* struct can be shared by many threads as it contains only read-only data.
*/
-typedef struct PFFFT_Setup PFFFT_Setup;
-
-#ifndef PFFFT_COMMON_ENUMS
-#define PFFFT_COMMON_ENUMS
+struct PFFFT_Setup;
/* direction of the transform */
-typedef enum { PFFFT_FORWARD, PFFFT_BACKWARD } pffft_direction_t;
+enum pffft_direction_t { PFFFT_FORWARD, PFFFT_BACKWARD };
/* type of transform */
-typedef enum { PFFFT_REAL, PFFFT_COMPLEX } pffft_transform_t;
+enum pffft_transform_t { PFFFT_REAL, PFFFT_COMPLEX };
+#ifndef __cplusplus
+typedef struct PFFFT_Setup PFFFT_Setup;
+typedef enum pffft_direction_t pffft_direction_t;
+typedef enum pffft_transform_t pffft_transform_t;
#endif
/**
@@ -187,6 +191,47 @@ int pffft_simd_size();
#ifdef __cplusplus
}
+
+struct PFFFTSetup {
+ PFFFT_Setup *mSetup{};
+
+ PFFFTSetup() = default;
+ PFFFTSetup(const PFFFTSetup&) = delete;
+ PFFFTSetup(PFFFTSetup&& rhs) : mSetup{rhs.mSetup} { rhs.mSetup = nullptr; }
+ explicit PFFFTSetup(std::nullptr_t) { }
+ explicit PFFFTSetup(unsigned int n, pffft_transform_t transform)
+ : mSetup{pffft_new_setup(n, transform)}
+ { }
+ ~PFFFTSetup() { if(mSetup) pffft_destroy_setup(mSetup); }
+
+ PFFFTSetup& operator=(const PFFFTSetup&) = delete;
+ PFFFTSetup& operator=(PFFFTSetup&& rhs)
+ {
+ if(mSetup)
+ pffft_destroy_setup(mSetup);
+ mSetup = std::exchange(rhs.mSetup, nullptr);
+ return *this;
+ }
+
+ void transform(const float *input, float *output, float *work, pffft_direction_t direction) const
+ { pffft_transform(mSetup, input, output, work, direction); }
+
+ void transform_ordered(const float *input, float *output, float *work,
+ pffft_direction_t direction) const
+ { pffft_transform_ordered(mSetup, input, output, work, direction); }
+
+ void zreorder(const float *input, float *output, pffft_direction_t direction) const
+ { pffft_zreorder(mSetup, input, output, direction); }
+
+ void zconvolve_scale_accumulate(const float *dft_a, const float *dft_b, float *dft_ab,
+ float scaling) const
+ { pffft_zconvolve_scale_accumulate(mSetup, dft_a, dft_b, dft_ab, scaling); }
+
+ void zconvolve_accumulate(const float *dft_a, const float *dft_b, float *dft_ab) const
+ { pffft_zconvolve_accumulate(mSetup, dft_a, dft_b, dft_ab); }
+
+ [[nodiscard]] operator bool() const noexcept { return mSetup != nullptr; }
+};
#endif
#endif // PFFFT_H