aboutsummaryrefslogtreecommitdiff
path: root/plugins/rtp/src/voice_processor.vala
diff options
context:
space:
mode:
authorMarvin W <git@larma.de>2025-01-26 12:02:49 +0100
committerMarvin W <git@larma.de>2025-02-22 21:06:26 +0100
commit1c365daa14e0e11bb4931b0c7891a781c5fc7084 (patch)
tree0e045a92a5466be5509b7d9312d53a811c246f5f /plugins/rtp/src/voice_processor.vala
parentf796286650e4ad862b147e484d528ca56cf5e0e6 (diff)
Voice processor: add support for webrtc-audio-processing 1.x and 2.x
Diffstat (limited to 'plugins/rtp/src/voice_processor.vala')
-rw-r--r--plugins/rtp/src/voice_processor.vala43
1 files changed, 39 insertions, 4 deletions
diff --git a/plugins/rtp/src/voice_processor.vala b/plugins/rtp/src/voice_processor.vala
index 66e95d72..a522a6ce 100644
--- a/plugins/rtp/src/voice_processor.vala
+++ b/plugins/rtp/src/voice_processor.vala
@@ -8,9 +8,11 @@ public class Dino.Plugins.Rtp.EchoProbe : Audio.Filter {
private static StaticPadTemplate sink_template = {"sink", PadDirection.SINK, PadPresence.ALWAYS, {null, "audio/x-raw,rate=48000,channels=1,layout=interleaved,format=S16LE"}};
private static StaticPadTemplate src_template = {"src", PadDirection.SRC, PadPresence.ALWAYS, {null, "audio/x-raw,rate=48000,channels=1,layout=interleaved,format=S16LE"}};
public Audio.Info audio_info { get; private set; }
- public signal void on_new_buffer(Buffer buffer);
+ public signal void on_new_buffer(owned Buffer buffer);
+ public signal void on_new_delay(int delay);
private uint period_samples;
private uint period_size;
+ public int delay { get; private set; }
private Base.Adapter adapter = new Base.Adapter();
static construct {
@@ -30,6 +32,25 @@ public class Dino.Plugins.Rtp.EchoProbe : Audio.Filter {
return true;
}
+ public override bool src_event(owned Event event) {
+ Query query = new Query.latency();
+ if (event.type == EventType.LATENCY && srcpad != null && srcpad.query(query)) {
+ ClockTime upstream_latency;
+ query.parse_latency(null, out upstream_latency, null);
+ int delay = this.delay;
+ if (upstream_latency != CLOCK_TIME_NONE) {
+ delay = (int) (upstream_latency / MSECOND);
+ } else {
+ delay = 0;
+ }
+ if (delay != this.delay) {
+ debug("Delay adjusted from %ms to %dms", this.delay, delay);
+ this.delay = delay;
+ on_new_delay(delay);
+ }
+ }
+ return base.src_event((owned) event);
+ }
public override FlowReturn transform_ip(Buffer buf) {
lock (adapter) {
@@ -52,6 +73,7 @@ public class Dino.Plugins.Rtp.VoiceProcessor : Audio.Filter {
private static StaticPadTemplate src_template = {"src", PadDirection.SRC, PadPresence.ALWAYS, {null, "audio/x-raw,rate=48000,channels=1,layout=interleaved,format=S16LE"}};
public Audio.Info audio_info { get; private set; }
private ulong process_outgoing_buffer_handler_id;
+ private ulong process_stream_delay_handler_id;
private uint adjust_delay_timeout_id;
private uint period_samples;
private uint period_size;
@@ -82,6 +104,7 @@ public class Dino.Plugins.Rtp.VoiceProcessor : Audio.Filter {
private static extern void analyze_reverse_stream(void* native, Audio.Info info, Buffer buffer);
private static extern void process_stream(void* native, Audio.Info info, Buffer buffer);
private static extern void adjust_stream_delay(void* native);
+ private static extern void set_stream_delay(void* native, int delay);
private static extern void notify_gain_level(void* native, int gain_level);
private static extern int get_suggested_gain_level(void* native);
private static extern bool get_stream_has_voice(void* native);
@@ -97,10 +120,13 @@ public class Dino.Plugins.Rtp.VoiceProcessor : Audio.Filter {
}
public override bool start() {
- native = init_native(150);
+ native = init_native(echo_probe.delay);
if (process_outgoing_buffer_handler_id == 0 && echo_probe != null) {
process_outgoing_buffer_handler_id = echo_probe.on_new_buffer.connect(process_outgoing_buffer);
}
+ if (process_stream_delay_handler_id == 0 && echo_probe != null) {
+ process_stream_delay_handler_id = echo_probe.on_new_delay.connect(process_stream_delay);
+ }
if (stream_volume == null && sinkpad.get_peer() != null && sinkpad.get_peer().get_parent_element() is Audio.StreamVolume) {
stream_volume = sinkpad.get_peer().get_parent_element() as Audio.StreamVolume;
}
@@ -117,16 +143,25 @@ public class Dino.Plugins.Rtp.VoiceProcessor : Audio.Filter {
}
}
- private void process_outgoing_buffer(Buffer buffer) {
+ private void process_outgoing_buffer(owned Buffer buffer) {
if (buffer.pts != uint64.MAX) {
last_reverse = buffer.pts;
}
- analyze_reverse_stream(native, echo_probe.audio_info, buffer);
+ if (native != null) {
+ buffer = (Buffer) buffer.make_writable();
+ analyze_reverse_stream(native, echo_probe.audio_info, buffer);
+ }
if (adjust_delay_timeout_id == 0 && echo_probe != null) {
adjust_delay_timeout_id = Timeout.add(1000, adjust_delay);
}
}
+ private void process_stream_delay(int stream_delay) {
+ if (native != null) {
+ set_stream_delay(native, stream_delay);
+ }
+ }
+
public override FlowReturn submit_input_buffer(bool is_discont, Buffer input) {
lock (adapter) {
if (is_discont) {