mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-05 13:30:02 -05:00
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:
parent
0a71911796
commit
13b8e3a75d
17 changed files with 312 additions and 302 deletions
|
|
@ -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],
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
@ -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)
|
||||||
|
|
@ -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)
|
||||||
|
|
@ -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)
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
103
src/modules/module-filter-chain/audio-dsp.h
Normal file
103
src/modules/module-filter-chain/audio-dsp.h
Normal 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 */
|
||||||
|
|
@ -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"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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)) {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue