filter-graph: Make dsp-ops and interface

Rename dsp-ops to audio-dsp and make it a SPA interface.

Pass the audio-dsp interface around with the support.
This commit is contained in:
Wim Taymans 2024-11-12 15:54:28 +01:00
parent 0a71911796
commit 13b8e3a75d
17 changed files with 312 additions and 302 deletions

View file

@ -82,7 +82,7 @@ simd_dependencies = []
if have_sse if have_sse
filter_chain_sse = static_library('filter_chain_sse', filter_chain_sse = static_library('filter_chain_sse',
['module-filter-chain/pffft.c', ['module-filter-chain/pffft.c',
'module-filter-chain/dsp-ops-sse.c' ], 'module-filter-chain/audio-dsp-sse.c' ],
include_directories : [configinc], include_directories : [configinc],
c_args : [sse_args, '-O3', '-DHAVE_SSE'], c_args : [sse_args, '-O3', '-DHAVE_SSE'],
dependencies : [ spa_dep ], dependencies : [ spa_dep ],
@ -93,7 +93,7 @@ if have_sse
endif endif
if have_avx if have_avx
filter_chain_avx = static_library('filter_chain_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], include_directories : [configinc],
c_args : [avx_args, fma_args,'-O3', '-DHAVE_AVX'], c_args : [avx_args, fma_args,'-O3', '-DHAVE_AVX'],
dependencies : [ spa_dep ], dependencies : [ spa_dep ],
@ -115,8 +115,8 @@ endif
filter_chain_c = static_library('filter_chain_c', filter_chain_c = static_library('filter_chain_c',
['module-filter-chain/pffft.c', ['module-filter-chain/pffft.c',
'module-filter-chain/dsp-ops.c', 'module-filter-chain/audio-dsp.c',
'module-filter-chain/dsp-ops-c.c' ], 'module-filter-chain/audio-dsp-c.c' ],
include_directories : [configinc], include_directories : [configinc],
c_args : [simd_cargs, '-O3', '-DPFFFT_SIMD_DISABLE'], c_args : [simd_cargs, '-O3', '-DPFFFT_SIMD_DISABLE'],
dependencies : [ spa_dep, fftw_dep], dependencies : [ spa_dep, fftw_dep],

View file

@ -13,24 +13,14 @@
#include "config.h" #include "config.h"
#include "module-filter-chain/filter-graph.h"
#include <spa/utils/result.h>
#include <spa/utils/string.h>
#include <spa/utils/json.h>
#include <spa/support/cpu.h>
#include <spa/param/latency-utils.h> #include <spa/param/latency-utils.h>
#include <spa/param/tag-utils.h> #include <spa/param/tag-utils.h>
#include <spa/param/audio/raw-json.h> #include <spa/param/audio/raw-json.h>
#include <spa/pod/dynamic.h> #include <spa/pod/dynamic.h>
#include <spa/debug/types.h>
#include <spa/debug/log.h>
#include <pipewire/utils.h>
#include <pipewire/impl.h> #include <pipewire/impl.h>
#include <pipewire/extensions/profiler.h>
#include "module-filter-chain/dsp-ops-impl.h" #include "module-filter-chain/filter-graph.h"
#define NAME "filter-chain" #define NAME "filter-chain"

View file

@ -12,11 +12,11 @@
#ifndef HAVE_FFTW #ifndef HAVE_FFTW
#include "pffft.h" #include "pffft.h"
#endif #endif
#include "dsp-ops.h" #include "audio-dsp-impl.h"
#include <immintrin.h> #include <immintrin.h>
void dsp_mix_gain_avx(struct dsp_ops *ops, void dsp_mix_gain_avx(void *obj,
void * SPA_RESTRICT dst, void * SPA_RESTRICT dst,
const void * SPA_RESTRICT src[], const void * SPA_RESTRICT src[],
float gain[], uint32_t n_src, uint32_t n_samples) 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; uint32_t n, unrolled;
__m256 in[4]; __m256 in[4];
@ -138,7 +138,7 @@ inline static __m256 _mm256_mul_pz(__m256 ab, __m256 cd)
return _mm256_addsub_ps(x0, x1); 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, float * SPA_RESTRICT dst, const float * SPA_RESTRICT a,
const float * SPA_RESTRICT b, uint32_t len, const float scale) 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 #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, float * SPA_RESTRICT dst, const float * SPA_RESTRICT src,
const float * SPA_RESTRICT a, const float * SPA_RESTRICT b, const float * SPA_RESTRICT a, const float * SPA_RESTRICT b,
uint32_t len, const float scale) uint32_t len, const float scale)

View file

@ -16,21 +16,21 @@
#else #else
#include "pffft.h" #include "pffft.h"
#endif #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); 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) const void * SPA_RESTRICT src, uint32_t n_samples)
{ {
if (dst != src) if (dst != src)
spa_memcpy(dst, src, sizeof(float) * n_samples); 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) const void * SPA_RESTRICT src, uint32_t n_samples)
{ {
uint32_t i; 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]; 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) const void * SPA_RESTRICT src, float gain, uint32_t n_samples)
{ {
uint32_t i; uint32_t i;
const float *s = src; const float *s = src;
float *d = dst; float *d = dst;
if (gain == 0.0f) if (gain == 0.0f)
dsp_clear_c(ops, dst, n_samples); dsp_clear_c(obj, dst, n_samples);
else if (gain == 1.0f) else if (gain == 1.0f)
dsp_copy_c(ops, dst, src, n_samples); dsp_copy_c(obj, dst, src, n_samples);
else { else {
for (i = 0; i < n_samples; i++) for (i = 0; i < n_samples; i++)
d[i] = s[i] * gain; 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) const void * SPA_RESTRICT src, float gain, uint32_t n_samples)
{ {
uint32_t i; 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) if (gain == 0.0f)
return; return;
else if (gain == 1.0f) else if (gain == 1.0f)
dsp_add_c(ops, dst, src, n_samples); dsp_add_c(obj, dst, src, n_samples);
else { else {
for (i = 0; i < n_samples; i++) for (i = 0; i < n_samples; i++)
d[i] += s[i] * gain; 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, void * SPA_RESTRICT dst,
const void * SPA_RESTRICT src[], const void * SPA_RESTRICT src[],
float gain[], uint32_t n_src, uint32_t n_samples) float gain[], uint32_t n_src, uint32_t n_samples)
{ {
uint32_t i; uint32_t i;
if (n_src == 0) { if (n_src == 0) {
dsp_clear_c(ops, dst, n_samples); dsp_clear_c(obj, dst, n_samples);
} else { } 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++) 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) const void * SPA_RESTRICT src, uint32_t n_samples)
{ {
uint32_t i; 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]; d[i] *= s[i];
} }
void dsp_mult_c(struct dsp_ops *ops, void dsp_mult_c(void *obj,
void * SPA_RESTRICT dst, void * SPA_RESTRICT dst,
const void * SPA_RESTRICT src[], const void * SPA_RESTRICT src[],
uint32_t n_src, uint32_t n_samples) uint32_t n_src, uint32_t n_samples)
{ {
uint32_t i; uint32_t i;
if (n_src == 0) { if (n_src == 0) {
dsp_clear_c(ops, dst, n_samples); dsp_clear_c(obj, dst, n_samples);
} else { } 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++) 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 *out, const float *in, uint32_t n_samples)
{ {
float x, y, x1, x2; float x, y, x1, x2;
@ -122,7 +122,7 @@ static void biquad_run_c(struct dsp_ops *ops, struct biquad *bq,
uint32_t i; uint32_t i;
if (bq->type == BQ_NONE) { if (bq->type == BQ_NONE) {
dsp_copy_c(ops, out, in, n_samples); dsp_copy_c(obj, out, in, n_samples);
return; return;
} }
@ -146,7 +146,7 @@ static void biquad_run_c(struct dsp_ops *ops, struct biquad *bq,
#undef F #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[], float * SPA_RESTRICT out[], const float * SPA_RESTRICT in[],
uint32_t n_src, uint32_t n_samples) 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) if (s == NULL || d == NULL)
continue; continue;
if (n_bq > 0) 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++) 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) const float * SPA_RESTRICT a, const float * SPA_RESTRICT b, uint32_t n_samples)
{ {
uint32_t i; uint32_t i;
@ -173,13 +173,13 @@ void dsp_sum_c(struct dsp_ops *ops, float * dst,
dst[i] = a[i] + b[i]; 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 * SPA_RESTRICT src, const float mult,
const float add, uint32_t n_samples) const float add, uint32_t n_samples)
{ {
uint32_t i; uint32_t i;
if (add == 0.0f) { if (add == 0.0f) {
dsp_gain_c(ops, dst, src, mult, n_samples); dsp_gain_c(obj, dst, src, mult, n_samples);
} else { } else {
if (mult == 0.0f) { if (mult == 0.0f) {
for (i = 0; i < n_samples; i++) 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) uint32_t delay, float *dst, const float *src, uint32_t n_samples)
{ {
if (delay == 0) { if (delay == 0) {
dsp_copy_c(ops, dst, src, n_samples); dsp_copy_c(obj, dst, src, n_samples);
} else { } else {
uint32_t w, o, i; uint32_t w, o, i;
@ -222,7 +222,7 @@ struct fft_info {
}; };
#endif #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 #ifdef HAVE_FFTW
struct fft_info *info = calloc(1, sizeof(struct fft_info)); 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 #endif
} }
void dsp_fft_free_c(struct dsp_ops *ops, void *fft) void dsp_fft_free_c(void *obj, void *fft)
{ {
#ifdef HAVE_FFTW #ifdef HAVE_FFTW
struct fft_info *info = fft; struct fft_info *info = fft;
@ -259,7 +259,7 @@ void dsp_fft_free_c(struct dsp_ops *ops, void *fft)
#endif #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 #ifdef HAVE_FFTW
if (real) if (real)
@ -274,7 +274,7 @@ void *dsp_fft_memalloc_c(struct dsp_ops *ops, uint32_t size, bool real)
#endif #endif
} }
void dsp_fft_memfree_c(struct dsp_ops *ops, void *data) void dsp_fft_memfree_c(void *obj, void *data)
{ {
#ifdef HAVE_FFTW #ifdef HAVE_FFTW
fftwf_free(data); fftwf_free(data);
@ -283,16 +283,16 @@ void dsp_fft_memfree_c(struct dsp_ops *ops, void *data)
#endif #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 #ifdef HAVE_FFTW
dsp_ops_clear(ops, data, real ? size : size * 2); spa_fga_dsp_clear(obj, data, real ? size : size * 2);
#else #else
dsp_ops_clear(ops, data, real ? size : size * 2); spa_fga_dsp_clear(obj, data, real ? size : size * 2);
#endif #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) const float * SPA_RESTRICT src, float * SPA_RESTRICT dst)
{ {
#ifdef HAVE_FFTW #ifdef HAVE_FFTW
@ -306,7 +306,7 @@ void dsp_fft_run_c(struct dsp_ops *ops, void *fft, int direction,
#endif #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, float * SPA_RESTRICT dst, const float * SPA_RESTRICT a,
const float * SPA_RESTRICT b, uint32_t len, const float scale) 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 #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, float * SPA_RESTRICT dst, const float * SPA_RESTRICT src,
const float * SPA_RESTRICT a, const float * SPA_RESTRICT b, const float * SPA_RESTRICT a, const float * SPA_RESTRICT b,
uint32_t len, const float scale) uint32_t len, const float scale)

View file

@ -2,56 +2,57 @@
/* SPDX-FileCopyrightText: Copyright © 2022 Wim Taymans */ /* SPDX-FileCopyrightText: Copyright © 2022 Wim Taymans */
/* SPDX-License-Identifier: MIT */ /* SPDX-License-Identifier: MIT */
#ifndef DSP_OPS_IMPL_H #ifndef DSP_IMPL_H
#define DSP_OPS_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) \ #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) \ #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) const void * SPA_RESTRICT src, uint32_t n_samples)
#define MAKE_MIX_GAIN_FUNC(arch) \ #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) const void * SPA_RESTRICT src[], float gain[], uint32_t n_src, uint32_t n_samples)
#define MAKE_SUM_FUNC(arch) \ #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) const float * SPA_RESTRICT a, const float * SPA_RESTRICT b, uint32_t n_samples)
#define MAKE_LINEAR_FUNC(arch) \ #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) const float * SPA_RESTRICT src, const float mult, const float add, uint32_t n_samples)
#define MAKE_MULT_FUNC(arch) \ #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) const void * SPA_RESTRICT src[], uint32_t n_src, uint32_t n_samples)
#define MAKE_BIQUAD_RUN_FUNC(arch) \ #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) float * SPA_RESTRICT out[], const float * SPA_RESTRICT in[], uint32_t n_src, uint32_t n_samples)
#define MAKE_DELAY_FUNC(arch) \ #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) uint32_t delay, float *dst, const float *src, uint32_t n_samples)
#define MAKE_FFT_NEW_FUNC(arch) \ #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) \ #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) \ #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) \ #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) \ #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) \ #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) const float * SPA_RESTRICT src, float * SPA_RESTRICT dst)
#define MAKE_FFT_CMUL_FUNC(arch) \ #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, \ float * SPA_RESTRICT dst, const float * SPA_RESTRICT a, \
const float * SPA_RESTRICT b, uint32_t len, const float scale) const float * SPA_RESTRICT b, uint32_t len, const float scale)
#define MAKE_FFT_CMULADD_FUNC(arch) \ #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, \ float * dst, const float * src, \
const float * SPA_RESTRICT a, const float * SPA_RESTRICT b, \ const float * SPA_RESTRICT a, const float * SPA_RESTRICT b, \
uint32_t len, const float scale) uint32_t len, const float scale)

View file

@ -15,11 +15,11 @@
#include "pffft.h" #include "pffft.h"
#endif #endif
#include "dsp-ops-impl.h" #include "audio-dsp-impl.h"
#include <xmmintrin.h> #include <xmmintrin.h>
void dsp_mix_gain_sse(struct dsp_ops *ops, void dsp_mix_gain_sse(void *obj,
void * SPA_RESTRICT dst, void * SPA_RESTRICT dst,
const void * SPA_RESTRICT src[], const void * SPA_RESTRICT src[],
float gain[], uint32_t n_src, uint32_t n_samples) 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; uint32_t n, unrolled;
__m128 in[4]; __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) float *out, const float *in, uint32_t n_samples)
{ {
__m128 x, y, z; __m128 x, y, z;
@ -157,7 +157,7 @@ static void dsp_biquad_run1_sse(struct dsp_ops *ops, struct biquad *bq,
#undef F #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) float *out, const float *in, uint32_t n_samples)
{ {
__m128 x, y, z; __m128 x, y, z;
@ -201,7 +201,7 @@ static void dsp_biquad2_run_sse(struct dsp_ops *ops, struct biquad *bq,
#undef F #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) float **out, const float **in, uint32_t n_samples)
{ {
__m128 x, y, z; __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) float **out, const float **in, uint32_t n_samples)
{ {
__m128 x, y, z; __m128 x, y, z;
@ -309,7 +309,7 @@ static void dsp_biquad2_run2_sse(struct dsp_ops *ops, struct biquad *bq, uint32_
#undef F #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) float **out, const float **in, uint32_t n_samples)
{ {
__m128 x, y, z; __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 #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) float **out, const float **in, uint32_t n_samples)
{ {
__m128 x, y, z; __m128 x, y, z;
@ -432,7 +432,7 @@ static void dsp_biquad2_run4_sse(struct dsp_ops *ops, struct biquad *bq, uint32_
#undef F #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[], float * SPA_RESTRICT out[], const float * SPA_RESTRICT in[],
uint32_t n_src, uint32_t n_samples) 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; j = 0;
if (j < junrolled2) { 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[0] = d[0];
s[1] = d[1]; s[1] = d[1];
s[2] = d[2]; 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; j+=2;
} }
for (; j < junrolled2; 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) { 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) { 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; j = 0;
if (j < junrolled2) { 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[0] = d[0];
s[1] = d[1]; s[1] = d[1];
j+=2; j+=2;
} }
for (; j < junrolled2; 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) { 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) { 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; j = 0;
if (j < junrolled2) { 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; s = d;
j+=2; j+=2;
} }
for (; j < junrolled2; 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) { 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) float *dst, const float *src, uint32_t n_samples)
{ {
__m128 t[1]; __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); 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, float * SPA_RESTRICT dst, const float * SPA_RESTRICT a,
const float * SPA_RESTRICT b, uint32_t len, const float scale) 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 #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, float * SPA_RESTRICT dst, const float * SPA_RESTRICT src,
const float * SPA_RESTRICT a, const float * SPA_RESTRICT b, const float * SPA_RESTRICT a, const float * SPA_RESTRICT b,
uint32_t len, const float scale) uint32_t len, const float scale)

View file

@ -11,15 +11,15 @@
#include <spa/utils/defs.h> #include <spa/utils/defs.h>
#include <spa/param/audio/format-utils.h> #include <spa/param/audio/format-utils.h>
#include "dsp-ops-impl.h" #include "audio-dsp-impl.h"
struct dsp_info { struct dsp_info {
uint32_t cpu_flags; 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) #if defined (HAVE_AVX)
{ SPA_CPU_FLAG_AVX, { SPA_CPU_FLAG_AVX,
@ -92,23 +92,30 @@ static const struct dsp_info *find_dsp_info(uint32_t cpu_flags)
return NULL; 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; const struct dsp_info *info;
struct spa_fga_dsp *dsp;
info = find_dsp_info(cpu_flags); info = find_dsp_info(cpu_flags);
if (info == NULL) if (info == NULL) {
return -ENOTSUP; errno = ENOTSUP;
return NULL;
}
dsp = calloc(1, sizeof(*dsp));
if (dsp == NULL)
return NULL;
ops->cpu_flags = cpu_flags; dsp->cpu_flags = cpu_flags;
ops->priv = info; dsp->iface = SPA_INTERFACE_INIT(
ops->free = impl_dsp_ops_free; SPA_TYPE_INTERFACE_FILTER_GRAPH_AudioDSP,
ops->funcs = info->funcs; SPA_VERSION_FGA_DSP,
&info->funcs, dsp);
return 0; return dsp;
} }

View file

@ -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 <spa/utils/defs.h>
#include <spa/utils/hook.h>
#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 */

View file

@ -12,9 +12,6 @@
#include <spa/utils/hook.h> #include <spa/utils/hook.h>
#include <spa/support/plugin.h> #include <spa/support/plugin.h>
#include "dsp-ops.h"
#define SPA_TYPE_INTERFACE_FILTER_GRAPH_AudioPlugin SPA_TYPE_INFO_INTERFACE_BASE "FilterGraph:AudioPlugin" #define SPA_TYPE_INTERFACE_FILTER_GRAPH_AudioPlugin SPA_TYPE_INFO_INTERFACE_BASE "FilterGraph:AudioPlugin"
#define SPA_VERSION_FGA_PLUGIN 0 #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__) #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, 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, uint32_t n_support, const char *path, const struct spa_dict *info);
const char *path, const struct spa_dict *info);
#define SPA_FILTER_GRAPH_AUDIO_PLUGIN_LOAD_FUNC_NAME "spa_filter_graph_audio_plugin_load" #define SPA_FILTER_GRAPH_AUDIO_PLUGIN_LOAD_FUNC_NAME "spa_filter_graph_audio_plugin_load"

View file

@ -23,20 +23,20 @@
#include "biquad.h" #include "biquad.h"
#include "pffft.h" #include "pffft.h"
#include "convolver.h" #include "convolver.h"
#include "dsp-ops.h" #include "audio-dsp.h"
#define MAX_RATES 32u #define MAX_RATES 32u
struct plugin { struct plugin {
struct spa_fga_plugin plugin; struct spa_fga_plugin plugin;
struct dsp_ops *dsp; struct spa_fga_dsp *dsp;
struct spa_log *log; struct spa_log *log;
}; };
struct builtin { struct builtin {
struct plugin *plugin; struct plugin *plugin;
struct dsp_ops *dsp; struct spa_fga_dsp *dsp;
struct spa_log *log; struct spa_log *log;
unsigned long rate; unsigned long rate;
@ -86,7 +86,7 @@ static void copy_run(void * Instance, unsigned long SampleCount)
{ {
struct builtin *impl = Instance; struct builtin *impl = Instance;
float *in = impl->port[1], *out = impl->port[0]; 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[] = { static struct spa_fga_port copy_ports[] = {
@ -135,7 +135,7 @@ static void mixer_run(void * Instance, unsigned long SampleCount)
src[n_src] = in; src[n_src] = in;
gains[n_src++] = gain; 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[] = { 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) if (impl->freq != freq || impl->Q != Q || impl->gain != gain)
bq_freq_update(impl, impl->type, freq, Q, 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 */ /** bq_lowpass */
@ -675,7 +675,7 @@ struct convolver_impl {
struct plugin *plugin; struct plugin *plugin;
struct spa_log *log; struct spa_log *log;
struct dsp_ops *dsp; struct spa_fga_dsp *dsp;
unsigned long rate; unsigned long rate;
float *port[2]; float *port[2];
@ -1124,7 +1124,7 @@ static const struct spa_fga_descriptor convolve_desc = {
struct delay_impl { struct delay_impl {
struct plugin *plugin; struct plugin *plugin;
struct dsp_ops *dsp; struct spa_fga_dsp *dsp;
struct spa_log *log; struct spa_log *log;
unsigned long rate; 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_samples = SPA_CLAMP((uint32_t)(delay * impl->rate), 0u, impl->buffer_samples-1);
impl->delay = delay; 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); 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]; float *ctrl = impl->port[3], *notify = impl->port[2];
if (in != NULL && out != NULL) 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) if (ctrl != NULL && notify != NULL)
notify[0] = ctrl[0] * mult + add; notify[0] = ctrl[0] * mult + add;
@ -1599,7 +1599,7 @@ static void mult_run(void * Instance, unsigned long SampleCount)
src[n_src++] = in; 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[] = { static struct spa_fga_port mult_ports[] = {
@ -1727,7 +1727,7 @@ static const struct spa_fga_descriptor sine_desc = {
struct param_eq_impl { struct param_eq_impl {
struct plugin *plugin; struct plugin *plugin;
struct dsp_ops *dsp; struct spa_fga_dsp *dsp;
struct spa_log *log; struct spa_log *log;
unsigned long rate; 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) static void param_eq_run(void * Instance, unsigned long SampleCount)
{ {
struct param_eq_impl *impl = Instance; 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); &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 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)); 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, SPA_VERSION_FGA_PLUGIN,
&impl_plugin, impl); &impl_plugin, impl);
impl->dsp = dsp; impl->dsp = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_FILTER_GRAPH_AudioDSP);
pffft_select_cpu(dsp->cpu_flags); pffft_select_cpu(impl->dsp->cpu_flags);
impl->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log); impl->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
return (struct spa_fga_plugin *) impl; return (struct spa_fga_plugin *) impl;

View file

@ -11,7 +11,7 @@
#include <math.h> #include <math.h>
struct convolver1 { struct convolver1 {
struct dsp_ops *dsp; struct spa_fga_dsp *dsp;
int blockSize; int blockSize;
int segSize; int segSize;
@ -49,11 +49,11 @@ static void convolver1_reset(struct convolver1 *conv)
{ {
int i; int i;
for (i = 0; i < conv->segCount; i++) for (i = 0; i < conv->segCount; i++)
dsp_ops_fft_memclear(conv->dsp, conv->segments[i], conv->fftComplexSize, false); spa_fga_dsp_fft_memclear(conv->dsp, conv->segments[i], conv->fftComplexSize, false);
dsp_ops_fft_memclear(conv->dsp, conv->overlap, conv->blockSize, true); spa_fga_dsp_fft_memclear(conv->dsp, conv->overlap, conv->blockSize, true);
dsp_ops_fft_memclear(conv->dsp, conv->inputBuffer, conv->segSize, true); spa_fga_dsp_fft_memclear(conv->dsp, conv->inputBuffer, conv->segSize, true);
dsp_ops_fft_memclear(conv->dsp, conv->pre_mult, conv->fftComplexSize, false); spa_fga_dsp_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->conv, conv->fftComplexSize, false);
conv->inputBufferFill = 0; conv->inputBufferFill = 0;
conv->current = 0; conv->current = 0;
} }
@ -63,26 +63,26 @@ static void convolver1_free(struct convolver1 *conv)
int i; int i;
for (i = 0; i < conv->segCount; i++) { for (i = 0; i < conv->segCount; i++) {
if (conv->segments) 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) 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) if (conv->fft)
dsp_ops_fft_free(conv->dsp, conv->fft); spa_fga_dsp_fft_free(conv->dsp, conv->fft);
if (conv->ifft) if (conv->ifft)
dsp_ops_fft_free(conv->dsp, conv->ifft); spa_fga_dsp_fft_free(conv->dsp, conv->ifft);
if (conv->fft_buffer) 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->segments);
free(conv->segmentsIr); free(conv->segmentsIr);
dsp_ops_fft_memfree(conv->dsp, conv->pre_mult); spa_fga_dsp_fft_memfree(conv->dsp, conv->pre_mult);
dsp_ops_fft_memfree(conv->dsp, conv->conv); spa_fga_dsp_fft_memfree(conv->dsp, conv->conv);
dsp_ops_fft_memfree(conv->dsp, conv->overlap); spa_fga_dsp_fft_memfree(conv->dsp, conv->overlap);
dsp_ops_fft_memfree(conv->dsp, conv->inputBuffer); spa_fga_dsp_fft_memfree(conv->dsp, conv->inputBuffer);
free(conv); 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; struct convolver1 *conv;
int i; 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->segCount = (irlen + conv->blockSize-1) / conv->blockSize;
conv->fftComplexSize = (conv->segSize / 2) + 1; 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) if (conv->fft == NULL)
goto error; 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) if (conv->ifft == NULL)
goto error; 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) if (conv->fft_buffer == NULL)
goto error; 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 left = irlen - (i * conv->blockSize);
int copy = SPA_MIN(conv->blockSize, left); int copy = SPA_MIN(conv->blockSize, left);
conv->segments[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] = dsp_ops_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) if (conv->segments[i] == NULL || conv->segmentsIr[i] == NULL)
goto error; 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) 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->pre_mult = spa_fga_dsp_fft_memalloc(conv->dsp, conv->fftComplexSize, false);
conv->conv = dsp_ops_fft_memalloc(conv->dsp, conv->fftComplexSize, false); conv->conv = spa_fga_dsp_fft_memalloc(conv->dsp, conv->fftComplexSize, false);
conv->overlap = dsp_ops_fft_memalloc(conv->dsp, conv->blockSize, true); conv->overlap = spa_fga_dsp_fft_memalloc(conv->dsp, conv->blockSize, true);
conv->inputBuffer = dsp_ops_fft_memalloc(conv->dsp, conv->segSize, true); conv->inputBuffer = spa_fga_dsp_fft_memalloc(conv->dsp, conv->segSize, true);
if (conv->pre_mult == NULL || conv->conv == NULL || conv->overlap == NULL || if (conv->pre_mult == NULL || conv->conv == NULL || conv->overlap == NULL ||
conv->inputBuffer == NULL) conv->inputBuffer == NULL)
goto error; goto error;
@ -158,7 +158,7 @@ static int convolver1_run(struct convolver1 *conv, const float *input, float *ou
int i, processed = 0; int i, processed = 0;
if (conv == NULL || conv->segCount == 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; 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 processing = SPA_MIN(len - processed, conv->blockSize - conv->inputBufferFill);
const int inputBufferPos = 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) 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->segCount > 1) {
if (conv->inputBufferFill == 0) { if (conv->inputBufferFill == 0) {
int indexAudio = (conv->current + 1) % conv->segCount; 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->segmentsIr[1],
conv->segments[indexAudio], conv->segments[indexAudio],
conv->fftComplexSize, conv->scale); 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++) { for (i = 2; i < conv->segCount; i++) {
indexAudio = (conv->current + i) % conv->segCount; 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->pre_mult, conv->pre_mult,
conv->segmentsIr[i], conv->segmentsIr[i],
@ -192,30 +192,30 @@ static int convolver1_run(struct convolver1 *conv, const float *input, float *ou
conv->fftComplexSize, conv->scale); conv->fftComplexSize, conv->scale);
} }
} }
dsp_ops_fft_cmuladd(conv->dsp, conv->fft, spa_fga_dsp_fft_cmuladd(conv->dsp, conv->fft,
conv->conv, conv->conv,
conv->pre_mult, conv->pre_mult,
conv->segments[conv->current], conv->segments[conv->current],
conv->segmentsIr[0], conv->segmentsIr[0],
conv->fftComplexSize, conv->scale); conv->fftComplexSize, conv->scale);
} else { } else {
dsp_ops_fft_cmul(conv->dsp, conv->fft, spa_fga_dsp_fft_cmul(conv->dsp, conv->fft,
conv->conv, conv->conv,
conv->segments[conv->current], conv->segments[conv->current],
conv->segmentsIr[0], conv->segmentsIr[0],
conv->fftComplexSize, conv->scale); 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->overlap + inputBufferPos, processing);
conv->inputBufferFill += processing; conv->inputBufferFill += processing;
if (conv->inputBufferFill == conv->blockSize) { if (conv->inputBufferFill == conv->blockSize) {
conv->inputBufferFill = 0; 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); 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 convolver
{ {
struct dsp_ops *dsp; struct spa_fga_dsp *dsp;
int headBlockSize; int headBlockSize;
int tailBlockSize; int tailBlockSize;
struct convolver1 *headConvolver; struct convolver1 *headConvolver;
@ -248,19 +248,19 @@ void convolver_reset(struct convolver *conv)
convolver1_reset(conv->headConvolver); convolver1_reset(conv->headConvolver);
if (conv->tailConvolver0) { if (conv->tailConvolver0) {
convolver1_reset(conv->tailConvolver0); convolver1_reset(conv->tailConvolver0);
dsp_ops_fft_memclear(conv->dsp, conv->tailOutput0, conv->tailBlockSize, true); spa_fga_dsp_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->tailPrecalculated0, conv->tailBlockSize, true);
} }
if (conv->tailConvolver) { if (conv->tailConvolver) {
convolver1_reset(conv->tailConvolver); convolver1_reset(conv->tailConvolver);
dsp_ops_fft_memclear(conv->dsp, conv->tailOutput, conv->tailBlockSize, true); spa_fga_dsp_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->tailPrecalculated, conv->tailBlockSize, true);
} }
conv->tailInputFill = 0; conv->tailInputFill = 0;
conv->precalculatedPos = 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; struct convolver *conv;
int head_ir_len; 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) if (irlen == 0)
return conv; return conv;
conv->dsp = dsp_ops; conv->dsp = dsp;
conv->headBlockSize = next_power_of_two(head_block); conv->headBlockSize = next_power_of_two(head_block);
conv->tailBlockSize = next_power_of_two(tail_block); conv->tailBlockSize = next_power_of_two(tail_block);
head_ir_len = SPA_MIN(irlen, conv->tailBlockSize); 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) if (conv->headConvolver == NULL)
goto error; goto error;
if (irlen > conv->tailBlockSize) { if (irlen > conv->tailBlockSize) {
int conv1IrLen = SPA_MIN(irlen - conv->tailBlockSize, conv->tailBlockSize); int conv1IrLen = SPA_MIN(irlen - conv->tailBlockSize, conv->tailBlockSize);
conv->tailConvolver0 = convolver1_new(dsp_ops, conv->headBlockSize, ir + conv->tailBlockSize, conv1IrLen); conv->tailConvolver0 = convolver1_new(dsp, conv->headBlockSize, ir + conv->tailBlockSize, conv1IrLen);
conv->tailOutput0 = dsp_ops_fft_memalloc(conv->dsp, conv->tailBlockSize, true); conv->tailOutput0 = spa_fga_dsp_fft_memalloc(conv->dsp, conv->tailBlockSize, true);
conv->tailPrecalculated0 = dsp_ops_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 || if (conv->tailConvolver0 == NULL || conv->tailOutput0 == NULL ||
conv->tailPrecalculated0 == NULL) conv->tailPrecalculated0 == NULL)
goto error; 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) { if (irlen > 2 * conv->tailBlockSize) {
int tailIrLen = irlen - (2 * conv->tailBlockSize); int tailIrLen = irlen - (2 * conv->tailBlockSize);
conv->tailConvolver = convolver1_new(dsp_ops, conv->tailBlockSize, ir + (2 * conv->tailBlockSize), tailIrLen); conv->tailConvolver = convolver1_new(dsp, conv->tailBlockSize, ir + (2 * conv->tailBlockSize), tailIrLen);
conv->tailOutput = dsp_ops_fft_memalloc(conv->dsp, conv->tailBlockSize, true); conv->tailOutput = spa_fga_dsp_fft_memalloc(conv->dsp, conv->tailBlockSize, true);
conv->tailPrecalculated = dsp_ops_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 || if (conv->tailConvolver == NULL || conv->tailOutput == NULL ||
conv->tailPrecalculated == NULL) conv->tailPrecalculated == NULL)
goto error; goto error;
} }
if (conv->tailConvolver0 || conv->tailConvolver) { 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) if (conv->tailInput == NULL)
goto error; goto error;
} }
@ -333,11 +333,11 @@ void convolver_free(struct convolver *conv)
convolver1_free(conv->tailConvolver0); convolver1_free(conv->tailConvolver0);
if (conv->tailConvolver) if (conv->tailConvolver)
convolver1_free(conv->tailConvolver); convolver1_free(conv->tailConvolver);
dsp_ops_fft_memfree(conv->dsp, conv->tailOutput0); spa_fga_dsp_fft_memfree(conv->dsp, conv->tailOutput0);
dsp_ops_fft_memfree(conv->dsp, conv->tailPrecalculated0); spa_fga_dsp_fft_memfree(conv->dsp, conv->tailPrecalculated0);
dsp_ops_fft_memfree(conv->dsp, conv->tailOutput); spa_fga_dsp_fft_memfree(conv->dsp, conv->tailOutput);
dsp_ops_fft_memfree(conv->dsp, conv->tailPrecalculated); spa_fga_dsp_fft_memfree(conv->dsp, conv->tailPrecalculated);
dsp_ops_fft_memfree(conv->dsp, conv->tailInput); spa_fga_dsp_fft_memfree(conv->dsp, conv->tailInput);
free(conv); 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)); int processing = SPA_MIN(remaining, conv->headBlockSize - (conv->tailInputFill % conv->headBlockSize));
if (conv->tailPrecalculated0) 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], &conv->tailPrecalculated0[conv->precalculatedPos],
processing); processing);
if (conv->tailPrecalculated) 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], &conv->tailPrecalculated[conv->precalculatedPos],
processing); processing);
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; conv->tailInputFill += processing;
if (conv->tailPrecalculated0 && (conv->tailInputFill % conv->headBlockSize == 0)) { if (conv->tailPrecalculated0 && (conv->tailInputFill % conv->headBlockSize == 0)) {

View file

@ -5,9 +5,9 @@
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#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_free(struct convolver *conv);
void convolver_reset(struct convolver *conv); void convolver_reset(struct convolver *conv);

View file

@ -1,84 +0,0 @@
/* Spa */
/* SPDX-FileCopyrightText: Copyright © 2022 Wim Taymans */
/* SPDX-License-Identifier: MIT */
#ifndef DSP_OPS_H
#define DSP_OPS_H
#include <spa/utils/defs.h>
#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 */

View file

@ -32,11 +32,7 @@
#include <spa/debug/types.h> #include <spa/debug/types.h>
#include <spa/debug/log.h> #include <spa/debug/log.h>
#include <pipewire/utils.h> #include "module-filter-chain/audio-dsp-impl.h"
#include <pipewire/impl.h>
#include <pipewire/pipewire.h>
#include "module-filter-chain/dsp-ops-impl.h"
#define NAME "filter-chain" #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 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 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 plugin {
struct spa_list link; struct spa_list link;
@ -206,11 +202,11 @@ struct impl {
struct spa_log *log; struct spa_log *log;
struct spa_cpu *cpu; struct spa_cpu *cpu;
struct spa_fga_dsp *dsp;
struct graph graph; struct graph graph;
uint32_t quantum_limit; uint32_t quantum_limit;
struct dsp_ops dsp;
uint32_t max_align; uint32_t max_align;
long unsigned rate; 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); spa_log_error(impl->log, "can't load plugin type '%s': %m", type);
pl = NULL; pl = NULL;
} else { } 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) if (pl == NULL)
goto exit; 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); impl->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
spa_log_topic_init(impl->log, &log_topic); 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->support[i] = support[i];
impl->n_support = n_support; impl->n_support = n_support;
impl->cpu = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_CPU); 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->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_list);
spa_list_init(&impl->plugin_func_list); spa_list_init(&impl->plugin_func_list);

View file

@ -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 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_fga_plugin *pl = NULL;
struct spa_log *log; struct spa_log *log;

View file

@ -468,7 +468,7 @@ static struct spa_fga_plugin_methods impl_plugin = {
SPA_EXPORT SPA_EXPORT
struct spa_fga_plugin *spa_filter_graph_audio_plugin_load(const struct spa_support *support, uint32_t n_support, 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; struct context *c;
const LilvPlugins *plugins; const LilvPlugins *plugins;

View file

@ -8,7 +8,7 @@
#include "audio-plugin.h" #include "audio-plugin.h"
#include "convolver.h" #include "convolver.h"
#include "dsp-ops.h" #include "audio-dsp.h"
#include "pffft.h" #include "pffft.h"
#include <mysofa.h> #include <mysofa.h>
@ -16,7 +16,7 @@
struct plugin { struct plugin {
struct spa_fga_plugin plugin; struct spa_fga_plugin plugin;
struct dsp_ops *dsp; struct spa_fga_dsp *dsp;
struct spa_log *log; struct spa_log *log;
struct spa_loop *data_loop; struct spa_loop *data_loop;
struct spa_loop *main_loop; struct spa_loop *main_loop;
@ -26,7 +26,7 @@ struct plugin {
struct spatializer_impl { struct spatializer_impl {
struct plugin *plugin; struct plugin *plugin;
struct dsp_ops *dsp; struct spa_fga_dsp *dsp;
struct spa_log *log; struct spa_log *log;
unsigned long rate; unsigned long rate;
@ -438,7 +438,7 @@ static struct spa_fga_plugin_methods impl_plugin = {
SPA_EXPORT SPA_EXPORT
struct spa_fga_plugin *spa_filter_graph_audio_plugin_load(const struct spa_support *support, uint32_t n_support, 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)); 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")) if (spa_streq(k, "clock.quantum-limit"))
spa_atou32(s, &impl->quantum_limit, 0); 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->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->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->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; return (struct spa_fga_plugin *) impl;
} }