mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-03 09:01:54 -05:00
filter-chain: move dsp_ops pointers to dynamically allocated memory
Make a plugin structure that is dynamically allocated for each plugin and pass it around to the descriptor instance structures, so that they all have access to dsp_ops without sharing a static pointer. The problem with the static pointer is that the dsp_ops structure is actually allocated in module-filter-chain's instance structure, so it always points to the instance of the last filter-chain that was loaded in the process. When this is unloaded, the other filter-chains crash.
This commit is contained in:
parent
b2dd733520
commit
c7854e1da4
7 changed files with 135 additions and 103 deletions
|
|
@ -2433,6 +2433,7 @@ static int graph_instantiate(struct graph *graph)
|
|||
struct link *link;
|
||||
struct descriptor *desc;
|
||||
const struct fc_descriptor *d;
|
||||
const struct fc_plugin *p;
|
||||
uint32_t i, j, max_samples = impl->quantum_limit;
|
||||
int res;
|
||||
float *sd, *dd;
|
||||
|
|
@ -2448,11 +2449,12 @@ static int graph_instantiate(struct graph *graph)
|
|||
|
||||
desc = node->desc;
|
||||
d = desc->desc;
|
||||
p = desc->plugin->plugin;
|
||||
|
||||
for (i = 0; i < node->n_hndl; i++) {
|
||||
pw_log_info("instantiate %s %s[%d] rate:%lu", d->name, node->name, i, impl->rate);
|
||||
errno = EINVAL;
|
||||
if ((node->hndl[i] = d->instantiate(d, impl->rate, i, node->config)) == NULL) {
|
||||
if ((node->hndl[i] = d->instantiate(p, d, impl->rate, i, node->config)) == NULL) {
|
||||
pw_log_error("cannot create plugin instance %d rate:%lu: %m", i, impl->rate);
|
||||
res = -errno;
|
||||
goto error;
|
||||
|
|
|
|||
|
|
@ -28,9 +28,13 @@
|
|||
|
||||
#define MAX_RATES 32u
|
||||
|
||||
static struct dsp_ops *dsp_ops;
|
||||
struct plugin {
|
||||
struct fc_plugin plugin;
|
||||
struct dsp_ops *dsp_ops;
|
||||
};
|
||||
|
||||
struct builtin {
|
||||
struct plugin *plugin;
|
||||
unsigned long rate;
|
||||
float *port[64];
|
||||
|
||||
|
|
@ -44,7 +48,7 @@ struct builtin {
|
|||
float accum;
|
||||
};
|
||||
|
||||
static void *builtin_instantiate(const struct fc_descriptor * Descriptor,
|
||||
static void *builtin_instantiate(const struct fc_plugin *plugin, const struct fc_descriptor * Descriptor,
|
||||
unsigned long SampleRate, int index, const char *config)
|
||||
{
|
||||
struct builtin *impl;
|
||||
|
|
@ -53,6 +57,7 @@ static void *builtin_instantiate(const struct fc_descriptor * Descriptor,
|
|||
if (impl == NULL)
|
||||
return NULL;
|
||||
|
||||
impl->plugin = (struct plugin *) plugin;
|
||||
impl->rate = SampleRate;
|
||||
|
||||
return impl;
|
||||
|
|
@ -75,7 +80,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(dsp_ops, out, in, SampleCount);
|
||||
dsp_ops_copy(impl->plugin->dsp_ops, out, in, SampleCount);
|
||||
}
|
||||
|
||||
static struct fc_port copy_ports[] = {
|
||||
|
|
@ -124,7 +129,7 @@ static void mixer_run(void * Instance, unsigned long SampleCount)
|
|||
src[n_src] = in;
|
||||
gains[n_src++] = gain;
|
||||
}
|
||||
dsp_ops_mix_gain(dsp_ops, out, src, gains, n_src, SampleCount);
|
||||
dsp_ops_mix_gain(impl->plugin->dsp_ops, out, src, gains, n_src, SampleCount);
|
||||
}
|
||||
|
||||
static struct fc_port mixer_ports[] = {
|
||||
|
|
@ -300,7 +305,7 @@ static void bq_raw_update(struct builtin *impl, float b0, float b1, float b2,
|
|||
* ]
|
||||
* }
|
||||
*/
|
||||
static void *bq_instantiate(const struct fc_descriptor * Descriptor,
|
||||
static void *bq_instantiate(const struct fc_plugin *plugin, const struct fc_descriptor * Descriptor,
|
||||
unsigned long SampleRate, int index, const char *config)
|
||||
{
|
||||
struct builtin *impl;
|
||||
|
|
@ -314,6 +319,7 @@ static void *bq_instantiate(const struct fc_descriptor * Descriptor,
|
|||
if (impl == NULL)
|
||||
return NULL;
|
||||
|
||||
impl->plugin = (struct plugin *) plugin;
|
||||
impl->rate = SampleRate;
|
||||
impl->b0 = impl->a0 = 1.0f;
|
||||
impl->type = bq_type_from_name(Descriptor->name);
|
||||
|
|
@ -526,7 +532,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(dsp_ops, bq, out, in, samples);
|
||||
dsp_ops_biquad_run(impl->plugin->dsp_ops, bq, out, in, samples);
|
||||
}
|
||||
|
||||
/** bq_lowpass */
|
||||
|
|
@ -658,6 +664,7 @@ static const struct fc_descriptor bq_raw_desc = {
|
|||
|
||||
/** convolve */
|
||||
struct convolver_impl {
|
||||
struct plugin *plugin;
|
||||
unsigned long rate;
|
||||
float *port[2];
|
||||
|
||||
|
|
@ -807,7 +814,7 @@ static float *create_dirac(const char *filename, float gain, int rate, float del
|
|||
return samples;
|
||||
}
|
||||
|
||||
static float *resample_buffer(float *samples, int *n_samples,
|
||||
static float *resample_buffer(struct dsp_ops *dsp_ops, float *samples, int *n_samples,
|
||||
unsigned long in_rate, unsigned long out_rate, uint32_t quality)
|
||||
{
|
||||
#ifdef HAVE_SPA_PLUGINS
|
||||
|
|
@ -884,7 +891,7 @@ error:
|
|||
#endif
|
||||
}
|
||||
|
||||
static void * convolver_instantiate(const struct fc_descriptor * Descriptor,
|
||||
static void * convolver_instantiate(const struct fc_plugin *plugin, const struct fc_descriptor * Descriptor,
|
||||
unsigned long SampleRate, int index, const char *config)
|
||||
{
|
||||
struct convolver_impl *impl;
|
||||
|
|
@ -1003,9 +1010,11 @@ static void * convolver_instantiate(const struct fc_descriptor * Descriptor,
|
|||
rate = SampleRate;
|
||||
samples = read_closest(filenames, gain, delay, offset,
|
||||
length, channel, &rate, &n_samples);
|
||||
if (samples != NULL && rate != SampleRate)
|
||||
samples = resample_buffer(samples, &n_samples,
|
||||
if (samples != NULL && rate != SampleRate) {
|
||||
struct plugin *p = (struct plugin *) plugin;
|
||||
samples = resample_buffer(p->dsp_ops, samples, &n_samples,
|
||||
rate, SampleRate, resample_quality);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_RATES; i++)
|
||||
|
|
@ -1029,9 +1038,10 @@ static void * convolver_instantiate(const struct fc_descriptor * Descriptor,
|
|||
if (impl == NULL)
|
||||
goto error;
|
||||
|
||||
impl->plugin = (struct plugin *) plugin;
|
||||
impl->rate = SampleRate;
|
||||
|
||||
impl->conv = convolver_new(dsp_ops, blocksize, tailsize, samples, n_samples);
|
||||
impl->conv = convolver_new(impl->plugin->dsp_ops, blocksize, tailsize, samples, n_samples);
|
||||
if (impl->conv == NULL)
|
||||
goto error;
|
||||
|
||||
|
|
@ -1099,6 +1109,7 @@ static const struct fc_descriptor convolve_desc = {
|
|||
|
||||
/** delay */
|
||||
struct delay_impl {
|
||||
struct plugin *plugin;
|
||||
unsigned long rate;
|
||||
float *port[4];
|
||||
|
||||
|
|
@ -1116,7 +1127,7 @@ static void delay_cleanup(void * Instance)
|
|||
free(impl);
|
||||
}
|
||||
|
||||
static void *delay_instantiate(const struct fc_descriptor * Descriptor,
|
||||
static void *delay_instantiate(const struct fc_plugin *plugin, const struct fc_descriptor * Descriptor,
|
||||
unsigned long SampleRate, int index, const char *config)
|
||||
{
|
||||
struct delay_impl *impl;
|
||||
|
|
@ -1154,6 +1165,7 @@ static void *delay_instantiate(const struct fc_descriptor * Descriptor,
|
|||
if (impl == NULL)
|
||||
return NULL;
|
||||
|
||||
impl->plugin = (struct plugin *) plugin;
|
||||
impl->rate = SampleRate;
|
||||
impl->buffer_samples = SPA_ROUND_UP_N((uint32_t)(max_delay * impl->rate), 64);
|
||||
pw_log_info("max-delay:%f seconds rate:%lu samples:%d", max_delay, impl->rate, impl->buffer_samples);
|
||||
|
|
@ -1188,7 +1200,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(dsp_ops, impl->buffer, &impl->ptr, impl->buffer_samples,
|
||||
dsp_ops_delay(impl->plugin->dsp_ops, impl->buffer, &impl->ptr, impl->buffer_samples,
|
||||
impl->delay_samples, out, in, SampleCount);
|
||||
}
|
||||
|
||||
|
|
@ -1322,7 +1334,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(dsp_ops, out, in, mult, add, SampleCount);
|
||||
dsp_ops_linear(impl->plugin->dsp_ops, out, in, mult, add, SampleCount);
|
||||
|
||||
if (ctrl != NULL && notify != NULL)
|
||||
notify[0] = ctrl[0] * mult + add;
|
||||
|
|
@ -1567,7 +1579,7 @@ static void mult_run(void * Instance, unsigned long SampleCount)
|
|||
|
||||
src[n_src++] = in;
|
||||
}
|
||||
dsp_ops_mult(dsp_ops, out, src, n_src, SampleCount);
|
||||
dsp_ops_mult(impl->plugin->dsp_ops, out, src, n_src, SampleCount);
|
||||
}
|
||||
|
||||
static struct fc_port mult_ports[] = {
|
||||
|
|
@ -1693,6 +1705,7 @@ static const struct fc_descriptor sine_desc = {
|
|||
|
||||
#define PARAM_EQ_MAX 64
|
||||
struct param_eq_impl {
|
||||
struct plugin *plugin;
|
||||
unsigned long rate;
|
||||
float *port[8*2];
|
||||
|
||||
|
|
@ -1859,7 +1872,7 @@ static int parse_filters(struct spa_json *iter, int rate, struct biquad *bq, uin
|
|||
* filtersX = [ ... ] # to load channel X
|
||||
* }
|
||||
*/
|
||||
static void *param_eq_instantiate(const struct fc_descriptor * Descriptor,
|
||||
static void *param_eq_instantiate(const struct fc_plugin *plugin, const struct fc_descriptor * Descriptor,
|
||||
unsigned long SampleRate, int index, const char *config)
|
||||
{
|
||||
struct spa_json it[3];
|
||||
|
|
@ -1884,6 +1897,7 @@ static void *param_eq_instantiate(const struct fc_descriptor * Descriptor,
|
|||
if (impl == NULL)
|
||||
return NULL;
|
||||
|
||||
impl->plugin = (struct plugin *) plugin;
|
||||
impl->rate = SampleRate;
|
||||
for (i = 0; i < SPA_N_ELEMENTS(impl->bq); i++)
|
||||
biquad_set(&impl->bq[i], BQ_NONE, 0.0f, 0.0f, 0.0f);
|
||||
|
|
@ -1950,7 +1964,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_biquadn_run(dsp_ops, impl->bq, impl->n_bq, PARAM_EQ_MAX,
|
||||
dsp_ops_biquadn_run(impl->plugin->dsp_ops, impl->bq, impl->n_bq, PARAM_EQ_MAX,
|
||||
&impl->port[8], (const float**)impl->port, 8, SampleCount);
|
||||
}
|
||||
|
||||
|
|
@ -2099,14 +2113,18 @@ static const struct fc_descriptor *builtin_make_desc(struct fc_plugin *plugin, c
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static struct fc_plugin builtin_plugin = {
|
||||
.make_desc = builtin_make_desc
|
||||
};
|
||||
static void builtin_plugin_unload(struct fc_plugin *p)
|
||||
{
|
||||
free(p);
|
||||
}
|
||||
|
||||
struct fc_plugin *load_builtin_plugin(const struct spa_support *support, uint32_t n_support,
|
||||
struct dsp_ops *dsp, const char *plugin, const char *config)
|
||||
{
|
||||
dsp_ops = dsp;
|
||||
struct plugin *impl = calloc (1, sizeof (struct plugin));
|
||||
impl->plugin.make_desc = builtin_make_desc;
|
||||
impl->plugin.unload = builtin_plugin_unload;
|
||||
impl->dsp_ops = dsp;
|
||||
pffft_select_cpu(dsp->cpu_flags);
|
||||
return &builtin_plugin;
|
||||
return (struct fc_plugin *) impl;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@
|
|||
|
||||
#include <math.h>
|
||||
|
||||
static struct dsp_ops *dsp;
|
||||
|
||||
struct convolver1 {
|
||||
struct dsp_ops *dsp;
|
||||
|
||||
int blockSize;
|
||||
int segSize;
|
||||
int segCount;
|
||||
|
|
@ -49,11 +49,11 @@ static void convolver1_reset(struct convolver1 *conv)
|
|||
{
|
||||
int i;
|
||||
for (i = 0; i < conv->segCount; i++)
|
||||
dsp_ops_fft_memclear(dsp, conv->segments[i], conv->fftComplexSize, false);
|
||||
dsp_ops_fft_memclear(dsp, conv->overlap, conv->blockSize, true);
|
||||
dsp_ops_fft_memclear(dsp, conv->inputBuffer, conv->segSize, true);
|
||||
dsp_ops_fft_memclear(dsp, conv->pre_mult, conv->fftComplexSize, false);
|
||||
dsp_ops_fft_memclear(dsp, conv->conv, conv->fftComplexSize, false);
|
||||
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);
|
||||
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(dsp, conv->segments[i]);
|
||||
dsp_ops_fft_memfree(conv->dsp, conv->segments[i]);
|
||||
if (conv->segmentsIr)
|
||||
dsp_ops_fft_memfree(dsp, conv->segmentsIr[i]);
|
||||
dsp_ops_fft_memfree(conv->dsp, conv->segmentsIr[i]);
|
||||
}
|
||||
if (conv->fft)
|
||||
dsp_ops_fft_free(dsp, conv->fft);
|
||||
dsp_ops_fft_free(conv->dsp, conv->fft);
|
||||
if (conv->ifft)
|
||||
dsp_ops_fft_free(dsp, conv->ifft);
|
||||
dsp_ops_fft_free(conv->dsp, conv->ifft);
|
||||
if (conv->fft_buffer)
|
||||
dsp_ops_fft_memfree(dsp, conv->fft_buffer);
|
||||
dsp_ops_fft_memfree(conv->dsp, conv->fft_buffer);
|
||||
free(conv->segments);
|
||||
free(conv->segmentsIr);
|
||||
dsp_ops_fft_memfree(dsp, conv->pre_mult);
|
||||
dsp_ops_fft_memfree(dsp, conv->conv);
|
||||
dsp_ops_fft_memfree(dsp, conv->overlap);
|
||||
dsp_ops_fft_memfree(dsp, conv->inputBuffer);
|
||||
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);
|
||||
free(conv);
|
||||
}
|
||||
|
||||
static struct convolver1 *convolver1_new(int block, const float *ir, int irlen)
|
||||
static struct convolver1 *convolver1_new(struct dsp_ops *dsp, int block, const float *ir, int irlen)
|
||||
{
|
||||
struct convolver1 *conv;
|
||||
int i;
|
||||
|
|
@ -100,19 +100,20 @@ static struct convolver1 *convolver1_new(int block, const float *ir, int irlen)
|
|||
if (irlen == 0)
|
||||
return conv;
|
||||
|
||||
conv->dsp = dsp;
|
||||
conv->blockSize = next_power_of_two(block);
|
||||
conv->segSize = 2 * conv->blockSize;
|
||||
conv->segCount = (irlen + conv->blockSize-1) / conv->blockSize;
|
||||
conv->fftComplexSize = (conv->segSize / 2) + 1;
|
||||
|
||||
conv->fft = dsp_ops_fft_new(dsp, conv->segSize, true);
|
||||
conv->fft = dsp_ops_fft_new(conv->dsp, conv->segSize, true);
|
||||
if (conv->fft == NULL)
|
||||
goto error;
|
||||
conv->ifft = dsp_ops_fft_new(dsp, conv->segSize, true);
|
||||
conv->ifft = dsp_ops_fft_new(conv->dsp, conv->segSize, true);
|
||||
if (conv->ifft == NULL)
|
||||
goto error;
|
||||
|
||||
conv->fft_buffer = dsp_ops_fft_memalloc(dsp, conv->segSize, true);
|
||||
conv->fft_buffer = dsp_ops_fft_memalloc(conv->dsp, conv->segSize, true);
|
||||
if (conv->fft_buffer == NULL)
|
||||
goto error;
|
||||
|
||||
|
|
@ -125,21 +126,21 @@ static struct convolver1 *convolver1_new(int block, const float *ir, int irlen)
|
|||
int left = irlen - (i * conv->blockSize);
|
||||
int copy = SPA_MIN(conv->blockSize, left);
|
||||
|
||||
conv->segments[i] = dsp_ops_fft_memalloc(dsp, conv->fftComplexSize, false);
|
||||
conv->segmentsIr[i] = dsp_ops_fft_memalloc(dsp, conv->fftComplexSize, false);
|
||||
conv->segments[i] = dsp_ops_fft_memalloc(conv->dsp, conv->fftComplexSize, false);
|
||||
conv->segmentsIr[i] = dsp_ops_fft_memalloc(conv->dsp, conv->fftComplexSize, false);
|
||||
if (conv->segments[i] == NULL || conv->segmentsIr[i] == NULL)
|
||||
goto error;
|
||||
|
||||
dsp_ops_copy(dsp, conv->fft_buffer, &ir[i * conv->blockSize], copy);
|
||||
dsp_ops_copy(conv->dsp, conv->fft_buffer, &ir[i * conv->blockSize], copy);
|
||||
if (copy < conv->segSize)
|
||||
dsp_ops_fft_memclear(dsp, conv->fft_buffer + copy, conv->segSize - copy, true);
|
||||
dsp_ops_fft_memclear(conv->dsp, conv->fft_buffer + copy, conv->segSize - copy, true);
|
||||
|
||||
dsp_ops_fft_run(dsp, conv->fft, 1, conv->fft_buffer, conv->segmentsIr[i]);
|
||||
dsp_ops_fft_run(conv->dsp, conv->fft, 1, conv->fft_buffer, conv->segmentsIr[i]);
|
||||
}
|
||||
conv->pre_mult = dsp_ops_fft_memalloc(dsp, conv->fftComplexSize, false);
|
||||
conv->conv = dsp_ops_fft_memalloc(dsp, conv->fftComplexSize, false);
|
||||
conv->overlap = dsp_ops_fft_memalloc(dsp, conv->blockSize, true);
|
||||
conv->inputBuffer = dsp_ops_fft_memalloc(dsp, conv->segSize, true);
|
||||
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);
|
||||
if (conv->pre_mult == NULL || conv->conv == NULL || conv->overlap == NULL ||
|
||||
conv->inputBuffer == NULL)
|
||||
goto error;
|
||||
|
|
@ -157,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(dsp, output, len, true);
|
||||
dsp_ops_fft_memclear(conv->dsp, output, len, true);
|
||||
return len;
|
||||
}
|
||||
|
||||
|
|
@ -165,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(dsp, conv->inputBuffer + inputBufferPos, input + processed, processing);
|
||||
dsp_ops_copy(conv->dsp, conv->inputBuffer + inputBufferPos, input + processed, processing);
|
||||
if (inputBufferPos == 0 && processing < conv->blockSize)
|
||||
dsp_ops_fft_memclear(dsp, conv->inputBuffer + processing, conv->blockSize - processing, true);
|
||||
dsp_ops_fft_memclear(conv->dsp, conv->inputBuffer + processing, conv->blockSize - processing, true);
|
||||
|
||||
dsp_ops_fft_run(dsp, conv->fft, 1, conv->inputBuffer, conv->segments[conv->current]);
|
||||
dsp_ops_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(dsp, conv->fft, conv->pre_mult,
|
||||
dsp_ops_fft_cmul(conv->dsp, conv->fft, conv->pre_mult,
|
||||
conv->segmentsIr[1],
|
||||
conv->segments[indexAudio],
|
||||
conv->fftComplexSize, conv->scale);
|
||||
|
|
@ -183,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(dsp, conv->fft,
|
||||
dsp_ops_fft_cmuladd(conv->dsp, conv->fft,
|
||||
conv->pre_mult,
|
||||
conv->pre_mult,
|
||||
conv->segmentsIr[i],
|
||||
|
|
@ -191,30 +192,30 @@ static int convolver1_run(struct convolver1 *conv, const float *input, float *ou
|
|||
conv->fftComplexSize, conv->scale);
|
||||
}
|
||||
}
|
||||
dsp_ops_fft_cmuladd(dsp, conv->fft,
|
||||
dsp_ops_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(dsp, conv->fft,
|
||||
dsp_ops_fft_cmul(conv->dsp, conv->fft,
|
||||
conv->conv,
|
||||
conv->segments[conv->current],
|
||||
conv->segmentsIr[0],
|
||||
conv->fftComplexSize, conv->scale);
|
||||
}
|
||||
|
||||
dsp_ops_fft_run(dsp, conv->ifft, -1, conv->conv, conv->fft_buffer);
|
||||
dsp_ops_fft_run(conv->dsp, conv->ifft, -1, conv->conv, conv->fft_buffer);
|
||||
|
||||
dsp_ops_sum(dsp, output + processed, conv->fft_buffer + inputBufferPos,
|
||||
dsp_ops_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(dsp, conv->overlap, conv->fft_buffer + conv->blockSize, conv->blockSize);
|
||||
dsp_ops_copy(conv->dsp, conv->overlap, conv->fft_buffer + conv->blockSize, conv->blockSize);
|
||||
|
||||
conv->current = (conv->current > 0) ? (conv->current - 1) : (conv->segCount - 1);
|
||||
}
|
||||
|
|
@ -226,6 +227,7 @@ static int convolver1_run(struct convolver1 *conv, const float *input, float *ou
|
|||
|
||||
struct convolver
|
||||
{
|
||||
struct dsp_ops *dsp;
|
||||
int headBlockSize;
|
||||
int tailBlockSize;
|
||||
struct convolver1 *headConvolver;
|
||||
|
|
@ -246,13 +248,13 @@ void convolver_reset(struct convolver *conv)
|
|||
convolver1_reset(conv->headConvolver);
|
||||
if (conv->tailConvolver0) {
|
||||
convolver1_reset(conv->tailConvolver0);
|
||||
dsp_ops_fft_memclear(dsp, conv->tailOutput0, conv->tailBlockSize, true);
|
||||
dsp_ops_fft_memclear(dsp, conv->tailPrecalculated0, conv->tailBlockSize, true);
|
||||
dsp_ops_fft_memclear(conv->dsp, conv->tailOutput0, conv->tailBlockSize, true);
|
||||
dsp_ops_fft_memclear(conv->dsp, conv->tailPrecalculated0, conv->tailBlockSize, true);
|
||||
}
|
||||
if (conv->tailConvolver) {
|
||||
convolver1_reset(conv->tailConvolver);
|
||||
dsp_ops_fft_memclear(dsp, conv->tailOutput, conv->tailBlockSize, true);
|
||||
dsp_ops_fft_memclear(dsp, conv->tailPrecalculated, conv->tailBlockSize, true);
|
||||
dsp_ops_fft_memclear(conv->dsp, conv->tailOutput, conv->tailBlockSize, true);
|
||||
dsp_ops_fft_memclear(conv->dsp, conv->tailPrecalculated, conv->tailBlockSize, true);
|
||||
}
|
||||
conv->tailInputFill = 0;
|
||||
conv->precalculatedPos = 0;
|
||||
|
|
@ -263,8 +265,6 @@ struct convolver *convolver_new(struct dsp_ops *dsp_ops, int head_block, int tai
|
|||
struct convolver *conv;
|
||||
int head_ir_len;
|
||||
|
||||
dsp = dsp_ops;
|
||||
|
||||
if (head_block == 0 || tail_block == 0)
|
||||
return NULL;
|
||||
|
||||
|
|
@ -282,19 +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->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(conv->headBlockSize, ir, head_ir_len);
|
||||
conv->headConvolver = convolver1_new(dsp_ops, 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(conv->headBlockSize, ir + conv->tailBlockSize, conv1IrLen);
|
||||
conv->tailOutput0 = dsp_ops_fft_memalloc(dsp, conv->tailBlockSize, true);
|
||||
conv->tailPrecalculated0 = dsp_ops_fft_memalloc(dsp, conv->tailBlockSize, true);
|
||||
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);
|
||||
if (conv->tailConvolver0 == NULL || conv->tailOutput0 == NULL ||
|
||||
conv->tailPrecalculated0 == NULL)
|
||||
goto error;
|
||||
|
|
@ -302,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(conv->tailBlockSize, ir + (2 * conv->tailBlockSize), tailIrLen);
|
||||
conv->tailOutput = dsp_ops_fft_memalloc(dsp, conv->tailBlockSize, true);
|
||||
conv->tailPrecalculated = dsp_ops_fft_memalloc(dsp, conv->tailBlockSize, true);
|
||||
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);
|
||||
if (conv->tailConvolver == NULL || conv->tailOutput == NULL ||
|
||||
conv->tailPrecalculated == NULL)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (conv->tailConvolver0 || conv->tailConvolver) {
|
||||
conv->tailInput = dsp_ops_fft_memalloc(dsp, conv->tailBlockSize, true);
|
||||
conv->tailInput = dsp_ops_fft_memalloc(conv->dsp, conv->tailBlockSize, true);
|
||||
if (conv->tailInput == NULL)
|
||||
goto error;
|
||||
}
|
||||
|
|
@ -332,11 +333,11 @@ void convolver_free(struct convolver *conv)
|
|||
convolver1_free(conv->tailConvolver0);
|
||||
if (conv->tailConvolver)
|
||||
convolver1_free(conv->tailConvolver);
|
||||
dsp_ops_fft_memfree(dsp, conv->tailOutput0);
|
||||
dsp_ops_fft_memfree(dsp, conv->tailPrecalculated0);
|
||||
dsp_ops_fft_memfree(dsp, conv->tailOutput);
|
||||
dsp_ops_fft_memfree(dsp, conv->tailPrecalculated);
|
||||
dsp_ops_fft_memfree(dsp, conv->tailInput);
|
||||
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);
|
||||
free(conv);
|
||||
}
|
||||
|
||||
|
|
@ -352,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(dsp, &output[processed], &output[processed],
|
||||
dsp_ops_sum(conv->dsp, &output[processed], &output[processed],
|
||||
&conv->tailPrecalculated0[conv->precalculatedPos],
|
||||
processing);
|
||||
if (conv->tailPrecalculated)
|
||||
dsp_ops_sum(dsp, &output[processed], &output[processed],
|
||||
dsp_ops_sum(conv->dsp, &output[processed], &output[processed],
|
||||
&conv->tailPrecalculated[conv->precalculatedPos],
|
||||
processing);
|
||||
conv->precalculatedPos += processing;
|
||||
|
||||
dsp_ops_copy(dsp, conv->tailInput + conv->tailInputFill, input + processed, processing);
|
||||
dsp_ops_copy(conv->dsp, conv->tailInput + conv->tailInputFill, input + processed, processing);
|
||||
conv->tailInputFill += processing;
|
||||
|
||||
if (conv->tailPrecalculated0 && (conv->tailInputFill % conv->headBlockSize == 0)) {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ struct descriptor {
|
|||
const LADSPA_Descriptor *d;
|
||||
};
|
||||
|
||||
static void *ladspa_instantiate(const struct fc_descriptor *desc,
|
||||
static void *ladspa_instantiate(const struct fc_plugin *plugin, const struct fc_descriptor *desc,
|
||||
unsigned long SampleRate, int index, const char *config)
|
||||
{
|
||||
struct descriptor *d = (struct descriptor *)desc;
|
||||
|
|
|
|||
|
|
@ -278,7 +278,7 @@ work_schedule(LV2_Worker_Schedule_Handle handle, uint32_t size, const void *data
|
|||
return LV2_WORKER_SUCCESS;
|
||||
}
|
||||
|
||||
static void *lv2_instantiate(const struct fc_descriptor *desc,
|
||||
static void *lv2_instantiate(const struct fc_plugin *plugin, const struct fc_descriptor *desc,
|
||||
unsigned long SampleRate, int index, const char *config)
|
||||
{
|
||||
struct descriptor *d = (struct descriptor*)desc;
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ struct fc_descriptor {
|
|||
uint32_t n_ports;
|
||||
struct fc_port *ports;
|
||||
|
||||
void *(*instantiate) (const struct fc_descriptor *desc,
|
||||
void *(*instantiate) (const struct fc_plugin *plugin, const struct fc_descriptor *desc,
|
||||
unsigned long SampleRate, int index, const char *config);
|
||||
|
||||
void (*cleanup) (void *instance);
|
||||
|
|
|
|||
|
|
@ -16,11 +16,15 @@
|
|||
|
||||
#define MAX_SAMPLES 8192u
|
||||
|
||||
static struct dsp_ops *dsp_ops;
|
||||
static struct spa_loop *data_loop;
|
||||
static struct spa_loop *main_loop;
|
||||
struct plugin {
|
||||
struct fc_plugin plugin;
|
||||
struct dsp_ops *dsp_ops;
|
||||
struct spa_loop *data_loop;
|
||||
struct spa_loop *main_loop;
|
||||
};
|
||||
|
||||
struct spatializer_impl {
|
||||
struct plugin *plugin;
|
||||
unsigned long rate;
|
||||
float *port[6];
|
||||
int n_samples, blocksize, tailsize;
|
||||
|
|
@ -32,7 +36,7 @@ struct spatializer_impl {
|
|||
struct convolver *r_conv[3];
|
||||
};
|
||||
|
||||
static void * spatializer_instantiate(const struct fc_descriptor * Descriptor,
|
||||
static void * spatializer_instantiate(const struct fc_plugin *plugin, const struct fc_descriptor * Descriptor,
|
||||
unsigned long SampleRate, int index, const char *config)
|
||||
{
|
||||
struct spatializer_impl *impl;
|
||||
|
|
@ -59,6 +63,8 @@ static void * spatializer_instantiate(const struct fc_descriptor * Descriptor,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
impl->plugin = (struct plugin *) plugin;
|
||||
|
||||
while ((len = spa_json_object_next(&it[0], key, sizeof(key), &val)) > 0) {
|
||||
if (spa_streq(key, "blocksize")) {
|
||||
if (spa_json_parse_int(val, len, &impl->blocksize) <= 0) {
|
||||
|
|
@ -237,9 +243,9 @@ static void spatializer_reload(void * Instance)
|
|||
if (impl->r_conv[2])
|
||||
convolver_free(impl->r_conv[2]);
|
||||
|
||||
impl->l_conv[2] = convolver_new(dsp_ops, impl->blocksize, impl->tailsize,
|
||||
impl->l_conv[2] = convolver_new(impl->plugin->dsp_ops, impl->blocksize, impl->tailsize,
|
||||
left_ir, impl->n_samples);
|
||||
impl->r_conv[2] = convolver_new(dsp_ops, impl->blocksize, impl->tailsize,
|
||||
impl->r_conv[2] = convolver_new(impl->plugin->dsp_ops, impl->blocksize, impl->tailsize,
|
||||
right_ir, impl->n_samples);
|
||||
|
||||
free(left_ir);
|
||||
|
|
@ -249,7 +255,7 @@ static void spatializer_reload(void * Instance)
|
|||
pw_log_error("reloading left or right convolver failed");
|
||||
return;
|
||||
}
|
||||
spa_loop_invoke(data_loop, do_switch, 1, NULL, 0, true, impl);
|
||||
spa_loop_invoke(impl->plugin->data_loop, do_switch, 1, NULL, 0, true, impl);
|
||||
}
|
||||
|
||||
struct free_data {
|
||||
|
|
@ -294,7 +300,7 @@ static void spatializer_run(void * Instance, unsigned long SampleCount)
|
|||
impl->l_conv[1] = impl->r_conv[1] = NULL;
|
||||
impl->interpolate = false;
|
||||
|
||||
spa_loop_invoke(main_loop, do_free, 1, &free_data, sizeof(free_data), false, impl);
|
||||
spa_loop_invoke(impl->plugin->main_loop, do_free, 1, &free_data, sizeof(free_data), false, impl);
|
||||
} else if (impl->l_conv[0] && impl->r_conv[0]) {
|
||||
convolver_run(impl->l_conv[0], impl->port[2], impl->port[0], SampleCount);
|
||||
convolver_run(impl->r_conv[0], impl->port[2], impl->port[1], SampleCount);
|
||||
|
|
@ -411,19 +417,24 @@ static const struct fc_descriptor *sofa_make_desc(struct fc_plugin *plugin, cons
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static struct fc_plugin builtin_plugin = {
|
||||
.make_desc = sofa_make_desc
|
||||
};
|
||||
static void sofa_plugin_unload(struct fc_plugin *p)
|
||||
{
|
||||
free(p);
|
||||
}
|
||||
|
||||
SPA_EXPORT
|
||||
struct fc_plugin *pipewire__filter_chain_plugin_load(const struct spa_support *support, uint32_t n_support,
|
||||
struct dsp_ops *dsp, const char *plugin, const char *config)
|
||||
{
|
||||
dsp_ops = dsp;
|
||||
struct plugin *impl = calloc(1, sizeof (struct plugin));
|
||||
impl->plugin.make_desc = sofa_make_desc;
|
||||
impl->plugin.unload = sofa_plugin_unload;
|
||||
|
||||
impl->dsp_ops = dsp;
|
||||
pffft_select_cpu(dsp->cpu_flags);
|
||||
|
||||
data_loop = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_DataLoop);
|
||||
main_loop = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Loop);
|
||||
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);
|
||||
|
||||
return &builtin_plugin;
|
||||
return (struct fc_plugin *) impl;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue