diff --git a/src/modules/meson.build b/src/modules/meson.build index 1195cebaa..5092221d9 100644 --- a/src/modules/meson.build +++ b/src/modules/meson.build @@ -82,7 +82,7 @@ simd_dependencies = [] if have_sse filter_chain_sse = static_library('filter_chain_sse', ['module-filter-chain/pffft.c', - 'module-filter-chain/dsp-ops-sse.c' ], + 'module-filter-chain/audio-dsp-sse.c' ], include_directories : [configinc], c_args : [sse_args, '-O3', '-DHAVE_SSE'], dependencies : [ spa_dep ], @@ -93,7 +93,7 @@ if have_sse endif if have_avx filter_chain_avx = static_library('filter_chain_avx', - ['module-filter-chain/dsp-ops-avx.c' ], + ['module-filter-chain/audio-dsp-avx.c' ], include_directories : [configinc], c_args : [avx_args, fma_args,'-O3', '-DHAVE_AVX'], dependencies : [ spa_dep ], @@ -115,8 +115,8 @@ endif filter_chain_c = static_library('filter_chain_c', ['module-filter-chain/pffft.c', - 'module-filter-chain/dsp-ops.c', - 'module-filter-chain/dsp-ops-c.c' ], + 'module-filter-chain/audio-dsp.c', + 'module-filter-chain/audio-dsp-c.c' ], include_directories : [configinc], c_args : [simd_cargs, '-O3', '-DPFFFT_SIMD_DISABLE'], dependencies : [ spa_dep, fftw_dep], diff --git a/src/modules/module-filter-chain.c b/src/modules/module-filter-chain.c index 1fe26e064..5a536a5e7 100644 --- a/src/modules/module-filter-chain.c +++ b/src/modules/module-filter-chain.c @@ -13,24 +13,14 @@ #include "config.h" -#include "module-filter-chain/filter-graph.h" - -#include -#include -#include -#include #include #include #include #include -#include -#include -#include #include -#include -#include "module-filter-chain/dsp-ops-impl.h" +#include "module-filter-chain/filter-graph.h" #define NAME "filter-chain" diff --git a/src/modules/module-filter-chain/dsp-ops-avx.c b/src/modules/module-filter-chain/audio-dsp-avx.c similarity index 95% rename from src/modules/module-filter-chain/dsp-ops-avx.c rename to src/modules/module-filter-chain/audio-dsp-avx.c index 15f2a1472..870e94940 100644 --- a/src/modules/module-filter-chain/dsp-ops-avx.c +++ b/src/modules/module-filter-chain/audio-dsp-avx.c @@ -12,11 +12,11 @@ #ifndef HAVE_FFTW #include "pffft.h" #endif -#include "dsp-ops.h" +#include "audio-dsp-impl.h" #include -void dsp_mix_gain_avx(struct dsp_ops *ops, +void dsp_mix_gain_avx(void *obj, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src[], float gain[], uint32_t n_src, uint32_t n_samples) @@ -75,7 +75,7 @@ void dsp_mix_gain_avx(struct dsp_ops *ops, } } -void dsp_sum_avx(struct dsp_ops *ops, float *r, const float *a, const float *b, uint32_t n_samples) +void dsp_sum_avx(void *obj, float *r, const float *a, const float *b, uint32_t n_samples) { uint32_t n, unrolled; __m256 in[4]; @@ -138,7 +138,7 @@ inline static __m256 _mm256_mul_pz(__m256 ab, __m256 cd) return _mm256_addsub_ps(x0, x1); } -void dsp_fft_cmul_avx(struct dsp_ops *ops, void *fft, +void dsp_fft_cmul_avx(void *obj, void *fft, float * SPA_RESTRICT dst, const float * SPA_RESTRICT a, const float * SPA_RESTRICT b, uint32_t len, const float scale) { @@ -175,7 +175,7 @@ void dsp_fft_cmul_avx(struct dsp_ops *ops, void *fft, #endif } -void dsp_fft_cmuladd_avx(struct dsp_ops *ops, void *fft, +void dsp_fft_cmuladd_avx(void *obj, void *fft, float * SPA_RESTRICT dst, const float * SPA_RESTRICT src, const float * SPA_RESTRICT a, const float * SPA_RESTRICT b, uint32_t len, const float scale) diff --git a/src/modules/module-filter-chain/dsp-ops-c.c b/src/modules/module-filter-chain/audio-dsp-c.c similarity index 73% rename from src/modules/module-filter-chain/dsp-ops-c.c rename to src/modules/module-filter-chain/audio-dsp-c.c index d5f681ce2..ab018c0e0 100644 --- a/src/modules/module-filter-chain/dsp-ops-c.c +++ b/src/modules/module-filter-chain/audio-dsp-c.c @@ -16,21 +16,21 @@ #else #include "pffft.h" #endif -#include "dsp-ops-impl.h" +#include "audio-dsp-impl.h" -void dsp_clear_c(struct dsp_ops *ops, void * SPA_RESTRICT dst, uint32_t n_samples) +void dsp_clear_c(void *obj, void * SPA_RESTRICT dst, uint32_t n_samples) { memset(dst, 0, sizeof(float) * n_samples); } -void dsp_copy_c(struct dsp_ops *ops, void * SPA_RESTRICT dst, +void dsp_copy_c(void *obj, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src, uint32_t n_samples) { if (dst != src) spa_memcpy(dst, src, sizeof(float) * n_samples); } -static inline void dsp_add_c(struct dsp_ops *ops, void * SPA_RESTRICT dst, +static inline void dsp_add_c(void *obj, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src, uint32_t n_samples) { uint32_t i; @@ -40,23 +40,23 @@ static inline void dsp_add_c(struct dsp_ops *ops, void * SPA_RESTRICT dst, d[i] += s[i]; } -static inline void dsp_gain_c(struct dsp_ops *ops, void * SPA_RESTRICT dst, +static inline void dsp_gain_c(void *obj, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src, float gain, uint32_t n_samples) { uint32_t i; const float *s = src; float *d = dst; if (gain == 0.0f) - dsp_clear_c(ops, dst, n_samples); + dsp_clear_c(obj, dst, n_samples); else if (gain == 1.0f) - dsp_copy_c(ops, dst, src, n_samples); + dsp_copy_c(obj, dst, src, n_samples); else { for (i = 0; i < n_samples; i++) d[i] = s[i] * gain; } } -static inline void dsp_gain_add_c(struct dsp_ops *ops, void * SPA_RESTRICT dst, +static inline void dsp_gain_add_c(void *obj, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src, float gain, uint32_t n_samples) { uint32_t i; @@ -66,7 +66,7 @@ static inline void dsp_gain_add_c(struct dsp_ops *ops, void * SPA_RESTRICT dst, if (gain == 0.0f) return; else if (gain == 1.0f) - dsp_add_c(ops, dst, src, n_samples); + dsp_add_c(obj, dst, src, n_samples); else { for (i = 0; i < n_samples; i++) d[i] += s[i] * gain; @@ -74,22 +74,22 @@ static inline void dsp_gain_add_c(struct dsp_ops *ops, void * SPA_RESTRICT dst, } -void dsp_mix_gain_c(struct dsp_ops *ops, +void dsp_mix_gain_c(void *obj, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src[], float gain[], uint32_t n_src, uint32_t n_samples) { uint32_t i; if (n_src == 0) { - dsp_clear_c(ops, dst, n_samples); + dsp_clear_c(obj, dst, n_samples); } else { - dsp_gain_c(ops, dst, src[0], gain[0], n_samples); + dsp_gain_c(obj, dst, src[0], gain[0], n_samples); for (i = 1; i < n_src; i++) - dsp_gain_add_c(ops, dst, src[i], gain[i], n_samples); + dsp_gain_add_c(obj, dst, src[i], gain[i], n_samples); } } -static inline void dsp_mult1_c(struct dsp_ops *ops, void * SPA_RESTRICT dst, +static inline void dsp_mult1_c(void *obj, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src, uint32_t n_samples) { uint32_t i; @@ -99,22 +99,22 @@ static inline void dsp_mult1_c(struct dsp_ops *ops, void * SPA_RESTRICT dst, d[i] *= s[i]; } -void dsp_mult_c(struct dsp_ops *ops, +void dsp_mult_c(void *obj, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src[], uint32_t n_src, uint32_t n_samples) { uint32_t i; if (n_src == 0) { - dsp_clear_c(ops, dst, n_samples); + dsp_clear_c(obj, dst, n_samples); } else { - dsp_copy_c(ops, dst, src[0], n_samples); + dsp_copy_c(obj, dst, src[0], n_samples); for (i = 1; i < n_src; i++) - dsp_mult1_c(ops, dst, src[i], n_samples); + dsp_mult1_c(obj, dst, src[i], n_samples); } } -static void biquad_run_c(struct dsp_ops *ops, struct biquad *bq, +static void biquad_run_c(void *obj, struct biquad *bq, float *out, const float *in, uint32_t n_samples) { float x, y, x1, x2; @@ -122,7 +122,7 @@ static void biquad_run_c(struct dsp_ops *ops, struct biquad *bq, uint32_t i; if (bq->type == BQ_NONE) { - dsp_copy_c(ops, out, in, n_samples); + dsp_copy_c(obj, out, in, n_samples); return; } @@ -146,7 +146,7 @@ static void biquad_run_c(struct dsp_ops *ops, struct biquad *bq, #undef F } -void dsp_biquad_run_c(struct dsp_ops *ops, struct biquad *bq, uint32_t n_bq, uint32_t bq_stride, +void dsp_biquad_run_c(void *obj, struct biquad *bq, uint32_t n_bq, uint32_t bq_stride, float * SPA_RESTRICT out[], const float * SPA_RESTRICT in[], uint32_t n_src, uint32_t n_samples) { @@ -159,13 +159,13 @@ void dsp_biquad_run_c(struct dsp_ops *ops, struct biquad *bq, uint32_t n_bq, uin if (s == NULL || d == NULL) continue; if (n_bq > 0) - biquad_run_c(ops, &bq[0], d, s, n_samples); + biquad_run_c(obj, &bq[0], d, s, n_samples); for (j = 1; j < n_bq; j++) - biquad_run_c(ops, &bq[j], d, d, n_samples); + biquad_run_c(obj, &bq[j], d, d, n_samples); } } -void dsp_sum_c(struct dsp_ops *ops, float * dst, +void dsp_sum_c(void *obj, float * dst, const float * SPA_RESTRICT a, const float * SPA_RESTRICT b, uint32_t n_samples) { uint32_t i; @@ -173,13 +173,13 @@ void dsp_sum_c(struct dsp_ops *ops, float * dst, dst[i] = a[i] + b[i]; } -void dsp_linear_c(struct dsp_ops *ops, float * dst, +void dsp_linear_c(void *obj, float * dst, const float * SPA_RESTRICT src, const float mult, const float add, uint32_t n_samples) { uint32_t i; if (add == 0.0f) { - dsp_gain_c(ops, dst, src, mult, n_samples); + dsp_gain_c(obj, dst, src, mult, n_samples); } else { if (mult == 0.0f) { for (i = 0; i < n_samples; i++) @@ -195,11 +195,11 @@ void dsp_linear_c(struct dsp_ops *ops, float * dst, } -void dsp_delay_c(struct dsp_ops *ops, float *buffer, uint32_t *pos, uint32_t n_buffer, +void dsp_delay_c(void *obj, float *buffer, uint32_t *pos, uint32_t n_buffer, uint32_t delay, float *dst, const float *src, uint32_t n_samples) { if (delay == 0) { - dsp_copy_c(ops, dst, src, n_samples); + dsp_copy_c(obj, dst, src, n_samples); } else { uint32_t w, o, i; @@ -222,7 +222,7 @@ struct fft_info { }; #endif -void *dsp_fft_new_c(struct dsp_ops *ops, uint32_t size, bool real) +void *dsp_fft_new_c(void *obj, uint32_t size, bool real) { #ifdef HAVE_FFTW struct fft_info *info = calloc(1, sizeof(struct fft_info)); @@ -247,7 +247,7 @@ void *dsp_fft_new_c(struct dsp_ops *ops, uint32_t size, bool real) #endif } -void dsp_fft_free_c(struct dsp_ops *ops, void *fft) +void dsp_fft_free_c(void *obj, void *fft) { #ifdef HAVE_FFTW struct fft_info *info = fft; @@ -259,7 +259,7 @@ void dsp_fft_free_c(struct dsp_ops *ops, void *fft) #endif } -void *dsp_fft_memalloc_c(struct dsp_ops *ops, uint32_t size, bool real) +void *dsp_fft_memalloc_c(void *obj, uint32_t size, bool real) { #ifdef HAVE_FFTW if (real) @@ -274,7 +274,7 @@ void *dsp_fft_memalloc_c(struct dsp_ops *ops, uint32_t size, bool real) #endif } -void dsp_fft_memfree_c(struct dsp_ops *ops, void *data) +void dsp_fft_memfree_c(void *obj, void *data) { #ifdef HAVE_FFTW fftwf_free(data); @@ -283,16 +283,16 @@ void dsp_fft_memfree_c(struct dsp_ops *ops, void *data) #endif } -void dsp_fft_memclear_c(struct dsp_ops *ops, void *data, uint32_t size, bool real) +void dsp_fft_memclear_c(void *obj, void *data, uint32_t size, bool real) { #ifdef HAVE_FFTW - dsp_ops_clear(ops, data, real ? size : size * 2); + spa_fga_dsp_clear(obj, data, real ? size : size * 2); #else - dsp_ops_clear(ops, data, real ? size : size * 2); + spa_fga_dsp_clear(obj, data, real ? size : size * 2); #endif } -void dsp_fft_run_c(struct dsp_ops *ops, void *fft, int direction, +void dsp_fft_run_c(void *obj, void *fft, int direction, const float * SPA_RESTRICT src, float * SPA_RESTRICT dst) { #ifdef HAVE_FFTW @@ -306,7 +306,7 @@ void dsp_fft_run_c(struct dsp_ops *ops, void *fft, int direction, #endif } -void dsp_fft_cmul_c(struct dsp_ops *ops, void *fft, +void dsp_fft_cmul_c(void *obj, void *fft, float * SPA_RESTRICT dst, const float * SPA_RESTRICT a, const float * SPA_RESTRICT b, uint32_t len, const float scale) { @@ -320,7 +320,7 @@ void dsp_fft_cmul_c(struct dsp_ops *ops, void *fft, #endif } -void dsp_fft_cmuladd_c(struct dsp_ops *ops, void *fft, +void dsp_fft_cmuladd_c(void *obj, void *fft, float * SPA_RESTRICT dst, const float * SPA_RESTRICT src, const float * SPA_RESTRICT a, const float * SPA_RESTRICT b, uint32_t len, const float scale) diff --git a/src/modules/module-filter-chain/dsp-ops-impl.h b/src/modules/module-filter-chain/audio-dsp-impl.h similarity index 63% rename from src/modules/module-filter-chain/dsp-ops-impl.h rename to src/modules/module-filter-chain/audio-dsp-impl.h index 205510daa..8d1a86475 100644 --- a/src/modules/module-filter-chain/dsp-ops-impl.h +++ b/src/modules/module-filter-chain/audio-dsp-impl.h @@ -2,56 +2,57 @@ /* SPDX-FileCopyrightText: Copyright © 2022 Wim Taymans */ /* SPDX-License-Identifier: MIT */ -#ifndef DSP_OPS_IMPL_H -#define DSP_OPS_IMPL_H +#ifndef DSP_IMPL_H +#define DSP_IMPL_H -#include "dsp-ops.h" +#include "audio-dsp.h" -int dsp_ops_init(struct dsp_ops *ops, uint32_t cpu_flags); +struct spa_fga_dsp * spa_fga_dsp_new(uint32_t cpu_flags); +void spa_fga_dsp_free(struct spa_fga_dsp *dsp); #define MAKE_CLEAR_FUNC(arch) \ -void dsp_clear_##arch(struct dsp_ops *ops, void * SPA_RESTRICT dst, uint32_t n_samples) +void dsp_clear_##arch(void *obj, void * SPA_RESTRICT dst, uint32_t n_samples) #define MAKE_COPY_FUNC(arch) \ -void dsp_copy_##arch(struct dsp_ops *ops, void * SPA_RESTRICT dst, \ +void dsp_copy_##arch(void *obj, void * SPA_RESTRICT dst, \ const void * SPA_RESTRICT src, uint32_t n_samples) #define MAKE_MIX_GAIN_FUNC(arch) \ -void dsp_mix_gain_##arch(struct dsp_ops *ops, void * SPA_RESTRICT dst, \ +void dsp_mix_gain_##arch(void *obj, void * SPA_RESTRICT dst, \ const void * SPA_RESTRICT src[], float gain[], uint32_t n_src, uint32_t n_samples) #define MAKE_SUM_FUNC(arch) \ -void dsp_sum_##arch (struct dsp_ops *ops, float * SPA_RESTRICT dst, \ +void dsp_sum_##arch (void *obj, float * SPA_RESTRICT dst, \ const float * SPA_RESTRICT a, const float * SPA_RESTRICT b, uint32_t n_samples) #define MAKE_LINEAR_FUNC(arch) \ -void dsp_linear_##arch (struct dsp_ops *ops, float * SPA_RESTRICT dst, \ +void dsp_linear_##arch (void *obj, float * SPA_RESTRICT dst, \ const float * SPA_RESTRICT src, const float mult, const float add, uint32_t n_samples) #define MAKE_MULT_FUNC(arch) \ -void dsp_mult_##arch(struct dsp_ops *ops, void * SPA_RESTRICT dst, \ +void dsp_mult_##arch(void *obj, void * SPA_RESTRICT dst, \ const void * SPA_RESTRICT src[], uint32_t n_src, uint32_t n_samples) #define MAKE_BIQUAD_RUN_FUNC(arch) \ -void dsp_biquad_run_##arch (struct dsp_ops *ops, struct biquad *bq, uint32_t n_bq, uint32_t bq_stride, \ +void dsp_biquad_run_##arch (void *obj, struct biquad *bq, uint32_t n_bq, uint32_t bq_stride, \ float * SPA_RESTRICT out[], const float * SPA_RESTRICT in[], uint32_t n_src, uint32_t n_samples) #define MAKE_DELAY_FUNC(arch) \ -void dsp_delay_##arch (struct dsp_ops *ops, float *buffer, uint32_t *pos, uint32_t n_buffer, \ +void dsp_delay_##arch (void *obj, float *buffer, uint32_t *pos, uint32_t n_buffer, \ uint32_t delay, float *dst, const float *src, uint32_t n_samples) #define MAKE_FFT_NEW_FUNC(arch) \ -void *dsp_fft_new_##arch(struct dsp_ops *ops, uint32_t size, bool real) +void *dsp_fft_new_##arch(void *obj, uint32_t size, bool real) #define MAKE_FFT_FREE_FUNC(arch) \ -void dsp_fft_free_##arch(struct dsp_ops *ops, void *fft) +void dsp_fft_free_##arch(void *obj, void *fft) #define MAKE_FFT_MEMALLOC_FUNC(arch) \ -void *dsp_fft_memalloc_##arch(struct dsp_ops *ops, uint32_t size, bool real) +void *dsp_fft_memalloc_##arch(void *obj, uint32_t size, bool real) #define MAKE_FFT_MEMFREE_FUNC(arch) \ -void dsp_fft_memfree_##arch(struct dsp_ops *ops, void *mem) +void dsp_fft_memfree_##arch(void *obj, void *mem) #define MAKE_FFT_MEMCLEAR_FUNC(arch) \ -void dsp_fft_memclear_##arch(struct dsp_ops *ops, void *mem, uint32_t size, bool real) +void dsp_fft_memclear_##arch(void *obj, void *mem, uint32_t size, bool real) #define MAKE_FFT_RUN_FUNC(arch) \ -void dsp_fft_run_##arch(struct dsp_ops *ops, void *fft, int direction, \ +void dsp_fft_run_##arch(void *obj, void *fft, int direction, \ const float * SPA_RESTRICT src, float * SPA_RESTRICT dst) #define MAKE_FFT_CMUL_FUNC(arch) \ -void dsp_fft_cmul_##arch(struct dsp_ops *ops, void *fft, \ +void dsp_fft_cmul_##arch(void *obj, void *fft, \ float * SPA_RESTRICT dst, const float * SPA_RESTRICT a, \ const float * SPA_RESTRICT b, uint32_t len, const float scale) #define MAKE_FFT_CMULADD_FUNC(arch) \ -void dsp_fft_cmuladd_##arch(struct dsp_ops *ops, void *fft, \ +void dsp_fft_cmuladd_##arch(void *obj, void *fft, \ float * dst, const float * src, \ const float * SPA_RESTRICT a, const float * SPA_RESTRICT b, \ uint32_t len, const float scale) diff --git a/src/modules/module-filter-chain/dsp-ops-sse.c b/src/modules/module-filter-chain/audio-dsp-sse.c similarity index 92% rename from src/modules/module-filter-chain/dsp-ops-sse.c rename to src/modules/module-filter-chain/audio-dsp-sse.c index c218f1bc6..deb3fc668 100644 --- a/src/modules/module-filter-chain/dsp-ops-sse.c +++ b/src/modules/module-filter-chain/audio-dsp-sse.c @@ -15,11 +15,11 @@ #include "pffft.h" #endif -#include "dsp-ops-impl.h" +#include "audio-dsp-impl.h" #include -void dsp_mix_gain_sse(struct dsp_ops *ops, +void dsp_mix_gain_sse(void *obj, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src[], float gain[], uint32_t n_src, uint32_t n_samples) @@ -77,7 +77,7 @@ void dsp_mix_gain_sse(struct dsp_ops *ops, } } -void dsp_sum_sse(struct dsp_ops *ops, float *r, const float *a, const float *b, uint32_t n_samples) +void dsp_sum_sse(void *obj, float *r, const float *a, const float *b, uint32_t n_samples) { uint32_t n, unrolled; __m128 in[4]; @@ -128,7 +128,7 @@ void dsp_sum_sse(struct dsp_ops *ops, float *r, const float *a, const float *b, } } -static void dsp_biquad_run1_sse(struct dsp_ops *ops, struct biquad *bq, +static void dsp_biquad_run1_sse(void *obj, struct biquad *bq, float *out, const float *in, uint32_t n_samples) { __m128 x, y, z; @@ -157,7 +157,7 @@ static void dsp_biquad_run1_sse(struct dsp_ops *ops, struct biquad *bq, #undef F } -static void dsp_biquad2_run_sse(struct dsp_ops *ops, struct biquad *bq, +static void dsp_biquad2_run_sse(void *obj, struct biquad *bq, float *out, const float *in, uint32_t n_samples) { __m128 x, y, z; @@ -201,7 +201,7 @@ static void dsp_biquad2_run_sse(struct dsp_ops *ops, struct biquad *bq, #undef F } -static void dsp_biquad_run2_sse(struct dsp_ops *ops, struct biquad *bq, uint32_t bq_stride, +static void dsp_biquad_run2_sse(void *obj, struct biquad *bq, uint32_t bq_stride, float **out, const float **in, uint32_t n_samples) { __m128 x, y, z; @@ -243,7 +243,7 @@ static void dsp_biquad_run2_sse(struct dsp_ops *ops, struct biquad *bq, uint32_t } -static void dsp_biquad2_run2_sse(struct dsp_ops *ops, struct biquad *bq, uint32_t bq_stride, +static void dsp_biquad2_run2_sse(void *obj, struct biquad *bq, uint32_t bq_stride, float **out, const float **in, uint32_t n_samples) { __m128 x, y, z; @@ -309,7 +309,7 @@ static void dsp_biquad2_run2_sse(struct dsp_ops *ops, struct biquad *bq, uint32_ #undef F } -static void dsp_biquad_run4_sse(struct dsp_ops *ops, struct biquad *bq, uint32_t bq_stride, +static void dsp_biquad_run4_sse(void *obj, struct biquad *bq, uint32_t bq_stride, float **out, const float **in, uint32_t n_samples) { __m128 x, y, z; @@ -356,7 +356,7 @@ static void dsp_biquad_run4_sse(struct dsp_ops *ops, struct biquad *bq, uint32_t #undef F } -static void dsp_biquad2_run4_sse(struct dsp_ops *ops, struct biquad *bq, uint32_t bq_stride, +static void dsp_biquad2_run4_sse(void *obj, struct biquad *bq, uint32_t bq_stride, float **out, const float **in, uint32_t n_samples) { __m128 x, y, z; @@ -432,7 +432,7 @@ static void dsp_biquad2_run4_sse(struct dsp_ops *ops, struct biquad *bq, uint32_ #undef F } -void dsp_biquad_run_sse(struct dsp_ops *ops, struct biquad *bq, uint32_t n_bq, uint32_t bq_stride, +void dsp_biquad_run_sse(void *obj, struct biquad *bq, uint32_t n_bq, uint32_t bq_stride, float * SPA_RESTRICT out[], const float * SPA_RESTRICT in[], uint32_t n_src, uint32_t n_samples) { @@ -451,7 +451,7 @@ void dsp_biquad_run_sse(struct dsp_ops *ops, struct biquad *bq, uint32_t n_bq, u j = 0; if (j < junrolled2) { - dsp_biquad2_run4_sse(ops, &bq[j], bq_stride, d, s, n_samples); + dsp_biquad2_run4_sse(obj, &bq[j], bq_stride, d, s, n_samples); s[0] = d[0]; s[1] = d[1]; s[2] = d[2]; @@ -459,10 +459,10 @@ void dsp_biquad_run_sse(struct dsp_ops *ops, struct biquad *bq, uint32_t n_bq, u j+=2; } for (; j < junrolled2; j+=2) { - dsp_biquad2_run4_sse(ops, &bq[j], bq_stride, d, s, n_samples); + dsp_biquad2_run4_sse(obj, &bq[j], bq_stride, d, s, n_samples); } if (j < n_bq) { - dsp_biquad_run4_sse(ops, &bq[j], bq_stride, d, s, n_samples); + dsp_biquad_run4_sse(obj, &bq[j], bq_stride, d, s, n_samples); } } for (; i < iunrolled2; i+=2, bq+=bqs2) { @@ -474,16 +474,16 @@ void dsp_biquad_run_sse(struct dsp_ops *ops, struct biquad *bq, uint32_t n_bq, u j = 0; if (j < junrolled2) { - dsp_biquad2_run2_sse(ops, &bq[j], bq_stride, d, s, n_samples); + dsp_biquad2_run2_sse(obj, &bq[j], bq_stride, d, s, n_samples); s[0] = d[0]; s[1] = d[1]; j+=2; } for (; j < junrolled2; j+=2) { - dsp_biquad2_run2_sse(ops, &bq[j], bq_stride, d, s, n_samples); + dsp_biquad2_run2_sse(obj, &bq[j], bq_stride, d, s, n_samples); } if (j < n_bq) { - dsp_biquad_run2_sse(ops, &bq[j], bq_stride, d, s, n_samples); + dsp_biquad_run2_sse(obj, &bq[j], bq_stride, d, s, n_samples); } } for (; i < n_src; i++, bq+=bq_stride) { @@ -494,20 +494,20 @@ void dsp_biquad_run_sse(struct dsp_ops *ops, struct biquad *bq, uint32_t n_bq, u j = 0; if (j < junrolled2) { - dsp_biquad2_run_sse(ops, &bq[j], d, s, n_samples); + dsp_biquad2_run_sse(obj, &bq[j], d, s, n_samples); s = d; j+=2; } for (; j < junrolled2; j+=2) { - dsp_biquad2_run_sse(ops, &bq[j], d, s, n_samples); + dsp_biquad2_run_sse(obj, &bq[j], d, s, n_samples); } if (j < n_bq) { - dsp_biquad_run1_sse(ops, &bq[j], d, s, n_samples); + dsp_biquad_run1_sse(obj, &bq[j], d, s, n_samples); } } } -void dsp_delay_sse(struct dsp_ops *ops, float *buffer, uint32_t *pos, uint32_t n_buffer, uint32_t delay, +void dsp_delay_sse(void *obj, float *buffer, uint32_t *pos, uint32_t n_buffer, uint32_t delay, float *dst, const float *src, uint32_t n_samples) { __m128 t[1]; @@ -560,7 +560,7 @@ inline static void _mm_mul_pz(__m128 *a, __m128 *b, __m128 *d) d[1] = _mm_unpackhi_ps(dr, di); } -void dsp_fft_cmul_sse(struct dsp_ops *ops, void *fft, +void dsp_fft_cmul_sse(void *obj, void *fft, float * SPA_RESTRICT dst, const float * SPA_RESTRICT a, const float * SPA_RESTRICT b, uint32_t len, const float scale) { @@ -596,7 +596,7 @@ void dsp_fft_cmul_sse(struct dsp_ops *ops, void *fft, #endif } -void dsp_fft_cmuladd_sse(struct dsp_ops *ops, void *fft, +void dsp_fft_cmuladd_sse(void *obj, void *fft, float * SPA_RESTRICT dst, const float * SPA_RESTRICT src, const float * SPA_RESTRICT a, const float * SPA_RESTRICT b, uint32_t len, const float scale) diff --git a/src/modules/module-filter-chain/dsp-ops.c b/src/modules/module-filter-chain/audio-dsp.c similarity index 82% rename from src/modules/module-filter-chain/dsp-ops.c rename to src/modules/module-filter-chain/audio-dsp.c index ffd2983bf..1ba0b981c 100644 --- a/src/modules/module-filter-chain/dsp-ops.c +++ b/src/modules/module-filter-chain/audio-dsp.c @@ -11,15 +11,15 @@ #include #include -#include "dsp-ops-impl.h" +#include "audio-dsp-impl.h" struct dsp_info { uint32_t cpu_flags; - struct dsp_ops_funcs funcs; + struct spa_fga_dsp_methods funcs; }; -static struct dsp_info dsp_table[] = +static const struct dsp_info dsp_table[] = { #if defined (HAVE_AVX) { SPA_CPU_FLAG_AVX, @@ -92,23 +92,30 @@ static const struct dsp_info *find_dsp_info(uint32_t cpu_flags) return NULL; } -static void impl_dsp_ops_free(struct dsp_ops *ops) +void spa_fga_dsp_free(struct spa_fga_dsp *dsp) { - spa_zero(*ops); + free(dsp); } -int dsp_ops_init(struct dsp_ops *ops, uint32_t cpu_flags) +struct spa_fga_dsp * spa_fga_dsp_new(uint32_t cpu_flags) { const struct dsp_info *info; + struct spa_fga_dsp *dsp; info = find_dsp_info(cpu_flags); - if (info == NULL) - return -ENOTSUP; + if (info == NULL) { + errno = ENOTSUP; + return NULL; + } + dsp = calloc(1, sizeof(*dsp)); + if (dsp == NULL) + return NULL; - ops->cpu_flags = cpu_flags; - ops->priv = info; - ops->free = impl_dsp_ops_free; - ops->funcs = info->funcs; + dsp->cpu_flags = cpu_flags; + dsp->iface = SPA_INTERFACE_INIT( + SPA_TYPE_INTERFACE_FILTER_GRAPH_AudioDSP, + SPA_VERSION_FGA_DSP, + &info->funcs, dsp); - return 0; + return dsp; } diff --git a/src/modules/module-filter-chain/audio-dsp.h b/src/modules/module-filter-chain/audio-dsp.h new file mode 100644 index 000000000..8519b830b --- /dev/null +++ b/src/modules/module-filter-chain/audio-dsp.h @@ -0,0 +1,103 @@ +/* Spa */ +/* SPDX-FileCopyrightText: Copyright © 2022 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_FGA_DSP_H +#define SPA_FGA_DSP_H + +#include +#include + +#include "biquad.h" + +#define SPA_TYPE_INTERFACE_FILTER_GRAPH_AudioDSP SPA_TYPE_INFO_INTERFACE_BASE "FilterGraph:AudioDSP" + +#define SPA_VERSION_FGA_DSP 0 +struct spa_fga_dsp { + struct spa_interface iface; + uint32_t cpu_flags; +}; + +struct spa_fga_dsp_methods { +#define SPA_VERSION_FGA_DSP_METHODS 0 + uint32_t version; + + void (*clear) (void *obj, void * SPA_RESTRICT dst, uint32_t n_samples); + void (*copy) (void *obj, + void * SPA_RESTRICT dst, + const void * SPA_RESTRICT src, uint32_t n_samples); + void (*mix_gain) (void *obj, + void * SPA_RESTRICT dst, + const void * SPA_RESTRICT src[], + float gain[], uint32_t n_src, uint32_t n_samples); + void (*sum) (void *obj, + float * dst, const float * SPA_RESTRICT a, + const float * SPA_RESTRICT b, uint32_t n_samples); + + void *(*fft_new) (void *obj, uint32_t size, bool real); + void (*fft_free) (void *obj, void *fft); + void *(*fft_memalloc) (void *obj, uint32_t size, bool real); + void (*fft_memfree) (void *obj, void *mem); + void (*fft_memclear) (void *obj, void *mem, uint32_t size, bool real); + void (*fft_run) (void *obj, void *fft, int direction, + const float * SPA_RESTRICT src, float * SPA_RESTRICT dst); + void (*fft_cmul) (void *obj, void *fft, + float * SPA_RESTRICT dst, const float * SPA_RESTRICT a, + const float * SPA_RESTRICT b, uint32_t len, const float scale); + void (*fft_cmuladd) (void *obj, void *fft, + float * dst, const float * src, + const float * SPA_RESTRICT a, const float * SPA_RESTRICT b, + uint32_t len, const float scale); + void (*linear) (void *obj, + float * dst, const float * SPA_RESTRICT src, + const float mult, const float add, uint32_t n_samples); + void (*mult) (void *obj, + void * SPA_RESTRICT dst, + const void * SPA_RESTRICT src[], uint32_t n_src, uint32_t n_samples); + void (*biquad_run) (void *obj, struct biquad *bq, uint32_t n_bq, uint32_t bq_stride, + float * SPA_RESTRICT out[], const float * SPA_RESTRICT in[], + uint32_t n_src, uint32_t n_samples); + void (*delay) (void *obj, float *buffer, uint32_t *pos, uint32_t n_buffer, uint32_t delay, + float *dst, const float *src, uint32_t n_samples); +}; + +#define spa_fga_dsp_method_r(o,type,method,version,...) \ +({ \ + type _res = NULL; \ + struct spa_fga_dsp *_o = o; \ + spa_interface_call_fast_res(&_o->iface, \ + struct spa_fga_dsp_methods, _res, \ + method, version, ##__VA_ARGS__); \ + _res; \ +}) + + +#define spa_fga_dsp_method(o,method,version,...) \ +({ \ + struct spa_fga_dsp *_o = o; \ + spa_interface_call_fast(&_o->iface, \ + struct spa_fga_dsp_methods, \ + method, version, ##__VA_ARGS__); \ +}) + + +#define spa_fga_dsp_clear(o,...) spa_fga_dsp_method(o,clear,0,__VA_ARGS__) +#define spa_fga_dsp_copy(o,...) spa_fga_dsp_method(o,copy,0,__VA_ARGS__) +#define spa_fga_dsp_mix_gain(o,...) spa_fga_dsp_method(o,mix_gain,0,__VA_ARGS__) +#define spa_fga_dsp_biquad_run(o,...) spa_fga_dsp_method(o,biquad_run,0,__VA_ARGS__) +#define spa_fga_dsp_sum(o,...) spa_fga_dsp_method(o,sum,0,__VA_ARGS__) +#define spa_fga_dsp_linear(o,...) spa_fga_dsp_method(o,linear,0,__VA_ARGS__) +#define spa_fga_dsp_mult(o,...) spa_fga_dsp_method(o,mult,0,__VA_ARGS__) +#define spa_fga_dsp_delay(o,...) spa_fga_dsp_method(o,delay,0,__VA_ARGS__) + +#define spa_fga_dsp_fft_new(o,...) spa_fga_dsp_method_r(o,void*,fft_new,0,__VA_ARGS__) +#define spa_fga_dsp_fft_free(o,...) spa_fga_dsp_method(o,fft_free,0,__VA_ARGS__) +#define spa_fga_dsp_fft_memalloc(o,...) spa_fga_dsp_method_r(o,void*,fft_memalloc,0,__VA_ARGS__) +#define spa_fga_dsp_fft_memfree(o,...) spa_fga_dsp_method(o,fft_memfree,0,__VA_ARGS__) +#define spa_fga_dsp_fft_memclear(o,...) spa_fga_dsp_method(o,fft_memclear,0,__VA_ARGS__) +#define spa_fga_dsp_fft_run(o,...) spa_fga_dsp_method(o,fft_run,0,__VA_ARGS__) +#define spa_fga_dsp_fft_cmul(o,...) spa_fga_dsp_method(o,fft_cmul,0,__VA_ARGS__) +#define spa_fga_dsp_fft_cmul(o,...) spa_fga_dsp_method(o,fft_cmul,0,__VA_ARGS__) +#define spa_fga_dsp_fft_cmuladd(o,...) spa_fga_dsp_method(o,fft_cmuladd,0,__VA_ARGS__) + +#endif /* SPA_FGA_DSP_H */ diff --git a/src/modules/module-filter-chain/audio-plugin.h b/src/modules/module-filter-chain/audio-plugin.h index d212d8209..124873487 100644 --- a/src/modules/module-filter-chain/audio-plugin.h +++ b/src/modules/module-filter-chain/audio-plugin.h @@ -12,9 +12,6 @@ #include #include -#include "dsp-ops.h" - - #define SPA_TYPE_INTERFACE_FILTER_GRAPH_AudioPlugin SPA_TYPE_INFO_INTERFACE_BASE "FilterGraph:AudioPlugin" #define SPA_VERSION_FGA_PLUGIN 0 @@ -105,8 +102,7 @@ static inline void spa_fga_descriptor_free(const struct spa_fga_descriptor *desc #define spa_fga_plugin_free(o,...) spa_fga_plugin_method(o,free,0,##__VA_ARGS__) typedef struct spa_fga_plugin *(spa_filter_graph_audio_plugin_load_func_t)(const struct spa_support *support, - uint32_t n_support, struct dsp_ops *dsp, - const char *path, const struct spa_dict *info); + uint32_t n_support, const char *path, const struct spa_dict *info); #define SPA_FILTER_GRAPH_AUDIO_PLUGIN_LOAD_FUNC_NAME "spa_filter_graph_audio_plugin_load" diff --git a/src/modules/module-filter-chain/builtin_plugin.c b/src/modules/module-filter-chain/builtin_plugin.c index d7d8eb989..fd152ca9f 100644 --- a/src/modules/module-filter-chain/builtin_plugin.c +++ b/src/modules/module-filter-chain/builtin_plugin.c @@ -23,20 +23,20 @@ #include "biquad.h" #include "pffft.h" #include "convolver.h" -#include "dsp-ops.h" +#include "audio-dsp.h" #define MAX_RATES 32u struct plugin { struct spa_fga_plugin plugin; - struct dsp_ops *dsp; + struct spa_fga_dsp *dsp; struct spa_log *log; }; struct builtin { struct plugin *plugin; - struct dsp_ops *dsp; + struct spa_fga_dsp *dsp; struct spa_log *log; unsigned long rate; @@ -86,7 +86,7 @@ static void copy_run(void * Instance, unsigned long SampleCount) { struct builtin *impl = Instance; float *in = impl->port[1], *out = impl->port[0]; - dsp_ops_copy(impl->dsp, out, in, SampleCount); + spa_fga_dsp_copy(impl->dsp, out, in, SampleCount); } static struct spa_fga_port copy_ports[] = { @@ -135,7 +135,7 @@ static void mixer_run(void * Instance, unsigned long SampleCount) src[n_src] = in; gains[n_src++] = gain; } - dsp_ops_mix_gain(impl->dsp, out, src, gains, n_src, SampleCount); + spa_fga_dsp_mix_gain(impl->dsp, out, src, gains, n_src, SampleCount); } static struct spa_fga_port mixer_ports[] = { @@ -540,7 +540,7 @@ static void bq_run(void *Instance, unsigned long samples) if (impl->freq != freq || impl->Q != Q || impl->gain != gain) bq_freq_update(impl, impl->type, freq, Q, gain); } - dsp_ops_biquad_run(impl->dsp, bq, 1, 0, &out, (const float **)&in, 1, samples); + spa_fga_dsp_biquad_run(impl->dsp, bq, 1, 0, &out, (const float **)&in, 1, samples); } /** bq_lowpass */ @@ -675,7 +675,7 @@ struct convolver_impl { struct plugin *plugin; struct spa_log *log; - struct dsp_ops *dsp; + struct spa_fga_dsp *dsp; unsigned long rate; float *port[2]; @@ -1124,7 +1124,7 @@ static const struct spa_fga_descriptor convolve_desc = { struct delay_impl { struct plugin *plugin; - struct dsp_ops *dsp; + struct spa_fga_dsp *dsp; struct spa_log *log; unsigned long rate; @@ -1220,7 +1220,7 @@ static void delay_run(void * Instance, unsigned long SampleCount) impl->delay_samples = SPA_CLAMP((uint32_t)(delay * impl->rate), 0u, impl->buffer_samples-1); impl->delay = delay; } - dsp_ops_delay(impl->dsp, impl->buffer, &impl->ptr, impl->buffer_samples, + spa_fga_dsp_delay(impl->dsp, impl->buffer, &impl->ptr, impl->buffer_samples, impl->delay_samples, out, in, SampleCount); } @@ -1354,7 +1354,7 @@ static void linear_run(void * Instance, unsigned long SampleCount) float *ctrl = impl->port[3], *notify = impl->port[2]; if (in != NULL && out != NULL) - dsp_ops_linear(impl->dsp, out, in, mult, add, SampleCount); + spa_fga_dsp_linear(impl->dsp, out, in, mult, add, SampleCount); if (ctrl != NULL && notify != NULL) notify[0] = ctrl[0] * mult + add; @@ -1599,7 +1599,7 @@ static void mult_run(void * Instance, unsigned long SampleCount) src[n_src++] = in; } - dsp_ops_mult(impl->dsp, out, src, n_src, SampleCount); + spa_fga_dsp_mult(impl->dsp, out, src, n_src, SampleCount); } static struct spa_fga_port mult_ports[] = { @@ -1727,7 +1727,7 @@ static const struct spa_fga_descriptor sine_desc = { struct param_eq_impl { struct plugin *plugin; - struct dsp_ops *dsp; + struct spa_fga_dsp *dsp; struct spa_log *log; unsigned long rate; @@ -1993,7 +1993,7 @@ static void param_eq_connect_port(void * Instance, unsigned long Port, static void param_eq_run(void * Instance, unsigned long SampleCount) { struct param_eq_impl *impl = Instance; - dsp_ops_biquad_run(impl->dsp, impl->bq, impl->n_bq, PARAM_EQ_MAX, + spa_fga_dsp_biquad_run(impl->dsp, impl->bq, impl->n_bq, PARAM_EQ_MAX, &impl->port[8], (const float**)impl->port, 8, SampleCount); } @@ -2154,7 +2154,7 @@ static struct spa_fga_plugin_methods impl_plugin = { }; struct spa_fga_plugin *load_builtin_plugin(const struct spa_support *support, uint32_t n_support, - struct dsp_ops *dsp, const char *plugin, const struct spa_dict *info) + const char *plugin, const struct spa_dict *info) { struct plugin *impl = calloc (1, sizeof (struct plugin)); @@ -2163,8 +2163,8 @@ struct spa_fga_plugin *load_builtin_plugin(const struct spa_support *support, ui SPA_VERSION_FGA_PLUGIN, &impl_plugin, impl); - impl->dsp = dsp; - pffft_select_cpu(dsp->cpu_flags); + impl->dsp = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_FILTER_GRAPH_AudioDSP); + pffft_select_cpu(impl->dsp->cpu_flags); impl->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log); return (struct spa_fga_plugin *) impl; diff --git a/src/modules/module-filter-chain/convolver.c b/src/modules/module-filter-chain/convolver.c index 20d2a047e..d42b02773 100644 --- a/src/modules/module-filter-chain/convolver.c +++ b/src/modules/module-filter-chain/convolver.c @@ -11,7 +11,7 @@ #include struct convolver1 { - struct dsp_ops *dsp; + struct spa_fga_dsp *dsp; int blockSize; int segSize; @@ -49,11 +49,11 @@ static void convolver1_reset(struct convolver1 *conv) { int i; for (i = 0; i < conv->segCount; i++) - dsp_ops_fft_memclear(conv->dsp, conv->segments[i], conv->fftComplexSize, false); - dsp_ops_fft_memclear(conv->dsp, conv->overlap, conv->blockSize, true); - dsp_ops_fft_memclear(conv->dsp, conv->inputBuffer, conv->segSize, true); - dsp_ops_fft_memclear(conv->dsp, conv->pre_mult, conv->fftComplexSize, false); - dsp_ops_fft_memclear(conv->dsp, conv->conv, conv->fftComplexSize, false); + spa_fga_dsp_fft_memclear(conv->dsp, conv->segments[i], conv->fftComplexSize, false); + spa_fga_dsp_fft_memclear(conv->dsp, conv->overlap, conv->blockSize, true); + spa_fga_dsp_fft_memclear(conv->dsp, conv->inputBuffer, conv->segSize, true); + spa_fga_dsp_fft_memclear(conv->dsp, conv->pre_mult, conv->fftComplexSize, false); + spa_fga_dsp_fft_memclear(conv->dsp, conv->conv, conv->fftComplexSize, false); conv->inputBufferFill = 0; conv->current = 0; } @@ -63,26 +63,26 @@ static void convolver1_free(struct convolver1 *conv) int i; for (i = 0; i < conv->segCount; i++) { if (conv->segments) - dsp_ops_fft_memfree(conv->dsp, conv->segments[i]); + spa_fga_dsp_fft_memfree(conv->dsp, conv->segments[i]); if (conv->segmentsIr) - dsp_ops_fft_memfree(conv->dsp, conv->segmentsIr[i]); + spa_fga_dsp_fft_memfree(conv->dsp, conv->segmentsIr[i]); } if (conv->fft) - dsp_ops_fft_free(conv->dsp, conv->fft); + spa_fga_dsp_fft_free(conv->dsp, conv->fft); if (conv->ifft) - dsp_ops_fft_free(conv->dsp, conv->ifft); + spa_fga_dsp_fft_free(conv->dsp, conv->ifft); if (conv->fft_buffer) - dsp_ops_fft_memfree(conv->dsp, conv->fft_buffer); + spa_fga_dsp_fft_memfree(conv->dsp, conv->fft_buffer); free(conv->segments); free(conv->segmentsIr); - dsp_ops_fft_memfree(conv->dsp, conv->pre_mult); - dsp_ops_fft_memfree(conv->dsp, conv->conv); - dsp_ops_fft_memfree(conv->dsp, conv->overlap); - dsp_ops_fft_memfree(conv->dsp, conv->inputBuffer); + spa_fga_dsp_fft_memfree(conv->dsp, conv->pre_mult); + spa_fga_dsp_fft_memfree(conv->dsp, conv->conv); + spa_fga_dsp_fft_memfree(conv->dsp, conv->overlap); + spa_fga_dsp_fft_memfree(conv->dsp, conv->inputBuffer); free(conv); } -static struct convolver1 *convolver1_new(struct dsp_ops *dsp, int block, const float *ir, int irlen) +static struct convolver1 *convolver1_new(struct spa_fga_dsp *dsp, int block, const float *ir, int irlen) { struct convolver1 *conv; int i; @@ -106,14 +106,14 @@ static struct convolver1 *convolver1_new(struct dsp_ops *dsp, int block, const f conv->segCount = (irlen + conv->blockSize-1) / conv->blockSize; conv->fftComplexSize = (conv->segSize / 2) + 1; - conv->fft = dsp_ops_fft_new(conv->dsp, conv->segSize, true); + conv->fft = spa_fga_dsp_fft_new(conv->dsp, conv->segSize, true); if (conv->fft == NULL) goto error; - conv->ifft = dsp_ops_fft_new(conv->dsp, conv->segSize, true); + conv->ifft = spa_fga_dsp_fft_new(conv->dsp, conv->segSize, true); if (conv->ifft == NULL) goto error; - conv->fft_buffer = dsp_ops_fft_memalloc(conv->dsp, conv->segSize, true); + conv->fft_buffer = spa_fga_dsp_fft_memalloc(conv->dsp, conv->segSize, true); if (conv->fft_buffer == NULL) goto error; @@ -126,21 +126,21 @@ static struct convolver1 *convolver1_new(struct dsp_ops *dsp, int block, const f int left = irlen - (i * conv->blockSize); int copy = SPA_MIN(conv->blockSize, left); - conv->segments[i] = dsp_ops_fft_memalloc(conv->dsp, conv->fftComplexSize, false); - conv->segmentsIr[i] = dsp_ops_fft_memalloc(conv->dsp, conv->fftComplexSize, false); + conv->segments[i] = spa_fga_dsp_fft_memalloc(conv->dsp, conv->fftComplexSize, false); + conv->segmentsIr[i] = spa_fga_dsp_fft_memalloc(conv->dsp, conv->fftComplexSize, false); if (conv->segments[i] == NULL || conv->segmentsIr[i] == NULL) goto error; - dsp_ops_copy(conv->dsp, conv->fft_buffer, &ir[i * conv->blockSize], copy); + spa_fga_dsp_copy(conv->dsp, conv->fft_buffer, &ir[i * conv->blockSize], copy); if (copy < conv->segSize) - dsp_ops_fft_memclear(conv->dsp, conv->fft_buffer + copy, conv->segSize - copy, true); + spa_fga_dsp_fft_memclear(conv->dsp, conv->fft_buffer + copy, conv->segSize - copy, true); - dsp_ops_fft_run(conv->dsp, conv->fft, 1, conv->fft_buffer, conv->segmentsIr[i]); + spa_fga_dsp_fft_run(conv->dsp, conv->fft, 1, conv->fft_buffer, conv->segmentsIr[i]); } - conv->pre_mult = dsp_ops_fft_memalloc(conv->dsp, conv->fftComplexSize, false); - conv->conv = dsp_ops_fft_memalloc(conv->dsp, conv->fftComplexSize, false); - conv->overlap = dsp_ops_fft_memalloc(conv->dsp, conv->blockSize, true); - conv->inputBuffer = dsp_ops_fft_memalloc(conv->dsp, conv->segSize, true); + conv->pre_mult = spa_fga_dsp_fft_memalloc(conv->dsp, conv->fftComplexSize, false); + conv->conv = spa_fga_dsp_fft_memalloc(conv->dsp, conv->fftComplexSize, false); + conv->overlap = spa_fga_dsp_fft_memalloc(conv->dsp, conv->blockSize, true); + conv->inputBuffer = spa_fga_dsp_fft_memalloc(conv->dsp, conv->segSize, true); if (conv->pre_mult == NULL || conv->conv == NULL || conv->overlap == NULL || conv->inputBuffer == NULL) goto error; @@ -158,7 +158,7 @@ static int convolver1_run(struct convolver1 *conv, const float *input, float *ou int i, processed = 0; if (conv == NULL || conv->segCount == 0) { - dsp_ops_fft_memclear(conv->dsp, output, len, true); + spa_fga_dsp_fft_memclear(conv->dsp, output, len, true); return len; } @@ -166,17 +166,17 @@ static int convolver1_run(struct convolver1 *conv, const float *input, float *ou const int processing = SPA_MIN(len - processed, conv->blockSize - conv->inputBufferFill); const int inputBufferPos = conv->inputBufferFill; - dsp_ops_copy(conv->dsp, conv->inputBuffer + inputBufferPos, input + processed, processing); + spa_fga_dsp_copy(conv->dsp, conv->inputBuffer + inputBufferPos, input + processed, processing); if (inputBufferPos == 0 && processing < conv->blockSize) - dsp_ops_fft_memclear(conv->dsp, conv->inputBuffer + processing, conv->blockSize - processing, true); + spa_fga_dsp_fft_memclear(conv->dsp, conv->inputBuffer + processing, conv->blockSize - processing, true); - dsp_ops_fft_run(conv->dsp, conv->fft, 1, conv->inputBuffer, conv->segments[conv->current]); + spa_fga_dsp_fft_run(conv->dsp, conv->fft, 1, conv->inputBuffer, conv->segments[conv->current]); if (conv->segCount > 1) { if (conv->inputBufferFill == 0) { int indexAudio = (conv->current + 1) % conv->segCount; - dsp_ops_fft_cmul(conv->dsp, conv->fft, conv->pre_mult, + spa_fga_dsp_fft_cmul(conv->dsp, conv->fft, conv->pre_mult, conv->segmentsIr[1], conv->segments[indexAudio], conv->fftComplexSize, conv->scale); @@ -184,7 +184,7 @@ static int convolver1_run(struct convolver1 *conv, const float *input, float *ou for (i = 2; i < conv->segCount; i++) { indexAudio = (conv->current + i) % conv->segCount; - dsp_ops_fft_cmuladd(conv->dsp, conv->fft, + spa_fga_dsp_fft_cmuladd(conv->dsp, conv->fft, conv->pre_mult, conv->pre_mult, conv->segmentsIr[i], @@ -192,30 +192,30 @@ static int convolver1_run(struct convolver1 *conv, const float *input, float *ou conv->fftComplexSize, conv->scale); } } - dsp_ops_fft_cmuladd(conv->dsp, conv->fft, + spa_fga_dsp_fft_cmuladd(conv->dsp, conv->fft, conv->conv, conv->pre_mult, conv->segments[conv->current], conv->segmentsIr[0], conv->fftComplexSize, conv->scale); } else { - dsp_ops_fft_cmul(conv->dsp, conv->fft, + spa_fga_dsp_fft_cmul(conv->dsp, conv->fft, conv->conv, conv->segments[conv->current], conv->segmentsIr[0], conv->fftComplexSize, conv->scale); } - dsp_ops_fft_run(conv->dsp, conv->ifft, -1, conv->conv, conv->fft_buffer); + spa_fga_dsp_fft_run(conv->dsp, conv->ifft, -1, conv->conv, conv->fft_buffer); - dsp_ops_sum(conv->dsp, output + processed, conv->fft_buffer + inputBufferPos, + spa_fga_dsp_sum(conv->dsp, output + processed, conv->fft_buffer + inputBufferPos, conv->overlap + inputBufferPos, processing); conv->inputBufferFill += processing; if (conv->inputBufferFill == conv->blockSize) { conv->inputBufferFill = 0; - dsp_ops_copy(conv->dsp, conv->overlap, conv->fft_buffer + conv->blockSize, conv->blockSize); + spa_fga_dsp_copy(conv->dsp, conv->overlap, conv->fft_buffer + conv->blockSize, conv->blockSize); conv->current = (conv->current > 0) ? (conv->current - 1) : (conv->segCount - 1); } @@ -227,7 +227,7 @@ static int convolver1_run(struct convolver1 *conv, const float *input, float *ou struct convolver { - struct dsp_ops *dsp; + struct spa_fga_dsp *dsp; int headBlockSize; int tailBlockSize; struct convolver1 *headConvolver; @@ -248,19 +248,19 @@ void convolver_reset(struct convolver *conv) convolver1_reset(conv->headConvolver); if (conv->tailConvolver0) { convolver1_reset(conv->tailConvolver0); - dsp_ops_fft_memclear(conv->dsp, conv->tailOutput0, conv->tailBlockSize, true); - dsp_ops_fft_memclear(conv->dsp, conv->tailPrecalculated0, conv->tailBlockSize, true); + spa_fga_dsp_fft_memclear(conv->dsp, conv->tailOutput0, conv->tailBlockSize, true); + spa_fga_dsp_fft_memclear(conv->dsp, conv->tailPrecalculated0, conv->tailBlockSize, true); } if (conv->tailConvolver) { convolver1_reset(conv->tailConvolver); - dsp_ops_fft_memclear(conv->dsp, conv->tailOutput, conv->tailBlockSize, true); - dsp_ops_fft_memclear(conv->dsp, conv->tailPrecalculated, conv->tailBlockSize, true); + spa_fga_dsp_fft_memclear(conv->dsp, conv->tailOutput, conv->tailBlockSize, true); + spa_fga_dsp_fft_memclear(conv->dsp, conv->tailPrecalculated, conv->tailBlockSize, true); } conv->tailInputFill = 0; conv->precalculatedPos = 0; } -struct convolver *convolver_new(struct dsp_ops *dsp_ops, int head_block, int tail_block, const float *ir, int irlen) +struct convolver *convolver_new(struct spa_fga_dsp *dsp, int head_block, int tail_block, const float *ir, int irlen) { struct convolver *conv; int head_ir_len; @@ -282,20 +282,20 @@ struct convolver *convolver_new(struct dsp_ops *dsp_ops, int head_block, int tai if (irlen == 0) return conv; - conv->dsp = dsp_ops; + conv->dsp = dsp; conv->headBlockSize = next_power_of_two(head_block); conv->tailBlockSize = next_power_of_two(tail_block); head_ir_len = SPA_MIN(irlen, conv->tailBlockSize); - conv->headConvolver = convolver1_new(dsp_ops, conv->headBlockSize, ir, head_ir_len); + conv->headConvolver = convolver1_new(dsp, conv->headBlockSize, ir, head_ir_len); if (conv->headConvolver == NULL) goto error; if (irlen > conv->tailBlockSize) { int conv1IrLen = SPA_MIN(irlen - conv->tailBlockSize, conv->tailBlockSize); - conv->tailConvolver0 = convolver1_new(dsp_ops, conv->headBlockSize, ir + conv->tailBlockSize, conv1IrLen); - conv->tailOutput0 = dsp_ops_fft_memalloc(conv->dsp, conv->tailBlockSize, true); - conv->tailPrecalculated0 = dsp_ops_fft_memalloc(conv->dsp, conv->tailBlockSize, true); + conv->tailConvolver0 = convolver1_new(dsp, conv->headBlockSize, ir + conv->tailBlockSize, conv1IrLen); + conv->tailOutput0 = spa_fga_dsp_fft_memalloc(conv->dsp, conv->tailBlockSize, true); + conv->tailPrecalculated0 = spa_fga_dsp_fft_memalloc(conv->dsp, conv->tailBlockSize, true); if (conv->tailConvolver0 == NULL || conv->tailOutput0 == NULL || conv->tailPrecalculated0 == NULL) goto error; @@ -303,16 +303,16 @@ struct convolver *convolver_new(struct dsp_ops *dsp_ops, int head_block, int tai if (irlen > 2 * conv->tailBlockSize) { int tailIrLen = irlen - (2 * conv->tailBlockSize); - conv->tailConvolver = convolver1_new(dsp_ops, conv->tailBlockSize, ir + (2 * conv->tailBlockSize), tailIrLen); - conv->tailOutput = dsp_ops_fft_memalloc(conv->dsp, conv->tailBlockSize, true); - conv->tailPrecalculated = dsp_ops_fft_memalloc(conv->dsp, conv->tailBlockSize, true); + conv->tailConvolver = convolver1_new(dsp, conv->tailBlockSize, ir + (2 * conv->tailBlockSize), tailIrLen); + conv->tailOutput = spa_fga_dsp_fft_memalloc(conv->dsp, conv->tailBlockSize, true); + conv->tailPrecalculated = spa_fga_dsp_fft_memalloc(conv->dsp, conv->tailBlockSize, true); if (conv->tailConvolver == NULL || conv->tailOutput == NULL || conv->tailPrecalculated == NULL) goto error; } if (conv->tailConvolver0 || conv->tailConvolver) { - conv->tailInput = dsp_ops_fft_memalloc(conv->dsp, conv->tailBlockSize, true); + conv->tailInput = spa_fga_dsp_fft_memalloc(conv->dsp, conv->tailBlockSize, true); if (conv->tailInput == NULL) goto error; } @@ -333,11 +333,11 @@ void convolver_free(struct convolver *conv) convolver1_free(conv->tailConvolver0); if (conv->tailConvolver) convolver1_free(conv->tailConvolver); - dsp_ops_fft_memfree(conv->dsp, conv->tailOutput0); - dsp_ops_fft_memfree(conv->dsp, conv->tailPrecalculated0); - dsp_ops_fft_memfree(conv->dsp, conv->tailOutput); - dsp_ops_fft_memfree(conv->dsp, conv->tailPrecalculated); - dsp_ops_fft_memfree(conv->dsp, conv->tailInput); + spa_fga_dsp_fft_memfree(conv->dsp, conv->tailOutput0); + spa_fga_dsp_fft_memfree(conv->dsp, conv->tailPrecalculated0); + spa_fga_dsp_fft_memfree(conv->dsp, conv->tailOutput); + spa_fga_dsp_fft_memfree(conv->dsp, conv->tailPrecalculated); + spa_fga_dsp_fft_memfree(conv->dsp, conv->tailInput); free(conv); } @@ -353,16 +353,16 @@ int convolver_run(struct convolver *conv, const float *input, float *output, int int processing = SPA_MIN(remaining, conv->headBlockSize - (conv->tailInputFill % conv->headBlockSize)); if (conv->tailPrecalculated0) - dsp_ops_sum(conv->dsp, &output[processed], &output[processed], + spa_fga_dsp_sum(conv->dsp, &output[processed], &output[processed], &conv->tailPrecalculated0[conv->precalculatedPos], processing); if (conv->tailPrecalculated) - dsp_ops_sum(conv->dsp, &output[processed], &output[processed], + spa_fga_dsp_sum(conv->dsp, &output[processed], &output[processed], &conv->tailPrecalculated[conv->precalculatedPos], processing); conv->precalculatedPos += processing; - dsp_ops_copy(conv->dsp, conv->tailInput + conv->tailInputFill, input + processed, processing); + spa_fga_dsp_copy(conv->dsp, conv->tailInput + conv->tailInputFill, input + processed, processing); conv->tailInputFill += processing; if (conv->tailPrecalculated0 && (conv->tailInputFill % conv->headBlockSize == 0)) { diff --git a/src/modules/module-filter-chain/convolver.h b/src/modules/module-filter-chain/convolver.h index e8749d7bc..ad6139a35 100644 --- a/src/modules/module-filter-chain/convolver.h +++ b/src/modules/module-filter-chain/convolver.h @@ -5,9 +5,9 @@ #include #include -#include "dsp-ops.h" +#include "audio-dsp.h" -struct convolver *convolver_new(struct dsp_ops *dsp, int block, int tail, const float *ir, int irlen); +struct convolver *convolver_new(struct spa_fga_dsp *dsp, int block, int tail, const float *ir, int irlen); void convolver_free(struct convolver *conv); void convolver_reset(struct convolver *conv); diff --git a/src/modules/module-filter-chain/dsp-ops.h b/src/modules/module-filter-chain/dsp-ops.h deleted file mode 100644 index 1bf4eed96..000000000 --- a/src/modules/module-filter-chain/dsp-ops.h +++ /dev/null @@ -1,84 +0,0 @@ -/* Spa */ -/* SPDX-FileCopyrightText: Copyright © 2022 Wim Taymans */ -/* SPDX-License-Identifier: MIT */ - -#ifndef DSP_OPS_H -#define DSP_OPS_H - -#include - -#include "biquad.h" - -struct dsp_ops; - -struct dsp_ops_funcs { - void (*clear) (struct dsp_ops *ops, void * SPA_RESTRICT dst, uint32_t n_samples); - void (*copy) (struct dsp_ops *ops, - void * SPA_RESTRICT dst, - const void * SPA_RESTRICT src, uint32_t n_samples); - void (*mix_gain) (struct dsp_ops *ops, - void * SPA_RESTRICT dst, - const void * SPA_RESTRICT src[], - float gain[], uint32_t n_src, uint32_t n_samples); - void (*sum) (struct dsp_ops *ops, - float * dst, const float * SPA_RESTRICT a, - const float * SPA_RESTRICT b, uint32_t n_samples); - - void *(*fft_new) (struct dsp_ops *ops, uint32_t size, bool real); - void (*fft_free) (struct dsp_ops *ops, void *fft); - void *(*fft_memalloc) (struct dsp_ops *ops, uint32_t size, bool real); - void (*fft_memfree) (struct dsp_ops *ops, void *mem); - void (*fft_memclear) (struct dsp_ops *ops, void *mem, uint32_t size, bool real); - void (*fft_run) (struct dsp_ops *ops, void *fft, int direction, - const float * SPA_RESTRICT src, float * SPA_RESTRICT dst); - void (*fft_cmul) (struct dsp_ops *ops, void *fft, - float * SPA_RESTRICT dst, const float * SPA_RESTRICT a, - const float * SPA_RESTRICT b, uint32_t len, const float scale); - void (*fft_cmuladd) (struct dsp_ops *ops, void *fft, - float * dst, const float * src, - const float * SPA_RESTRICT a, const float * SPA_RESTRICT b, - uint32_t len, const float scale); - void (*linear) (struct dsp_ops *ops, - float * dst, const float * SPA_RESTRICT src, - const float mult, const float add, uint32_t n_samples); - void (*mult) (struct dsp_ops *ops, - void * SPA_RESTRICT dst, - const void * SPA_RESTRICT src[], uint32_t n_src, uint32_t n_samples); - void (*biquad_run) (struct dsp_ops *ops, struct biquad *bq, uint32_t n_bq, uint32_t bq_stride, - float * SPA_RESTRICT out[], const float * SPA_RESTRICT in[], - uint32_t n_src, uint32_t n_samples); - void (*delay) (struct dsp_ops *ops, float *buffer, uint32_t *pos, uint32_t n_buffer, uint32_t delay, - float *dst, const float *src, uint32_t n_samples); -}; - -struct dsp_ops { - uint32_t cpu_flags; - - void (*free) (struct dsp_ops *ops); - - struct dsp_ops_funcs funcs; - - const void *priv; -}; - -#define dsp_ops_free(ops) (ops)->free(ops) - -#define dsp_ops_clear(ops,...) (ops)->funcs.clear(ops, __VA_ARGS__) -#define dsp_ops_copy(ops,...) (ops)->funcs.copy(ops, __VA_ARGS__) -#define dsp_ops_mix_gain(ops,...) (ops)->funcs.mix_gain(ops, __VA_ARGS__) -#define dsp_ops_biquad_run(ops,...) (ops)->funcs.biquad_run(ops, __VA_ARGS__) -#define dsp_ops_sum(ops,...) (ops)->funcs.sum(ops, __VA_ARGS__) -#define dsp_ops_linear(ops,...) (ops)->funcs.linear(ops, __VA_ARGS__) -#define dsp_ops_mult(ops,...) (ops)->funcs.mult(ops, __VA_ARGS__) -#define dsp_ops_delay(ops,...) (ops)->funcs.delay(ops, __VA_ARGS__) - -#define dsp_ops_fft_new(ops,...) (ops)->funcs.fft_new(ops, __VA_ARGS__) -#define dsp_ops_fft_free(ops,...) (ops)->funcs.fft_free(ops, __VA_ARGS__) -#define dsp_ops_fft_memalloc(ops,...) (ops)->funcs.fft_memalloc(ops, __VA_ARGS__) -#define dsp_ops_fft_memfree(ops,...) (ops)->funcs.fft_memfree(ops, __VA_ARGS__) -#define dsp_ops_fft_memclear(ops,...) (ops)->funcs.fft_memclear(ops, __VA_ARGS__) -#define dsp_ops_fft_run(ops,...) (ops)->funcs.fft_run(ops, __VA_ARGS__) -#define dsp_ops_fft_cmul(ops,...) (ops)->funcs.fft_cmul(ops, __VA_ARGS__) -#define dsp_ops_fft_cmuladd(ops,...) (ops)->funcs.fft_cmuladd(ops, __VA_ARGS__) - -#endif /* DSP_OPS_H */ diff --git a/src/modules/module-filter-chain/filter-graph.c b/src/modules/module-filter-chain/filter-graph.c index 9f64f6e9d..54c6455a9 100644 --- a/src/modules/module-filter-chain/filter-graph.c +++ b/src/modules/module-filter-chain/filter-graph.c @@ -32,11 +32,7 @@ #include #include -#include -#include -#include - -#include "module-filter-chain/dsp-ops-impl.h" +#include "module-filter-chain/audio-dsp-impl.h" #define NAME "filter-chain" @@ -57,9 +53,9 @@ SPA_LOG_TOPIC_DEFINE_STATIC(log_topic, "spa.filter-graph"); struct spa_fga_plugin *load_ladspa_plugin(const struct spa_support *support, uint32_t n_support, - struct dsp_ops *dsp, const char *path, const struct spa_dict *info); + const char *path, const struct spa_dict *info); struct spa_fga_plugin *load_builtin_plugin(const struct spa_support *support, uint32_t n_support, - struct dsp_ops *dsp, const char *path, const struct spa_dict *info); + const char *path, const struct spa_dict *info); struct plugin { struct spa_list link; @@ -206,11 +202,11 @@ struct impl { struct spa_log *log; struct spa_cpu *cpu; + struct spa_fga_dsp *dsp; struct graph graph; uint32_t quantum_limit; - struct dsp_ops dsp; uint32_t max_align; long unsigned rate; @@ -858,7 +854,7 @@ static struct plugin *plugin_load(struct impl *impl, const char *type, const cha spa_log_error(impl->log, "can't load plugin type '%s': %m", type); pl = NULL; } else { - pl = plugin_func(impl->support, impl->n_support, &impl->dsp, path, NULL); + pl = plugin_func(impl->support, impl->n_support, path, NULL); } if (pl == NULL) goto exit; @@ -2084,14 +2080,16 @@ impl_init(const struct spa_handle_factory *factory, impl->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log); spa_log_topic_init(impl->log, &log_topic); - for (i = 0; i < SPA_MIN(n_support, 16u); i++) + for (i = 0; i < SPA_MIN(n_support, 15u); i++) impl->support[i] = support[i]; impl->n_support = n_support; impl->cpu = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_CPU); - dsp_ops_init(&impl->dsp, impl->cpu ? spa_cpu_get_flags(impl->cpu) : 0); impl->max_align = spa_cpu_get_max_align(impl->cpu); + impl->dsp = spa_fga_dsp_new(impl->cpu ? spa_cpu_get_flags(impl->cpu) : 0); + impl->support[impl->n_support++] = SPA_SUPPORT_INIT(SPA_TYPE_INTERFACE_FILTER_GRAPH_AudioDSP, impl->dsp); + spa_list_init(&impl->plugin_list); spa_list_init(&impl->plugin_func_list); diff --git a/src/modules/module-filter-chain/ladspa_plugin.c b/src/modules/module-filter-chain/ladspa_plugin.c index e5f20aa0b..f6fe5085f 100644 --- a/src/modules/module-filter-chain/ladspa_plugin.c +++ b/src/modules/module-filter-chain/ladspa_plugin.c @@ -240,7 +240,7 @@ static inline const char *split_walk(const char *str, const char *delimiter, siz } struct spa_fga_plugin *load_ladspa_plugin(const struct spa_support *support, uint32_t n_support, - struct dsp_ops *dsp, const char *plugin, const struct spa_dict *info) + const char *plugin, const struct spa_dict *info) { struct spa_fga_plugin *pl = NULL; struct spa_log *log; diff --git a/src/modules/module-filter-chain/lv2_plugin.c b/src/modules/module-filter-chain/lv2_plugin.c index 570df2ed6..6948eab9e 100644 --- a/src/modules/module-filter-chain/lv2_plugin.c +++ b/src/modules/module-filter-chain/lv2_plugin.c @@ -468,7 +468,7 @@ static struct spa_fga_plugin_methods impl_plugin = { SPA_EXPORT struct spa_fga_plugin *spa_filter_graph_audio_plugin_load(const struct spa_support *support, uint32_t n_support, - struct dsp_ops *dsp, const char *plugin_uri, const struct spa_dict *info) + const char *plugin_uri, const struct spa_dict *info) { struct context *c; const LilvPlugins *plugins; diff --git a/src/modules/module-filter-chain/sofa_plugin.c b/src/modules/module-filter-chain/sofa_plugin.c index 0733717e9..70b556f71 100644 --- a/src/modules/module-filter-chain/sofa_plugin.c +++ b/src/modules/module-filter-chain/sofa_plugin.c @@ -8,7 +8,7 @@ #include "audio-plugin.h" #include "convolver.h" -#include "dsp-ops.h" +#include "audio-dsp.h" #include "pffft.h" #include @@ -16,7 +16,7 @@ struct plugin { struct spa_fga_plugin plugin; - struct dsp_ops *dsp; + struct spa_fga_dsp *dsp; struct spa_log *log; struct spa_loop *data_loop; struct spa_loop *main_loop; @@ -26,7 +26,7 @@ struct plugin { struct spatializer_impl { struct plugin *plugin; - struct dsp_ops *dsp; + struct spa_fga_dsp *dsp; struct spa_log *log; unsigned long rate; @@ -438,7 +438,7 @@ static struct spa_fga_plugin_methods impl_plugin = { SPA_EXPORT struct spa_fga_plugin *spa_filter_graph_audio_plugin_load(const struct spa_support *support, uint32_t n_support, - struct dsp_ops *dsp, const char *plugin, const struct spa_dict *info) + const char *plugin, const struct spa_dict *info) { struct plugin *impl = calloc(1, sizeof (struct plugin)); @@ -455,12 +455,11 @@ struct spa_fga_plugin *spa_filter_graph_audio_plugin_load(const struct spa_suppo if (spa_streq(k, "clock.quantum-limit")) spa_atou32(s, &impl->quantum_limit, 0); } - impl->dsp = dsp; - pffft_select_cpu(dsp->cpu_flags); - impl->data_loop = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_DataLoop); impl->main_loop = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Loop); impl->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log); + impl->dsp = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_FILTER_GRAPH_AudioDSP); + pffft_select_cpu(impl->dsp->cpu_flags); return (struct spa_fga_plugin *) impl; }