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
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],

View file

@ -13,24 +13,14 @@
#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/tag-utils.h>
#include <spa/param/audio/raw-json.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/extensions/profiler.h>
#include "module-filter-chain/dsp-ops-impl.h"
#include "module-filter-chain/filter-graph.h"
#define NAME "filter-chain"

View file

@ -12,11 +12,11 @@
#ifndef HAVE_FFTW
#include "pffft.h"
#endif
#include "dsp-ops.h"
#include "audio-dsp-impl.h"
#include <immintrin.h>
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)

View file

@ -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)

View file

@ -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)

View file

@ -15,11 +15,11 @@
#include "pffft.h"
#endif
#include "dsp-ops-impl.h"
#include "audio-dsp-impl.h"
#include <xmmintrin.h>
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)

View file

@ -11,15 +11,15 @@
#include <spa/utils/defs.h>
#include <spa/param/audio/format-utils.h>
#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;
}

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/support/plugin.h>
#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"

View file

@ -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;

View file

@ -11,7 +11,7 @@
#include <math.h>
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)) {

View file

@ -5,9 +5,9 @@
#include <stdint.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_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/log.h>
#include <pipewire/utils.h>
#include <pipewire/impl.h>
#include <pipewire/pipewire.h>
#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);

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 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;

View file

@ -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;

View file

@ -8,7 +8,7 @@
#include "audio-plugin.h"
#include "convolver.h"
#include "dsp-ops.h"
#include "audio-dsp.h"
#include "pffft.h"
#include <mysofa.h>
@ -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;
}