mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-31 22:25:38 -04:00
filter-chain: add Level control input port for noisegate
This makes it possible to use another volume measurement algorithm to drive the noise gate, such as a VAD algorithm.
This commit is contained in:
parent
4b37f3db3d
commit
b3dddfed6a
2 changed files with 32 additions and 17 deletions
|
|
@ -2892,26 +2892,31 @@ static struct spa_fga_port noisegate_ports[] = {
|
||||||
.flags = SPA_FGA_PORT_OUTPUT | SPA_FGA_PORT_AUDIO,
|
.flags = SPA_FGA_PORT_OUTPUT | SPA_FGA_PORT_AUDIO,
|
||||||
},
|
},
|
||||||
{ .index = 2,
|
{ .index = 2,
|
||||||
.name = "Open Threshold",
|
.name = "Level",
|
||||||
.flags = SPA_FGA_PORT_INPUT | SPA_FGA_PORT_CONTROL,
|
.flags = SPA_FGA_PORT_INPUT | SPA_FGA_PORT_CONTROL,
|
||||||
.def = 0.004f, .min = 0.0f, .max = 1.0f
|
.def = NAN
|
||||||
},
|
},
|
||||||
{ .index = 3,
|
{ .index = 3,
|
||||||
.name = "Close Threshold",
|
.name = "Open Threshold",
|
||||||
.flags = SPA_FGA_PORT_INPUT | SPA_FGA_PORT_CONTROL,
|
.flags = SPA_FGA_PORT_INPUT | SPA_FGA_PORT_CONTROL,
|
||||||
.def = 0.003f, .min = 0.0f, .max = 1.0f
|
.def = 0.04f, .min = 0.0f, .max = 1.0f
|
||||||
},
|
},
|
||||||
{ .index = 4,
|
{ .index = 4,
|
||||||
|
.name = "Close Threshold",
|
||||||
|
.flags = SPA_FGA_PORT_INPUT | SPA_FGA_PORT_CONTROL,
|
||||||
|
.def = 0.03f, .min = 0.0f, .max = 1.0f
|
||||||
|
},
|
||||||
|
{ .index = 5,
|
||||||
.name = "Attack (s)",
|
.name = "Attack (s)",
|
||||||
.flags = SPA_FGA_PORT_INPUT | SPA_FGA_PORT_CONTROL,
|
.flags = SPA_FGA_PORT_INPUT | SPA_FGA_PORT_CONTROL,
|
||||||
.def = 0.005f, .min = 0.0f, .max = 1.0f
|
.def = 0.005f, .min = 0.0f, .max = 1.0f
|
||||||
},
|
},
|
||||||
{ .index = 5,
|
{ .index = 6,
|
||||||
.name = "Hold (s)",
|
.name = "Hold (s)",
|
||||||
.flags = SPA_FGA_PORT_INPUT | SPA_FGA_PORT_CONTROL,
|
.flags = SPA_FGA_PORT_INPUT | SPA_FGA_PORT_CONTROL,
|
||||||
.def = 0.050f, .min = 0.0f, .max = 1.0f
|
.def = 0.050f, .min = 0.0f, .max = 1.0f
|
||||||
},
|
},
|
||||||
{ .index = 6,
|
{ .index = 7,
|
||||||
.name = "Release (s)",
|
.name = "Release (s)",
|
||||||
.flags = SPA_FGA_PORT_INPUT | SPA_FGA_PORT_CONTROL,
|
.flags = SPA_FGA_PORT_INPUT | SPA_FGA_PORT_CONTROL,
|
||||||
.def = 0.010f, .min = 0.0f, .max = 1.0f
|
.def = 0.010f, .min = 0.0f, .max = 1.0f
|
||||||
|
|
@ -2923,9 +2928,10 @@ static void noisegate_run(void * Instance, unsigned long SampleCount)
|
||||||
struct builtin *impl = Instance;
|
struct builtin *impl = Instance;
|
||||||
float *in = impl->port[0];
|
float *in = impl->port[0];
|
||||||
float *out = impl->port[1];
|
float *out = impl->port[1];
|
||||||
|
float in_lev = impl->port[2][0];
|
||||||
unsigned long n;
|
unsigned long n;
|
||||||
float o_thres = impl->port[2][0];
|
float o_thres = impl->port[3][0];
|
||||||
float c_thres = impl->port[3][0];
|
float c_thres = impl->port[4][0];
|
||||||
float gate, hold, o_rate, c_rate, level;
|
float gate, hold, o_rate, c_rate, level;
|
||||||
int mode;
|
int mode;
|
||||||
|
|
||||||
|
|
@ -2937,20 +2943,25 @@ static void noisegate_run(void * Instance, unsigned long SampleCount)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
o_rate = 1.0f / (impl->port[4][0] * impl->rate);
|
o_rate = 1.0f / (impl->port[5][0] * impl->rate);
|
||||||
c_rate = 1.0f / (impl->port[6][0] * impl->rate);
|
c_rate = 1.0f / (impl->port[7][0] * impl->rate);
|
||||||
gate = impl->gate;
|
gate = impl->gate;
|
||||||
hold = impl->hold;
|
hold = impl->hold;
|
||||||
mode = impl->mode;
|
mode = impl->mode;
|
||||||
level = impl->last;
|
level = impl->last;
|
||||||
|
|
||||||
for (n = 0; n < SampleCount; n++) {
|
spa_log_trace_fp(impl->log, "%f %d %f", level, mode, gate);
|
||||||
float lev = fabsf(in[n]);
|
|
||||||
|
|
||||||
if (lev > level)
|
for (n = 0; n < SampleCount; n++) {
|
||||||
level = lev;
|
if (isnan(in_lev)) {
|
||||||
else
|
float lev = fabsf(in[n]);
|
||||||
level = lev * 0.05f + level * 0.95f;
|
if (lev > level)
|
||||||
|
level = lev;
|
||||||
|
else
|
||||||
|
level = lev * 0.05f + level * 0.95f;
|
||||||
|
} else {
|
||||||
|
level = in_lev;
|
||||||
|
}
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case 0:
|
case 0:
|
||||||
|
|
@ -2964,7 +2975,7 @@ static void noisegate_run(void * Instance, unsigned long SampleCount)
|
||||||
if (gate >= 1.0f) {
|
if (gate >= 1.0f) {
|
||||||
gate = 1.0f;
|
gate = 1.0f;
|
||||||
mode = 2;
|
mode = 2;
|
||||||
hold = impl->port[5][0] * impl->rate;
|
hold = impl->port[6][0] * impl->rate;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
|
|
|
||||||
|
|
@ -630,6 +630,10 @@ extern struct spa_handle_factory spa_filter_graph_factory;
|
||||||
* It has an "In" input port and an "Out" output data ports. Normally the input
|
* It has an "In" input port and an "Out" output data ports. Normally the input
|
||||||
* data is passed directly to the output.
|
* data is passed directly to the output.
|
||||||
*
|
*
|
||||||
|
* The "Level" control port can be used to control the measured volume of the "In"
|
||||||
|
* port. When not connected, a simple volume algorithm on the "In" port will be
|
||||||
|
* used.
|
||||||
|
*
|
||||||
* If the volume drops below "Close threshold", the noisegate will ramp down the
|
* If the volume drops below "Close threshold", the noisegate will ramp down the
|
||||||
* volume to zero for a duration of "Release (s)" seconds. When the volume is above
|
* volume to zero for a duration of "Release (s)" seconds. When the volume is above
|
||||||
* "Open threshold", the noisegate will ramp up the volume to 1 for a duration
|
* "Open threshold", the noisegate will ramp up the volume to 1 for a duration
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue