filter-graph: sync control updates with data thread.

don't read the control ports from the processing thread and check for
updates. Use the control_changed signal to check and update the
parameters of the biquad atimically.

See #5019
This commit is contained in:
Wim Taymans 2025-12-10 11:35:27 +01:00
parent be0e037809
commit e7ca02c4d8

View file

@ -21,6 +21,7 @@
#include <spa/utils/cleanup.h>
#include <spa/support/cpu.h>
#include <spa/support/log.h>
#include <spa/support/loop.h>
#include <spa/plugins/audioconvert/resample.h>
#include <spa/debug/log.h>
@ -38,6 +39,7 @@ struct plugin {
struct spa_fga_dsp *dsp;
struct spa_log *log;
struct spa_loop *data_loop;
};
struct builtin {
@ -542,7 +544,14 @@ static void bq_run(void *Instance, unsigned long samples)
struct biquad *bq = &impl->bq;
float *out = impl->port[0];
float *in = impl->port[1];
spa_fga_dsp_biquad_run(impl->dsp, bq, 1, 0, &out, (const float **)&in, 1, samples);
}
static int
do_bq_control_changed(struct spa_loop *loop, bool async, uint32_t seq, const void *data,
size_t size, void *user_data)
{
struct builtin *impl = user_data;
if (impl->type == BQ_NONE) {
float b0, b1, b2, a0, a1, a2;
b0 = impl->port[5][0];
@ -562,7 +571,13 @@ 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);
}
spa_fga_dsp_biquad_run(impl->dsp, bq, 1, 0, &out, (const float **)&in, 1, samples);
return 0;
}
static void bq_control_changed(void * Instance)
{
struct builtin *impl = Instance;
spa_loop_locked(impl->plugin->data_loop, do_bq_control_changed, 1, NULL, 0, impl);
}
/** bq_lowpass */
@ -574,6 +589,7 @@ static const struct spa_fga_descriptor bq_lowpass_desc = {
.instantiate = bq_instantiate,
.connect_port = builtin_connect_port,
.control_changed = bq_control_changed,
.activate = bq_activate,
.run = bq_run,
.cleanup = builtin_cleanup,
@ -588,6 +604,7 @@ static const struct spa_fga_descriptor bq_highpass_desc = {
.instantiate = bq_instantiate,
.connect_port = builtin_connect_port,
.control_changed = bq_control_changed,
.activate = bq_activate,
.run = bq_run,
.cleanup = builtin_cleanup,
@ -602,6 +619,7 @@ static const struct spa_fga_descriptor bq_bandpass_desc = {
.instantiate = bq_instantiate,
.connect_port = builtin_connect_port,
.control_changed = bq_control_changed,
.activate = bq_activate,
.run = bq_run,
.cleanup = builtin_cleanup,
@ -616,6 +634,7 @@ static const struct spa_fga_descriptor bq_lowshelf_desc = {
.instantiate = bq_instantiate,
.connect_port = builtin_connect_port,
.control_changed = bq_control_changed,
.activate = bq_activate,
.run = bq_run,
.cleanup = builtin_cleanup,
@ -630,6 +649,7 @@ static const struct spa_fga_descriptor bq_highshelf_desc = {
.instantiate = bq_instantiate,
.connect_port = builtin_connect_port,
.control_changed = bq_control_changed,
.activate = bq_activate,
.run = bq_run,
.cleanup = builtin_cleanup,
@ -644,6 +664,7 @@ static const struct spa_fga_descriptor bq_peaking_desc = {
.instantiate = bq_instantiate,
.connect_port = builtin_connect_port,
.control_changed = bq_control_changed,
.activate = bq_activate,
.run = bq_run,
.cleanup = builtin_cleanup,
@ -658,6 +679,7 @@ static const struct spa_fga_descriptor bq_notch_desc = {
.instantiate = bq_instantiate,
.connect_port = builtin_connect_port,
.control_changed = bq_control_changed,
.activate = bq_activate,
.run = bq_run,
.cleanup = builtin_cleanup,
@ -673,6 +695,7 @@ static const struct spa_fga_descriptor bq_allpass_desc = {
.instantiate = bq_instantiate,
.connect_port = builtin_connect_port,
.control_changed = bq_control_changed,
.activate = bq_activate,
.run = bq_run,
.cleanup = builtin_cleanup,
@ -687,6 +710,7 @@ static const struct spa_fga_descriptor bq_raw_desc = {
.instantiate = bq_instantiate,
.connect_port = builtin_connect_port,
.control_changed = bq_control_changed,
.activate = bq_activate,
.run = bq_run,
.cleanup = builtin_cleanup,
@ -3387,6 +3411,7 @@ impl_init(const struct spa_handle_factory *factory,
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);
impl->data_loop = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_DataLoop);
for (uint32_t i = 0; info && i < info->n_items; i++) {
const char *k = info->items[i].key;