mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-14 06:59:57 -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
5759a88f27
commit
270669be0d
7 changed files with 106 additions and 77 deletions
|
|
@ -2339,6 +2339,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;
|
||||
|
|
@ -2354,11 +2355,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 %d rate:%lu", d->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[] = {
|
||||
|
|
@ -274,7 +279,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;
|
||||
|
|
@ -287,6 +292,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);
|
||||
|
|
@ -503,7 +509,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 */
|
||||
|
|
@ -635,6 +641,7 @@ static const struct fc_descriptor bq_raw_desc = {
|
|||
|
||||
/** convolve */
|
||||
struct convolver_impl {
|
||||
struct plugin *plugin;
|
||||
unsigned long rate;
|
||||
float *port[64];
|
||||
|
||||
|
|
@ -781,7 +788,7 @@ static float *create_dirac(const char *filename, float gain, int delay, int offs
|
|||
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
|
||||
|
|
@ -858,7 +865,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;
|
||||
|
|
@ -982,9 +989,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++)
|
||||
|
|
@ -1008,9 +1017,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;
|
||||
|
||||
|
|
@ -1076,6 +1086,7 @@ static const struct fc_descriptor convolve_desc = {
|
|||
|
||||
/** delay */
|
||||
struct delay_impl {
|
||||
struct plugin *plugin;
|
||||
unsigned long rate;
|
||||
float *port[4];
|
||||
|
||||
|
|
@ -1093,7 +1104,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;
|
||||
|
|
@ -1133,6 +1144,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 = (uint32_t)(max_delay * impl->rate);
|
||||
pw_log_info("max-delay:%f seconds rate:%lu samples:%d", max_delay, impl->rate, impl->buffer_samples);
|
||||
|
|
@ -1311,7 +1323,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;
|
||||
|
|
@ -1556,7 +1568,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[] = {
|
||||
|
|
@ -1742,14 +1754,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;
|
||||
|
|
@ -54,7 +54,7 @@ static void fft_free(void *p)
|
|||
free(*((void **)p - 1));
|
||||
}
|
||||
|
||||
static inline void fft_cpx_clear(float *v, int size)
|
||||
static inline void fft_cpx_clear(struct dsp_ops *dsp, float *v, int size)
|
||||
{
|
||||
dsp_ops_clear(dsp, v, size * 2);
|
||||
}
|
||||
|
|
@ -80,16 +80,16 @@ static void convolver1_reset(struct convolver1 *conv)
|
|||
{
|
||||
int i;
|
||||
for (i = 0; i < conv->segCount; i++)
|
||||
fft_cpx_clear(conv->segments[i], conv->fftComplexSize);
|
||||
dsp_ops_clear(dsp, conv->overlap, conv->blockSize);
|
||||
dsp_ops_clear(dsp, conv->inputBuffer, conv->segSize);
|
||||
fft_cpx_clear(conv->pre_mult, conv->fftComplexSize);
|
||||
fft_cpx_clear(conv->conv, conv->fftComplexSize);
|
||||
fft_cpx_clear(conv->dsp, conv->segments[i], conv->fftComplexSize);
|
||||
dsp_ops_clear(conv->dsp, conv->overlap, conv->blockSize);
|
||||
dsp_ops_clear(conv->dsp, conv->inputBuffer, conv->segSize);
|
||||
fft_cpx_clear(conv->dsp, conv->pre_mult, conv->fftComplexSize);
|
||||
fft_cpx_clear(conv->dsp, conv->conv, conv->fftComplexSize);
|
||||
conv->inputBufferFill = 0;
|
||||
conv->current = 0;
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
@ -107,15 +107,16 @@ 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;
|
||||
|
||||
|
|
@ -133,11 +134,11 @@ static struct convolver1 *convolver1_new(int block, const float *ir, int irlen)
|
|||
conv->segments[i] = fft_cpx_alloc(conv->fftComplexSize);
|
||||
conv->segmentsIr[i] = fft_cpx_alloc(conv->fftComplexSize);
|
||||
|
||||
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_clear(dsp, conv->fft_buffer + copy, conv->segSize - copy);
|
||||
dsp_ops_clear(conv->dsp, conv->fft_buffer + copy, conv->segSize - copy);
|
||||
|
||||
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 = fft_cpx_alloc(conv->fftComplexSize);
|
||||
conv->conv = fft_cpx_alloc(conv->fftComplexSize);
|
||||
|
|
@ -166,9 +167,9 @@ static void convolver1_free(struct convolver1 *conv)
|
|||
fft_cpx_free(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)
|
||||
fft_free(conv->fft_buffer);
|
||||
free(conv->segments);
|
||||
|
|
@ -185,7 +186,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_clear(dsp, output, len);
|
||||
dsp_ops_clear(conv->dsp, output, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
|
|
@ -193,17 +194,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_clear(dsp, conv->inputBuffer + processing, conv->blockSize - processing);
|
||||
dsp_ops_clear(conv->dsp, conv->inputBuffer + processing, conv->blockSize - processing);
|
||||
|
||||
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);
|
||||
|
|
@ -211,7 +212,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],
|
||||
|
|
@ -219,30 +220,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);
|
||||
}
|
||||
|
|
@ -254,6 +255,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;
|
||||
|
|
@ -274,13 +276,13 @@ void convolver_reset(struct convolver *conv)
|
|||
convolver1_reset(conv->headConvolver);
|
||||
if (conv->tailConvolver0) {
|
||||
convolver1_reset(conv->tailConvolver0);
|
||||
dsp_ops_clear(dsp, conv->tailOutput0, conv->tailBlockSize);
|
||||
dsp_ops_clear(dsp, conv->tailPrecalculated0, conv->tailBlockSize);
|
||||
dsp_ops_clear(conv->dsp, conv->tailOutput0, conv->tailBlockSize);
|
||||
dsp_ops_clear(conv->dsp, conv->tailPrecalculated0, conv->tailBlockSize);
|
||||
}
|
||||
if (conv->tailConvolver) {
|
||||
convolver1_reset(conv->tailConvolver);
|
||||
dsp_ops_clear(dsp, conv->tailOutput, conv->tailBlockSize);
|
||||
dsp_ops_clear(dsp, conv->tailPrecalculated, conv->tailBlockSize);
|
||||
dsp_ops_clear(conv->dsp, conv->tailOutput, conv->tailBlockSize);
|
||||
dsp_ops_clear(conv->dsp, conv->tailPrecalculated, conv->tailBlockSize);
|
||||
}
|
||||
conv->tailInputFill = 0;
|
||||
conv->precalculatedPos = 0;
|
||||
|
|
@ -291,8 +293,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;
|
||||
|
||||
|
|
@ -310,22 +310,23 @@ 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 (irlen > conv->tailBlockSize) {
|
||||
int conv1IrLen = SPA_MIN(irlen - conv->tailBlockSize, conv->tailBlockSize);
|
||||
conv->tailConvolver0 = convolver1_new(conv->headBlockSize, ir + conv->tailBlockSize, conv1IrLen);
|
||||
conv->tailConvolver0 = convolver1_new(dsp_ops, conv->headBlockSize, ir + conv->tailBlockSize, conv1IrLen);
|
||||
conv->tailOutput0 = fft_alloc(conv->tailBlockSize);
|
||||
conv->tailPrecalculated0 = fft_alloc(conv->tailBlockSize);
|
||||
}
|
||||
|
||||
if (irlen > 2 * conv->tailBlockSize) {
|
||||
int tailIrLen = irlen - (2 * conv->tailBlockSize);
|
||||
conv->tailConvolver = convolver1_new(conv->tailBlockSize, ir + (2 * conv->tailBlockSize), tailIrLen);
|
||||
conv->tailConvolver = convolver1_new(dsp_ops, conv->tailBlockSize, ir + (2 * conv->tailBlockSize), tailIrLen);
|
||||
conv->tailOutput = fft_alloc(conv->tailBlockSize);
|
||||
conv->tailPrecalculated = fft_alloc(conv->tailBlockSize);
|
||||
}
|
||||
|
|
@ -366,16 +367,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;
|
||||
|
|
@ -58,6 +62,7 @@ static void * spatializer_instantiate(const struct fc_descriptor * Descriptor,
|
|||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
impl->plugin = (struct plugin *) plugin;
|
||||
|
||||
while (spa_json_get_string(&it[1], key, sizeof(key)) > 0) {
|
||||
if (spa_streq(key, "blocksize")) {
|
||||
|
|
@ -239,9 +244,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);
|
||||
|
|
@ -251,7 +256,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 {
|
||||
|
|
@ -296,7 +301,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);
|
||||
|
|
@ -413,19 +418,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