filter-chain: move fft to dsp_ops

This commit is contained in:
Wim Taymans 2022-12-16 11:30:18 +01:00
parent b6b6efff42
commit f4f316b951
4 changed files with 102 additions and 52 deletions

View file

@ -30,8 +30,6 @@
#include <math.h> #include <math.h>
#include "pffft.h"
static struct dsp_ops *dsp; static struct dsp_ops *dsp;
struct convolver1 { struct convolver1 {
@ -98,42 +96,6 @@ static int next_power_of_two(int val)
return r; return r;
} }
static inline void *fft_new(int size)
{
return pffft_new_setup(size, PFFFT_REAL);
}
static inline void *ifft_new(int size)
{
return pffft_new_setup(size, PFFFT_REAL);
}
static inline void fft_destroy(void *fft)
{
pffft_destroy_setup(fft);
}
static inline void fft_run(void *fft, const float *in, float *out)
{
pffft_transform(fft, in, out, NULL, PFFFT_FORWARD);
}
static inline void ifft_run(void *ifft, const float *in, float *out)
{
pffft_transform(ifft, in, out, NULL, PFFFT_BACKWARD);
}
static inline void fft_convolve(void *fft, float *r,
const float *a, const float *b, int len, float scale)
{
pffft_zconvolve(fft, a, b, r, scale);
}
static inline void fft_convolve_accum(void *fft, float *r,
const float *c, const float *a, const float *b, int len, float scale)
{
pffft_zconvolve_accumulate(fft, a, b, c, r, scale);
}
static void convolver1_reset(struct convolver1 *conv) static void convolver1_reset(struct convolver1 *conv)
{ {
int i; int i;
@ -170,10 +132,10 @@ static struct convolver1 *convolver1_new(int block, const float *ir, int irlen)
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 = fft_new(conv->segSize); conv->fft = dsp_ops_fft_new(dsp, conv->segSize, true);
if (conv->fft == NULL) if (conv->fft == NULL)
goto error; goto error;
conv->ifft = ifft_new(conv->segSize); conv->ifft = dsp_ops_fft_new(dsp, conv->segSize, true);
if (conv->ifft == NULL) if (conv->ifft == NULL)
goto error; goto error;
@ -195,7 +157,7 @@ static struct convolver1 *convolver1_new(int block, const float *ir, int irlen)
if (copy < conv->segSize) if (copy < conv->segSize)
dsp_ops_clear(dsp, conv->fft_buffer + copy, conv->segSize - copy); dsp_ops_clear(dsp, conv->fft_buffer + copy, conv->segSize - copy);
fft_run(conv->fft, conv->fft_buffer, conv->segmentsIr[i]); dsp_ops_fft_run(dsp, conv->fft, 1, conv->fft_buffer, conv->segmentsIr[i]);
} }
conv->pre_mult = fft_cpx_alloc(conv->fftComplexSize); conv->pre_mult = fft_cpx_alloc(conv->fftComplexSize);
conv->conv = fft_cpx_alloc(conv->fftComplexSize); conv->conv = fft_cpx_alloc(conv->fftComplexSize);
@ -207,9 +169,9 @@ static struct convolver1 *convolver1_new(int block, const float *ir, int irlen)
return conv; return conv;
error: error:
if (conv->fft) if (conv->fft)
fft_destroy(conv->fft); dsp_ops_fft_free(dsp, conv->fft);
if (conv->ifft) if (conv->ifft)
fft_destroy(conv->ifft); dsp_ops_fft_free(dsp, conv->ifft);
if (conv->fft_buffer) if (conv->fft_buffer)
fft_free(conv->fft_buffer); fft_free(conv->fft_buffer);
free(conv); free(conv);
@ -224,9 +186,9 @@ static void convolver1_free(struct convolver1 *conv)
fft_cpx_free(conv->segmentsIr[i]); fft_cpx_free(conv->segmentsIr[i]);
} }
if (conv->fft) if (conv->fft)
fft_destroy(conv->fft); dsp_ops_fft_free(dsp, conv->fft);
if (conv->ifft) if (conv->ifft)
fft_destroy(conv->ifft); dsp_ops_fft_free(dsp, conv->ifft);
if (conv->fft_buffer) if (conv->fft_buffer)
fft_free(conv->fft_buffer); fft_free(conv->fft_buffer);
free(conv->segments); free(conv->segments);
@ -255,13 +217,13 @@ static int convolver1_run(struct convolver1 *conv, const float *input, float *ou
if (inputBufferPos == 0 && processing < conv->blockSize) if (inputBufferPos == 0 && processing < conv->blockSize)
dsp_ops_clear(dsp, conv->inputBuffer + processing, conv->blockSize - processing); dsp_ops_clear(dsp, conv->inputBuffer + processing, conv->blockSize - processing);
fft_run(conv->fft, conv->inputBuffer, conv->segments[conv->current]); dsp_ops_fft_run(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;
fft_convolve(conv->fft, conv->pre_mult, dsp_ops_fft_cmul(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);
@ -269,7 +231,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;
fft_convolve_accum(conv->fft, dsp_ops_fft_cmuladd(dsp, conv->fft,
conv->pre_mult, conv->pre_mult,
conv->pre_mult, conv->pre_mult,
conv->segmentsIr[i], conv->segmentsIr[i],
@ -277,20 +239,21 @@ static int convolver1_run(struct convolver1 *conv, const float *input, float *ou
conv->fftComplexSize, conv->scale); conv->fftComplexSize, conv->scale);
} }
} }
fft_convolve_accum(conv->fft, dsp_ops_fft_cmuladd(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 {
fft_convolve(conv->fft, conv->conv, dsp_ops_fft_cmul(dsp, conv->fft,
conv->conv,
conv->segments[conv->current], conv->segments[conv->current],
conv->segmentsIr[0], conv->segmentsIr[0],
conv->fftComplexSize, conv->scale); conv->fftComplexSize, conv->scale);
} }
ifft_run(conv->ifft, conv->conv, conv->fft_buffer); dsp_ops_fft_run(dsp, conv->ifft, -1, conv->conv, conv->fft_buffer);
dsp_ops_sum(dsp, output + processed, conv->fft_buffer + inputBufferPos, dsp_ops_sum(dsp, output + processed, conv->fft_buffer + inputBufferPos,
conv->overlap + inputBufferPos, processing); conv->overlap + inputBufferPos, processing);

View file

@ -29,6 +29,7 @@
#include <spa/utils/defs.h> #include <spa/utils/defs.h>
#include "pffft.h"
#include "dsp-ops.h" #include "dsp-ops.h"
void dsp_clear_c(struct dsp_ops *ops, void * SPA_RESTRICT dst, uint32_t n_samples) void dsp_clear_c(struct dsp_ops *ops, void * SPA_RESTRICT dst, uint32_t n_samples)
@ -141,3 +142,33 @@ void dsp_sum_c(struct dsp_ops *ops, float * dst,
dst[i] = a[i] + b[i]; dst[i] = a[i] + b[i];
} }
void *dsp_fft_new_c(struct dsp_ops *ops, int32_t size, bool real)
{
return pffft_new_setup(size, real ? PFFFT_REAL : PFFFT_COMPLEX);
}
void dsp_fft_free_c(struct dsp_ops *ops, void *fft)
{
pffft_destroy_setup(fft);
}
void dsp_fft_run_c(struct dsp_ops *ops, void *fft, int direction,
const float * SPA_RESTRICT src, float * SPA_RESTRICT dst)
{
pffft_transform(fft, src, dst, NULL, direction < 0 ? PFFFT_BACKWARD : PFFFT_FORWARD);
}
void dsp_fft_cmul_c(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)
{
pffft_zconvolve(fft, a, b, dst, scale);
}
void dsp_fft_cmuladd_c(struct dsp_ops *ops, 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)
{
pffft_zconvolve_accumulate(fft, a, b, src, dst, scale);
}

View file

@ -47,6 +47,11 @@ static struct dsp_info dsp_table[] =
.funcs.mix_gain = dsp_mix_gain_sse, .funcs.mix_gain = dsp_mix_gain_sse,
.funcs.biquad_run = dsp_biquad_run_c, .funcs.biquad_run = dsp_biquad_run_c,
.funcs.sum = dsp_sum_avx, .funcs.sum = dsp_sum_avx,
.funcs.fft_new = dsp_fft_new_c,
.funcs.fft_free = dsp_fft_free_c,
.funcs.fft_run = dsp_fft_run_c,
.funcs.fft_cmul = dsp_fft_cmul_c,
.funcs.fft_cmuladd = dsp_fft_cmuladd_c,
}, },
#endif #endif
#if defined (HAVE_SSE) #if defined (HAVE_SSE)
@ -56,6 +61,11 @@ static struct dsp_info dsp_table[] =
.funcs.mix_gain = dsp_mix_gain_sse, .funcs.mix_gain = dsp_mix_gain_sse,
.funcs.biquad_run = dsp_biquad_run_c, .funcs.biquad_run = dsp_biquad_run_c,
.funcs.sum = dsp_sum_sse, .funcs.sum = dsp_sum_sse,
.funcs.fft_new = dsp_fft_new_c,
.funcs.fft_free = dsp_fft_free_c,
.funcs.fft_run = dsp_fft_run_c,
.funcs.fft_cmul = dsp_fft_cmul_c,
.funcs.fft_cmuladd = dsp_fft_cmuladd_c,
}, },
#endif #endif
{ 0, { 0,
@ -64,6 +74,11 @@ static struct dsp_info dsp_table[] =
.funcs.mix_gain = dsp_mix_gain_c, .funcs.mix_gain = dsp_mix_gain_c,
.funcs.biquad_run = dsp_biquad_run_c, .funcs.biquad_run = dsp_biquad_run_c,
.funcs.sum = dsp_sum_c, .funcs.sum = dsp_sum_c,
.funcs.fft_new = dsp_fft_new_c,
.funcs.fft_free = dsp_fft_free_c,
.funcs.fft_run = dsp_fft_run_c,
.funcs.fft_cmul = dsp_fft_cmul_c,
.funcs.fft_cmuladd = dsp_fft_cmuladd_c,
}, },
}; };

View file

@ -45,6 +45,18 @@ struct dsp_ops_funcs {
void (*sum) (struct dsp_ops *ops, void (*sum) (struct dsp_ops *ops,
float * dst, const float * SPA_RESTRICT a, float * dst, const float * SPA_RESTRICT a,
const float * SPA_RESTRICT b, uint32_t n_samples); const float * SPA_RESTRICT b, uint32_t n_samples);
void *(*fft_new) (struct dsp_ops *ops, int32_t size, bool real);
void (*fft_free) (struct dsp_ops *ops, void *fft);
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);
}; };
struct dsp_ops { struct dsp_ops {
@ -67,6 +79,12 @@ int dsp_ops_init(struct dsp_ops *ops);
#define dsp_ops_biquad_run(ops,...) (ops)->funcs.biquad_run(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_sum(ops,...) (ops)->funcs.sum(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_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__)
#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(struct dsp_ops *ops, void * SPA_RESTRICT dst, uint32_t n_samples)
#define MAKE_COPY_FUNC(arch) \ #define MAKE_COPY_FUNC(arch) \
@ -80,14 +98,37 @@ void dsp_biquad_run_##arch (struct dsp_ops *ops, struct biquad *bq, \
float *out, const float *in, uint32_t n_samples) float *out, const float *in, 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 (struct dsp_ops *ops, 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_FFT_NEW_FUNC(arch) \
void *dsp_fft_new_##arch(struct dsp_ops *ops, int32_t size, bool real)
#define MAKE_FFT_FREE_FUNC(arch) \
void dsp_fft_free_##arch(struct dsp_ops *ops, void *fft)
#define MAKE_FFT_RUN_FUNC(arch) \
void dsp_fft_run_##arch(struct dsp_ops *ops, 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, \
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, \
float * dst, const float * src, \
const float * SPA_RESTRICT a, const float * SPA_RESTRICT b, \
uint32_t len, const float scale)
MAKE_CLEAR_FUNC(c); MAKE_CLEAR_FUNC(c);
MAKE_COPY_FUNC(c); MAKE_COPY_FUNC(c);
MAKE_MIX_GAIN_FUNC(c); MAKE_MIX_GAIN_FUNC(c);
MAKE_BIQUAD_RUN_FUNC(c); MAKE_BIQUAD_RUN_FUNC(c);
MAKE_SUM_FUNC(c); MAKE_SUM_FUNC(c);
MAKE_FFT_NEW_FUNC(c);
MAKE_FFT_FREE_FUNC(c);
MAKE_FFT_RUN_FUNC(c);
MAKE_FFT_CMUL_FUNC(c);
MAKE_FFT_CMULADD_FUNC(c);
#if defined (HAVE_SSE) #if defined (HAVE_SSE)
MAKE_MIX_GAIN_FUNC(sse); MAKE_MIX_GAIN_FUNC(sse);
MAKE_SUM_FUNC(sse); MAKE_SUM_FUNC(sse);