From c7854e1da4a38eee1a82a35a0ee1af825abf1017 Mon Sep 17 00:00:00 2001 From: George Kiagiadakis Date: Wed, 6 Nov 2024 20:11:40 +0200 Subject: [PATCH] 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. --- src/modules/module-filter-chain.c | 4 +- .../module-filter-chain/builtin_plugin.c | 62 ++++++--- src/modules/module-filter-chain/convolver.c | 125 +++++++++--------- .../module-filter-chain/ladspa_plugin.c | 2 +- src/modules/module-filter-chain/lv2_plugin.c | 2 +- src/modules/module-filter-chain/plugin.h | 2 +- src/modules/module-filter-chain/sofa_plugin.c | 41 +++--- 7 files changed, 135 insertions(+), 103 deletions(-) diff --git a/src/modules/module-filter-chain.c b/src/modules/module-filter-chain.c index fb79e1989..06c722197 100644 --- a/src/modules/module-filter-chain.c +++ b/src/modules/module-filter-chain.c @@ -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; diff --git a/src/modules/module-filter-chain/builtin_plugin.c b/src/modules/module-filter-chain/builtin_plugin.c index 297f1c54b..fd588b8b6 100644 --- a/src/modules/module-filter-chain/builtin_plugin.c +++ b/src/modules/module-filter-chain/builtin_plugin.c @@ -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; } diff --git a/src/modules/module-filter-chain/convolver.c b/src/modules/module-filter-chain/convolver.c index da422e063..20d2a047e 100644 --- a/src/modules/module-filter-chain/convolver.c +++ b/src/modules/module-filter-chain/convolver.c @@ -10,9 +10,9 @@ #include -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)) { diff --git a/src/modules/module-filter-chain/ladspa_plugin.c b/src/modules/module-filter-chain/ladspa_plugin.c index a2e579344..6fb0aa2b5 100644 --- a/src/modules/module-filter-chain/ladspa_plugin.c +++ b/src/modules/module-filter-chain/ladspa_plugin.c @@ -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; diff --git a/src/modules/module-filter-chain/lv2_plugin.c b/src/modules/module-filter-chain/lv2_plugin.c index 861a4a1a4..713ec4e06 100644 --- a/src/modules/module-filter-chain/lv2_plugin.c +++ b/src/modules/module-filter-chain/lv2_plugin.c @@ -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; diff --git a/src/modules/module-filter-chain/plugin.h b/src/modules/module-filter-chain/plugin.h index 5955740af..bf937ed91 100644 --- a/src/modules/module-filter-chain/plugin.h +++ b/src/modules/module-filter-chain/plugin.h @@ -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); diff --git a/src/modules/module-filter-chain/sofa_plugin.c b/src/modules/module-filter-chain/sofa_plugin.c index 996cebe4e..beb060072 100644 --- a/src/modules/module-filter-chain/sofa_plugin.c +++ b/src/modules/module-filter-chain/sofa_plugin.c @@ -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; }