From 17e72f00831a36da387ceafe7f3076ffa8f66aba Mon Sep 17 00:00:00 2001
From: Clemence Him <clemence.him@belledonne-communications.com>
Date: Fri, 22 Sep 2023 14:28:02 +0200
Subject: [PATCH] Base64 functions refactoring

---
 aec.c | 781 +++++++++++++++++++++++++++++-----------------------------
 1 file changed, 394 insertions(+), 387 deletions(-)

diff --git a/aec.c b/aec.c
index 271f370..995f655 100644
--- a/aec.c
+++ b/aec.c
@@ -24,19 +24,18 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 #include "mediastreamer2/msfilter.h"
 #include "mediastreamer2/msticker.h"
 #ifdef BUILD_AEC
-#include "echo_cancellation.h"
 #include "aec_splitting_filter.h"
+#include "echo_cancellation.h"
 #endif
 #ifdef BUILD_AECM
 #include "echo_control_mobile.h"
 #endif
-#include "ortp/b64.h"
 
 #ifdef _WIN32
 #include <malloc.h> /* for alloca */
 #endif
 
-//#define EC_DUMP 1
+// #define EC_DUMP 1
 #ifdef ANDROID
 #define EC_DUMP_PREFIX "/sdcard"
 #else
@@ -48,466 +47,485 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 static const float smooth_factor = 0.05f;
 static const int framesize = 80;
 
-
 typedef enum _WebRTCAECType {
-	WebRTCAECTypeNormal,
-	WebRTCAECTypeMobile
+  WebRTCAECTypeNormal,
+  WebRTCAECTypeMobile
 } WebRTCAECType;
 
 typedef struct WebRTCAECState {
-	void *aecInst;
-	MSBufferizer delayed_ref;
-	MSFlowControlledBufferizer ref;
-	MSBufferizer echo;
-	int framesize;
-	int samplerate;
-	int delay_ms;
-	int nominal_ref_samples;
-	char *state_str;
+  void *aecInst;
+  MSBufferizer delayed_ref;
+  MSFlowControlledBufferizer ref;
+  MSBufferizer echo;
+  int framesize;
+  int samplerate;
+  int delay_ms;
+  int nominal_ref_samples;
+  char *state_str;
 #ifdef EC_DUMP
-	FILE *echofile;
-	FILE *reffile;
-	FILE *cleanfile;
+  FILE *echofile;
+  FILE *reffile;
+  FILE *cleanfile;
 #endif
-	bool_t echostarted;
-	bool_t bypass_mode;
-	bool_t using_zeroes;
-	WebRTCAECType aec_type;
+  bool_t echostarted;
+  bool_t bypass_mode;
+  bool_t using_zeroes;
+  WebRTCAECType aec_type;
 #ifdef BUILD_AEC
-	MSWebRtcAecSplittingFilter *splitting_filter;
+  MSWebRtcAecSplittingFilter *splitting_filter;
 #endif
 } WebRTCAECState;
 
 static void webrtc_aecgeneric_init(MSFilter *f, WebRTCAECType aec_type) {
-	WebRTCAECState *s = (WebRTCAECState *) ms_new0(WebRTCAECState, 1);
-
-	s->samplerate = 8000;
-	ms_bufferizer_init(&s->delayed_ref);
-	ms_bufferizer_init(&s->echo);
-	ms_flow_controlled_bufferizer_init(&s->ref, f, s->samplerate, 1);
-	s->delay_ms = 0;
-	s->aecInst = NULL;
-	s->framesize = framesize;
-	s->state_str = NULL;
-	s->using_zeroes = FALSE;
-	s->echostarted = FALSE;
-	s->bypass_mode = FALSE;
-	s->aec_type = aec_type;
+  WebRTCAECState *s = (WebRTCAECState *)ms_new0(WebRTCAECState, 1);
+
+  s->samplerate = 8000;
+  ms_bufferizer_init(&s->delayed_ref);
+  ms_bufferizer_init(&s->echo);
+  ms_flow_controlled_bufferizer_init(&s->ref, f, s->samplerate, 1);
+  s->delay_ms = 0;
+  s->aecInst = NULL;
+  s->framesize = framesize;
+  s->state_str = NULL;
+  s->using_zeroes = FALSE;
+  s->echostarted = FALSE;
+  s->bypass_mode = FALSE;
+  s->aec_type = aec_type;
 
 #ifdef EC_DUMP
-	{
-		char *fname = ms_strdup_printf("%s/mswebrtcaec-%p-echo.raw", EC_DUMP_PREFIX, f);
-		s->echofile = fopen(fname, "w");
-		ms_free(fname);
-		fname = ms_strdup_printf("%s/mswebrtcaec-%p-ref.raw", EC_DUMP_PREFIX, f);
-		s->reffile = fopen(fname, "w");
-		ms_free(fname);
-		fname = ms_strdup_printf("%s/mswebrtcaec-%p-clean.raw", EC_DUMP_PREFIX, f);
-		s->cleanfile = fopen(fname, "w");
-		ms_free(fname);
-	}
+  {
+    char *fname =
+        ms_strdup_printf("%s/mswebrtcaec-%p-echo.raw", EC_DUMP_PREFIX, f);
+    s->echofile = fopen(fname, "w");
+    ms_free(fname);
+    fname = ms_strdup_printf("%s/mswebrtcaec-%p-ref.raw", EC_DUMP_PREFIX, f);
+    s->reffile = fopen(fname, "w");
+    ms_free(fname);
+    fname = ms_strdup_printf("%s/mswebrtcaec-%p-clean.raw", EC_DUMP_PREFIX, f);
+    s->cleanfile = fopen(fname, "w");
+    ms_free(fname);
+  }
 #endif
 
-	f->data = s;
+  f->data = s;
 }
 
 #ifdef BUILD_AEC
 static void webrtc_aec_init(MSFilter *f) {
-	webrtc_aecgeneric_init(f, WebRTCAECTypeNormal);
+  webrtc_aecgeneric_init(f, WebRTCAECTypeNormal);
 }
 #endif
 
 #ifdef BUILD_AECM
 static void webrtc_aecm_init(MSFilter *f) {
-	webrtc_aecgeneric_init(f, WebRTCAECTypeMobile);
+  webrtc_aecgeneric_init(f, WebRTCAECTypeMobile);
 }
 #endif
 
 static void webrtc_aec_uninit(MSFilter *f) {
-	WebRTCAECState *s = (WebRTCAECState *) f->data;
-	if (s->state_str) ms_free(s->state_str);
-	ms_bufferizer_uninit(&s->delayed_ref);
+  WebRTCAECState *s = (WebRTCAECState *)f->data;
+  if (s->state_str)
+    ms_free(s->state_str);
+  ms_bufferizer_uninit(&s->delayed_ref);
 #ifdef EC_DUMP
-	if (s->echofile)
-		fclose(s->echofile);
-	if (s->reffile)
-		fclose(s->reffile);
+  if (s->echofile)
+    fclose(s->echofile);
+  if (s->reffile)
+    fclose(s->reffile);
 #endif
-	ms_free(s);
+  ms_free(s);
 }
 
 static void configure_flow_controlled_bufferizer(WebRTCAECState *s) {
-	ms_flow_controlled_bufferizer_set_samplerate(&s->ref, s->samplerate);
-	ms_flow_controlled_bufferizer_set_max_size_ms(&s->ref, s->delay_ms);
-	ms_flow_controlled_bufferizer_set_granularity_ms(&s->ref, (s->framesize * 1000) / s->samplerate);
+  ms_flow_controlled_bufferizer_set_samplerate(&s->ref, s->samplerate);
+  ms_flow_controlled_bufferizer_set_max_size_ms(&s->ref, s->delay_ms);
+  ms_flow_controlled_bufferizer_set_granularity_ms(
+      &s->ref, (s->framesize * 1000) / s->samplerate);
 }
 
 static void webrtc_aec_preprocess(MSFilter *f) {
-	WebRTCAECState *s = (WebRTCAECState *) f->data;
+  WebRTCAECState *s = (WebRTCAECState *)f->data;
 #ifdef BUILD_AEC
-	AecConfig aec_config;
+  AecConfig aec_config;
 #endif
 #ifdef BUILD_AECM
-	AecmConfig aecm_config;
-	int error_code;
+  AecmConfig aecm_config;
+  int error_code;
 #endif
-	int delay_samples = 0;
-	mblk_t *m;
+  int delay_samples = 0;
+  mblk_t *m;
 
-	s->echostarted = FALSE;
-	delay_samples = s->delay_ms * s->samplerate / 1000;
-	s->framesize=(framesize*s->samplerate)/8000;
-	ms_message("Initializing WebRTC echo canceler with framesize=%i, delay_ms=%i, delay_samples=%i", s->framesize, s->delay_ms, delay_samples);
-	configure_flow_controlled_bufferizer(s);
+  s->echostarted = FALSE;
+  delay_samples = s->delay_ms * s->samplerate / 1000;
+  s->framesize = (framesize * s->samplerate) / 8000;
+  ms_message("Initializing WebRTC echo canceler with framesize=%i, "
+             "delay_ms=%i, delay_samples=%i",
+             s->framesize, s->delay_ms, delay_samples);
+  configure_flow_controlled_bufferizer(s);
 
 #ifdef BUILD_AEC
-	if (s->aec_type == WebRTCAECTypeNormal) {
-		if ((s->aecInst = WebRtcAec_Create()) == NULL) {
-			s->bypass_mode = TRUE;
-			ms_error("WebRtcAec_Create(): error, entering bypass mode");
-			return;
-		}
-		if ((WebRtcAec_Init(s->aecInst, MIN(48000, s->samplerate), s->samplerate)) < 0) {
-			ms_error("WebRtcAec_Init(): WebRTC echo canceller does not support %d samplerate", s->samplerate);
-			s->bypass_mode = TRUE;
-			ms_error("Entering bypass mode");
-			return;
-		}
-		aec_config.nlpMode = kAecNlpAggressive;
-		aec_config.skewMode = kAecFalse;
-		aec_config.metricsMode = kAecFalse;
-		aec_config.delay_logging = kAecFalse;
-		if (WebRtcAec_set_config(s->aecInst, aec_config) != 0) {
-			ms_error("WebRtcAec_set_config(): failed.");
-		}
-	}
+  if (s->aec_type == WebRTCAECTypeNormal) {
+    if ((s->aecInst = WebRtcAec_Create()) == NULL) {
+      s->bypass_mode = TRUE;
+      ms_error("WebRtcAec_Create(): error, entering bypass mode");
+      return;
+    }
+    if ((WebRtcAec_Init(s->aecInst, MIN(48000, s->samplerate), s->samplerate)) <
+        0) {
+      ms_error("WebRtcAec_Init(): WebRTC echo canceller does not support %d "
+               "samplerate",
+               s->samplerate);
+      s->bypass_mode = TRUE;
+      ms_error("Entering bypass mode");
+      return;
+    }
+    aec_config.nlpMode = kAecNlpAggressive;
+    aec_config.skewMode = kAecFalse;
+    aec_config.metricsMode = kAecFalse;
+    aec_config.delay_logging = kAecFalse;
+    if (WebRtcAec_set_config(s->aecInst, aec_config) != 0) {
+      ms_error("WebRtcAec_set_config(): failed.");
+    }
+  }
 #endif
 #ifdef BUILD_AECM
-	if (s->aec_type == WebRTCAECTypeMobile) {
-		if ((s->aecInst = WebRtcAecm_Create()) == NULL) {
-			s->bypass_mode = TRUE;
-			ms_error("WebRtcAecm_Create(): error, entering bypass mode");
-			return;
-		}
-		if ((error_code = WebRtcAecm_Init(s->aecInst, s->samplerate)) < 0) {
-			if (error_code == AECM_BAD_PARAMETER_ERROR) {
-				ms_error("WebRtcAecm_Init(): WebRTC echo canceller does not support %d samplerate", s->samplerate);
-			}
-			s->bypass_mode = TRUE;
-			ms_error("Entering bypass mode");
-			return;
-		}
-		aecm_config.cngMode = TRUE;
-		aecm_config.echoMode = 3;
-		if (WebRtcAecm_set_config(s->aecInst, aecm_config)!=0){
-			ms_error("WebRtcAecm_set_config(): failed.");
-		}
-	}
+  if (s->aec_type == WebRTCAECTypeMobile) {
+    if ((s->aecInst = WebRtcAecm_Create()) == NULL) {
+      s->bypass_mode = TRUE;
+      ms_error("WebRtcAecm_Create(): error, entering bypass mode");
+      return;
+    }
+    if ((error_code = WebRtcAecm_Init(s->aecInst, s->samplerate)) < 0) {
+      if (error_code == AECM_BAD_PARAMETER_ERROR) {
+        ms_error("WebRtcAecm_Init(): WebRTC echo canceller does not support %d "
+                 "samplerate",
+                 s->samplerate);
+      }
+      s->bypass_mode = TRUE;
+      ms_error("Entering bypass mode");
+      return;
+    }
+    aecm_config.cngMode = TRUE;
+    aecm_config.echoMode = 3;
+    if (WebRtcAecm_set_config(s->aecInst, aecm_config) != 0) {
+      ms_error("WebRtcAecm_set_config(): failed.");
+    }
+  }
 #endif
 
-	/* fill with zeroes for the time of the delay*/
-	m = allocb(delay_samples * 2, 0);
-	m->b_wptr += delay_samples * 2;
-	ms_bufferizer_put(&s->delayed_ref, m);
-	s->nominal_ref_samples = delay_samples;
+  /* fill with zeroes for the time of the delay*/
+  m = allocb(delay_samples * 2, 0);
+  m->b_wptr += delay_samples * 2;
+  ms_bufferizer_put(&s->delayed_ref, m);
+  s->nominal_ref_samples = delay_samples;
 }
 
 /*	inputs[0]= reference signal from far end (sent to soundcard)
  *	inputs[1]= near speech & echo signal (read from soundcard)
  *	outputs[0]=  is a copy of inputs[0] to be sent to soundcard
  *	outputs[1]=  near end speech, echo removed - towards far end
-*/
+ */
 static void webrtc_aec_process(MSFilter *f) {
-	WebRTCAECState *s = (WebRTCAECState *) f->data;
-	int nbytes = s->framesize * sizeof(int16_t);
-	mblk_t *refm;
-	int16_t *ref, *echo;
-	int nbands = 1;
-	int bandsize = s->framesize;
-
-	if (s->bypass_mode) {
-		while ((refm = ms_queue_get(f->inputs[0])) != NULL) {
-			ms_queue_put(f->outputs[0], refm);
-		}
-		while ((refm = ms_queue_get(f->inputs[1])) != NULL) {
-			ms_queue_put(f->outputs[1], refm);
-		}
-		return;
-	}
-
-	if (f->inputs[0] != NULL) {
-		if (s->echostarted) {
-			while ((refm = ms_queue_get(f->inputs[0])) != NULL) {
-				mblk_t *cp=dupmsg(refm);
-				ms_bufferizer_put(&s->delayed_ref,cp);
-				ms_flow_controlled_bufferizer_put(&s->ref,refm);
-			}
-		} else {
-			ms_warning("Getting reference signal but no echo to synchronize on.");
-			ms_queue_flush(f->inputs[0]);
-		}
-	}
-
-	ms_bufferizer_put_from_queue(&s->echo, f->inputs[1]);
-
-	ref = (int16_t *) alloca(nbytes);
-	echo = (int16_t *) alloca(nbytes);
+  WebRTCAECState *s = (WebRTCAECState *)f->data;
+  int nbytes = s->framesize * sizeof(int16_t);
+  mblk_t *refm;
+  int16_t *ref, *echo;
+  int nbands = 1;
+  int bandsize = s->framesize;
+
+  if (s->bypass_mode) {
+    while ((refm = ms_queue_get(f->inputs[0])) != NULL) {
+      ms_queue_put(f->outputs[0], refm);
+    }
+    while ((refm = ms_queue_get(f->inputs[1])) != NULL) {
+      ms_queue_put(f->outputs[1], refm);
+    }
+    return;
+  }
+
+  if (f->inputs[0] != NULL) {
+    if (s->echostarted) {
+      while ((refm = ms_queue_get(f->inputs[0])) != NULL) {
+        mblk_t *cp = dupmsg(refm);
+        ms_bufferizer_put(&s->delayed_ref, cp);
+        ms_flow_controlled_bufferizer_put(&s->ref, refm);
+      }
+    } else {
+      ms_warning("Getting reference signal but no echo to synchronize on.");
+      ms_queue_flush(f->inputs[0]);
+    }
+  }
+
+  ms_bufferizer_put_from_queue(&s->echo, f->inputs[1]);
+
+  ref = (int16_t *)alloca(nbytes);
+  echo = (int16_t *)alloca(nbytes);
 #ifdef BUILD_AEC
-	if (s->aec_type == WebRTCAECTypeNormal) {
-		if (s->samplerate > 16000) {
-			nbands = s->samplerate / 16000;
-			bandsize = 160;
-		}
-		if (!s->splitting_filter) {
-			s->splitting_filter = mswebrtc_aec_splitting_filter_create(nbands, bandsize);
-		}
-	}
+  if (s->aec_type == WebRTCAECTypeNormal) {
+    if (s->samplerate > 16000) {
+      nbands = s->samplerate / 16000;
+      bandsize = 160;
+    }
+    if (!s->splitting_filter) {
+      s->splitting_filter =
+          mswebrtc_aec_splitting_filter_create(nbands, bandsize);
+    }
+  }
 #endif
-	while (ms_bufferizer_read(&s->echo, (uint8_t *)echo, (size_t)nbytes) >= (size_t)nbytes) {
-		mblk_t *oecho = allocb(nbytes, 0);
-		int avail;
-		int avail_samples;
-
-		if (!s->echostarted) s->echostarted = TRUE;
-		if ((avail = ms_bufferizer_get_avail(&s->delayed_ref)) < ((s->nominal_ref_samples * 2) + nbytes)) {
-			/*we don't have enough to read in a reference signal buffer, inject silence instead*/
-			refm = allocb(nbytes, 0);
-			memset(refm->b_wptr, 0, nbytes);
-			refm->b_wptr += nbytes;
-			ms_bufferizer_put(&s->delayed_ref, refm);
-			/*
-			 * However, we don't inject this silence buffer to the sound card, in order to break the following bad loop:
-			 * - the sound playback filter detects it has too many pending samples, then triggers an event to request samples to be dropped upstream.
-			 * - the upstream MSFlowControl filter is requested to drop samples, which it starts to do.
-			 * - necessarily shortly after the AEC goes into a situation where it has not enough reference samples while processing an audio buffer from mic.
-			 * - if the AEC injects a silence buffer as output, then it will RECREATE a situation where the sound playback filter has too many pending samples.
-			 * That's why we should not do this.
-			 * By not doing this, we will create a discrepancy between what we really injected to the soundcard, and what we told to the 
-			 * echo canceller about the samples we injected. This shifts the echo. The echo canceller will re-converge quickly to take into
-			 * account the situation.
-			 * 
-			*/
-			//ms_queue_put(f->outputs[0], dupmsg(refm));
-			if (!s->using_zeroes) {
-				ms_warning("Not enough ref samples, using zeroes");
-				s->using_zeroes = TRUE;
-			}
-		} else {
-			if (s->using_zeroes) {
-				ms_message("Samples are back.");
-				s->using_zeroes = FALSE;
-			}
-			/* read from our no-delay buffer and output */
-			refm = allocb(nbytes, 0);
-			if (ms_flow_controlled_bufferizer_read(&s->ref, refm->b_wptr, nbytes) == 0) {
-				ms_fatal("Should never happen");
-			}
-			refm->b_wptr += nbytes;
-			ms_queue_put(f->outputs[0], refm);
-		}
-
-		/*now read a valid buffer of delayed ref samples*/
-		if (ms_bufferizer_read(&s->delayed_ref, (uint8_t *)ref, nbytes) == 0) {
-			ms_fatal("Should never happen");
-		}
-		avail -= nbytes;
-		avail_samples = avail / 2;
+  while (ms_bufferizer_read(&s->echo, (uint8_t *)echo, (size_t)nbytes) >=
+         (size_t)nbytes) {
+    mblk_t *oecho = allocb(nbytes, 0);
+    int avail;
+    int avail_samples;
+
+    if (!s->echostarted)
+      s->echostarted = TRUE;
+    if ((avail = ms_bufferizer_get_avail(&s->delayed_ref)) <
+        ((s->nominal_ref_samples * 2) + nbytes)) {
+      /*we don't have enough to read in a reference signal buffer, inject
+       * silence instead*/
+      refm = allocb(nbytes, 0);
+      memset(refm->b_wptr, 0, nbytes);
+      refm->b_wptr += nbytes;
+      ms_bufferizer_put(&s->delayed_ref, refm);
+      /*
+       * However, we don't inject this silence buffer to the sound card, in
+       * order to break the following bad loop:
+       * - the sound playback filter detects it has too many pending samples,
+       * then triggers an event to request samples to be dropped upstream.
+       * - the upstream MSFlowControl filter is requested to drop samples, which
+       * it starts to do.
+       * - necessarily shortly after the AEC goes into a situation where it has
+       * not enough reference samples while processing an audio buffer from mic.
+       * - if the AEC injects a silence buffer as output, then it will RECREATE
+       * a situation where the sound playback filter has too many pending
+       * samples. That's why we should not do this. By not doing this, we will
+       * create a discrepancy between what we really injected to the soundcard,
+       * and what we told to the echo canceller about the samples we injected.
+       * This shifts the echo. The echo canceller will re-converge quickly to
+       * take into account the situation.
+       *
+       */
+      // ms_queue_put(f->outputs[0], dupmsg(refm));
+      if (!s->using_zeroes) {
+        ms_warning("Not enough ref samples, using zeroes");
+        s->using_zeroes = TRUE;
+      }
+    } else {
+      if (s->using_zeroes) {
+        ms_message("Samples are back.");
+        s->using_zeroes = FALSE;
+      }
+      /* read from our no-delay buffer and output */
+      refm = allocb(nbytes, 0);
+      if (ms_flow_controlled_bufferizer_read(&s->ref, refm->b_wptr, nbytes) ==
+          0) {
+        ms_fatal("Should never happen");
+      }
+      refm->b_wptr += nbytes;
+      ms_queue_put(f->outputs[0], refm);
+    }
+
+    /*now read a valid buffer of delayed ref samples*/
+    if (ms_bufferizer_read(&s->delayed_ref, (uint8_t *)ref, nbytes) == 0) {
+      ms_fatal("Should never happen");
+    }
+    avail -= nbytes;
+    avail_samples = avail / 2;
 
 #ifdef EC_DUMP
-		if (s->reffile)
-			fwrite(ref, nbytes, 1, s->reffile);
-		if (s->echofile)
-			fwrite(echo, nbytes, 1, s->echofile);
+    if (s->reffile)
+      fwrite(ref, nbytes, 1, s->reffile);
+    if (s->echofile)
+      fwrite(echo, nbytes, 1, s->echofile);
 #endif
 #ifdef BUILD_AEC
-		if (s->aec_type == WebRTCAECTypeNormal) {
-			mswebrtc_aec_splitting_filter_analysis(s->splitting_filter, ref, echo);
-			if (WebRtcAec_BufferFarend(s->aecInst,
-					mswebrtc_aec_splitting_filter_get_ref(s->splitting_filter),
-					(size_t)mswebrtc_aec_splitting_filter_get_bandsize(s->splitting_filter)) != 0)
-				ms_error("WebRtcAec_BufferFarend() failed.");
-			if (WebRtcAec_Process(s->aecInst,
-					mswebrtc_aec_splitting_filter_get_echo_bands(s->splitting_filter),
-					mswebrtc_aec_splitting_filter_get_number_of_bands(s->splitting_filter),
-					mswebrtc_aec_splitting_filter_get_output_bands(s->splitting_filter),
-					(size_t)mswebrtc_aec_splitting_filter_get_bandsize(s->splitting_filter), 0, 0) != 0)
-				ms_error("WebRtcAec_Process() failed.");
-			mswebrtc_aec_splitting_filter_synthesis(s->splitting_filter, (int16_t *)oecho->b_wptr);
-		}
+    if (s->aec_type == WebRTCAECTypeNormal) {
+      mswebrtc_aec_splitting_filter_analysis(s->splitting_filter, ref, echo);
+      if (WebRtcAec_BufferFarend(
+              s->aecInst,
+              mswebrtc_aec_splitting_filter_get_ref(s->splitting_filter),
+              (size_t)mswebrtc_aec_splitting_filter_get_bandsize(
+                  s->splitting_filter)) != 0)
+        ms_error("WebRtcAec_BufferFarend() failed.");
+      if (WebRtcAec_Process(
+              s->aecInst,
+              mswebrtc_aec_splitting_filter_get_echo_bands(s->splitting_filter),
+              mswebrtc_aec_splitting_filter_get_number_of_bands(
+                  s->splitting_filter),
+              mswebrtc_aec_splitting_filter_get_output_bands(
+                  s->splitting_filter),
+              (size_t)mswebrtc_aec_splitting_filter_get_bandsize(
+                  s->splitting_filter),
+              0, 0) != 0)
+        ms_error("WebRtcAec_Process() failed.");
+      mswebrtc_aec_splitting_filter_synthesis(s->splitting_filter,
+                                              (int16_t *)oecho->b_wptr);
+    }
 #endif
 #ifdef BUILD_AECM
-		if (s->aec_type == WebRTCAECTypeMobile) {
-			if (WebRtcAecm_BufferFarend(s->aecInst, ref, (size_t)s->framesize) != 0)
-				ms_error("WebRtcAecm_BufferFarend() failed.");
-			if (WebRtcAecm_Process(s->aecInst, echo, NULL, (int16_t *)oecho->b_wptr, (size_t)s->framesize, 0) != 0)
-				ms_error("WebRtcAecm_Process() failed.");
-		}
+    if (s->aec_type == WebRTCAECTypeMobile) {
+      if (WebRtcAecm_BufferFarend(s->aecInst, ref, (size_t)s->framesize) != 0)
+        ms_error("WebRtcAecm_BufferFarend() failed.");
+      if (WebRtcAecm_Process(s->aecInst, echo, NULL, (int16_t *)oecho->b_wptr,
+                             (size_t)s->framesize, 0) != 0)
+        ms_error("WebRtcAecm_Process() failed.");
+    }
 #endif
 #ifdef EC_DUMP
-		if (s->cleanfile)
-			fwrite(oecho->b_wptr, nbytes, 1, s->cleanfile);
+    if (s->cleanfile)
+      fwrite(oecho->b_wptr, nbytes, 1, s->cleanfile);
 #endif
-		oecho->b_wptr += nbytes;
-		ms_queue_put(f->outputs[1], oecho);
-	}
+    oecho->b_wptr += nbytes;
+    ms_queue_put(f->outputs[1], oecho);
+  }
 }
 
 static void webrtc_aec_postprocess(MSFilter *f) {
-	WebRTCAECState *s = (WebRTCAECState *) f->data;
+  WebRTCAECState *s = (WebRTCAECState *)f->data;
 
-	ms_bufferizer_flush(&s->delayed_ref);
-	ms_bufferizer_flush(&s->echo);
-	ms_flow_controlled_bufferizer_flush(&s->ref);
+  ms_bufferizer_flush(&s->delayed_ref);
+  ms_bufferizer_flush(&s->echo);
+  ms_flow_controlled_bufferizer_flush(&s->ref);
 #ifdef BUILD_AEC
-	if (s->splitting_filter) {
-		mswebrtc_aec_splitting_filter_destroy(s->splitting_filter);
-		s->splitting_filter = NULL;
-	}
+  if (s->splitting_filter) {
+    mswebrtc_aec_splitting_filter_destroy(s->splitting_filter);
+    s->splitting_filter = NULL;
+  }
 #endif
-	if (s->aecInst != NULL) {
+  if (s->aecInst != NULL) {
 #ifdef BUILD_AEC
-		if (s->aec_type == WebRTCAECTypeNormal) {
-			WebRtcAec_Free(s->aecInst);
-		}
+    if (s->aec_type == WebRTCAECTypeNormal) {
+      WebRtcAec_Free(s->aecInst);
+    }
 #endif
 #ifdef BUILD_AECM
-		if (s->aec_type == WebRTCAECTypeMobile) {
-			WebRtcAecm_Free(s->aecInst);
-		}
+    if (s->aec_type == WebRTCAECTypeMobile) {
+      WebRtcAecm_Free(s->aecInst);
+    }
 #endif
-		s->aecInst = NULL;
-	}
+    s->aecInst = NULL;
+  }
 }
 
 static int webrtc_aec_set_sr(MSFilter *f, void *arg) {
-	WebRTCAECState *s = (WebRTCAECState *) f->data;
-	int requested_sr = *(int *) arg;
-	int sr = requested_sr;
-
-	if ((s->aec_type == WebRTCAECTypeNormal) && (requested_sr >= 48000)) {
-		sr = 48000;
-	} else if ((s->aec_type == WebRTCAECTypeNormal) && (requested_sr >= 32000)) {
-		sr = 32000;
-	} else if (requested_sr >= 16000) {
-		sr = 16000;
-	} else {
-		sr = 8000;
-	}
-	if (sr != requested_sr)
-		ms_message("Webrtc %s does not support sampling rate %i, using %i instead", ((s->aec_type == WebRTCAECTypeNormal)?"aec":"aecm"),requested_sr, sr);
-
-	s->samplerate = sr;
-	configure_flow_controlled_bufferizer(s);
-	return 0;
+  WebRTCAECState *s = (WebRTCAECState *)f->data;
+  int requested_sr = *(int *)arg;
+  int sr = requested_sr;
+
+  if ((s->aec_type == WebRTCAECTypeNormal) && (requested_sr >= 48000)) {
+    sr = 48000;
+  } else if ((s->aec_type == WebRTCAECTypeNormal) && (requested_sr >= 32000)) {
+    sr = 32000;
+  } else if (requested_sr >= 16000) {
+    sr = 16000;
+  } else {
+    sr = 8000;
+  }
+  if (sr != requested_sr)
+    ms_message("Webrtc %s does not support sampling rate %i, using %i instead",
+               ((s->aec_type == WebRTCAECTypeNormal) ? "aec" : "aecm"),
+               requested_sr, sr);
+
+  s->samplerate = sr;
+  configure_flow_controlled_bufferizer(s);
+  return 0;
 }
 
 static int webrtc_aec_get_sr(MSFilter *f, void *arg) {
-	WebRTCAECState *s = (WebRTCAECState *) f->data;
-	*(int *) arg=s->samplerate;
-	return 0;
+  WebRTCAECState *s = (WebRTCAECState *)f->data;
+  *(int *)arg = s->samplerate;
+  return 0;
 }
 
 static int webrtc_aec_set_framesize(MSFilter *f, void *arg) {
-	/* Do nothing because the WebRTC echo canceller only accept specific values: 80 and 160. We use 80 at 8khz, and 160 at 16khz */
-	return 0;
+  /* Do nothing because the WebRTC echo canceller only accept specific values:
+   * 80 and 160. We use 80 at 8khz, and 160 at 16khz */
+  return 0;
 }
 
 static int webrtc_aec_set_delay(MSFilter *f, void *arg) {
-	WebRTCAECState *s = (WebRTCAECState *) f->data;
-	s->delay_ms = *(int *) arg;
-	configure_flow_controlled_bufferizer(s);
-	return 0;
+  WebRTCAECState *s = (WebRTCAECState *)f->data;
+  s->delay_ms = *(int *)arg;
+  configure_flow_controlled_bufferizer(s);
+  return 0;
 }
 
 static int webrtc_aec_set_tail_length(MSFilter *f, void *arg) {
-	/* Do nothing because this is not needed by the WebRTC echo canceller. */
-	return 0;
+  /* Do nothing because this is not needed by the WebRTC echo canceller. */
+  return 0;
 }
 static int webrtc_aec_set_bypass_mode(MSFilter *f, void *arg) {
-	WebRTCAECState *s = (WebRTCAECState *) f->data;
-	s->bypass_mode = *(bool_t *) arg;
-	ms_message("set EC bypass mode to [%i]", s->bypass_mode);
-	return 0;
+  WebRTCAECState *s = (WebRTCAECState *)f->data;
+  s->bypass_mode = *(bool_t *)arg;
+  ms_message("set EC bypass mode to [%i]", s->bypass_mode);
+  return 0;
 }
 static int webrtc_aec_get_bypass_mode(MSFilter *f, void *arg) {
-	WebRTCAECState *s = (WebRTCAECState *) f->data;
-	*(bool_t *) arg = s->bypass_mode;
-	return 0;
+  WebRTCAECState *s = (WebRTCAECState *)f->data;
+  *(bool_t *)arg = s->bypass_mode;
+  return 0;
 }
 
 static int webrtc_aec_set_state(MSFilter *f, void *arg) {
-	WebRTCAECState *s = (WebRTCAECState *) f->data;
-	s->state_str = ms_strdup((const char *) arg);
-	return 0;
+  WebRTCAECState *s = (WebRTCAECState *)f->data;
+  s->state_str = ms_strdup((const char *)arg);
+  return 0;
 }
 
 static int webrtc_aec_get_state(MSFilter *f, void *arg) {
-	WebRTCAECState *s = (WebRTCAECState *) f->data;
-	*(char **) arg = s->state_str;
-	return 0;
+  WebRTCAECState *s = (WebRTCAECState *)f->data;
+  *(char **)arg = s->state_str;
+  return 0;
 }
 
 static MSFilterMethod webrtc_aec_methods[] = {
-	{	MS_FILTER_SET_SAMPLE_RATE		,	webrtc_aec_set_sr 		},
-	{	MS_FILTER_GET_SAMPLE_RATE		,	webrtc_aec_get_sr 		},
-	{	MS_ECHO_CANCELLER_SET_TAIL_LENGTH	,	webrtc_aec_set_tail_length	},
-	{	MS_ECHO_CANCELLER_SET_DELAY		,	webrtc_aec_set_delay		},
-	{	MS_ECHO_CANCELLER_SET_FRAMESIZE		,	webrtc_aec_set_framesize	},
-	{	MS_ECHO_CANCELLER_SET_BYPASS_MODE	,	webrtc_aec_set_bypass_mode	},
-	{	MS_ECHO_CANCELLER_GET_BYPASS_MODE	,	webrtc_aec_get_bypass_mode	},
-	{	MS_ECHO_CANCELLER_GET_STATE_STRING	,	webrtc_aec_get_state		},
-	{	MS_ECHO_CANCELLER_SET_STATE_STRING	,	webrtc_aec_set_state		},
-	{	0,	NULL }
-};
-
+    {MS_FILTER_SET_SAMPLE_RATE, webrtc_aec_set_sr},
+    {MS_FILTER_GET_SAMPLE_RATE, webrtc_aec_get_sr},
+    {MS_ECHO_CANCELLER_SET_TAIL_LENGTH, webrtc_aec_set_tail_length},
+    {MS_ECHO_CANCELLER_SET_DELAY, webrtc_aec_set_delay},
+    {MS_ECHO_CANCELLER_SET_FRAMESIZE, webrtc_aec_set_framesize},
+    {MS_ECHO_CANCELLER_SET_BYPASS_MODE, webrtc_aec_set_bypass_mode},
+    {MS_ECHO_CANCELLER_GET_BYPASS_MODE, webrtc_aec_get_bypass_mode},
+    {MS_ECHO_CANCELLER_GET_STATE_STRING, webrtc_aec_get_state},
+    {MS_ECHO_CANCELLER_SET_STATE_STRING, webrtc_aec_set_state},
+    {0, NULL}};
 
 #ifdef BUILD_AEC
 
-#define MS_WEBRTC_AEC_NAME        "MSWebRTCAEC"
+#define MS_WEBRTC_AEC_NAME "MSWebRTCAEC"
 #define MS_WEBRTC_AEC_DESCRIPTION "Echo canceller using WebRTC library."
-#define MS_WEBRTC_AEC_CATEGORY    MS_FILTER_OTHER
-#define MS_WEBRTC_AEC_ENC_FMT     NULL
-#define MS_WEBRTC_AEC_NINPUTS     2
-#define MS_WEBRTC_AEC_NOUTPUTS    2
-#define MS_WEBRTC_AEC_FLAGS       0
+#define MS_WEBRTC_AEC_CATEGORY MS_FILTER_OTHER
+#define MS_WEBRTC_AEC_ENC_FMT NULL
+#define MS_WEBRTC_AEC_NINPUTS 2
+#define MS_WEBRTC_AEC_NOUTPUTS 2
+#define MS_WEBRTC_AEC_FLAGS 0
 
 #ifdef _MSC_VER
 
 MSFilterDesc ms_webrtc_aec_desc = {
-	MS_FILTER_PLUGIN_ID,
-	MS_WEBRTC_AEC_NAME,
-	MS_WEBRTC_AEC_DESCRIPTION,
-	MS_WEBRTC_AEC_CATEGORY,
-	MS_WEBRTC_AEC_ENC_FMT,
-	MS_WEBRTC_AEC_NINPUTS,
-	MS_WEBRTC_AEC_NOUTPUTS,
-	webrtc_aec_init,
-	webrtc_aec_preprocess,
-	webrtc_aec_process,
-	webrtc_aec_postprocess,
-	webrtc_aec_uninit,
-	webrtc_aec_methods,
-	MS_WEBRTC_AEC_FLAGS
-};
+    MS_FILTER_PLUGIN_ID,    MS_WEBRTC_AEC_NAME,     MS_WEBRTC_AEC_DESCRIPTION,
+    MS_WEBRTC_AEC_CATEGORY, MS_WEBRTC_AEC_ENC_FMT,  MS_WEBRTC_AEC_NINPUTS,
+    MS_WEBRTC_AEC_NOUTPUTS, webrtc_aec_init,        webrtc_aec_preprocess,
+    webrtc_aec_process,     webrtc_aec_postprocess, webrtc_aec_uninit,
+    webrtc_aec_methods,     MS_WEBRTC_AEC_FLAGS};
 
 #else
 
-MSFilterDesc ms_webrtc_aec_desc = {
-	.id = MS_FILTER_PLUGIN_ID,
-	.name = MS_WEBRTC_AEC_NAME,
-	.text = MS_WEBRTC_AEC_DESCRIPTION,
-	.category = MS_WEBRTC_AEC_CATEGORY,
-	.enc_fmt = MS_WEBRTC_AEC_ENC_FMT,
-	.ninputs = MS_WEBRTC_AEC_NINPUTS,
-	.noutputs = MS_WEBRTC_AEC_NOUTPUTS,
-	.init = webrtc_aec_init,
-	.preprocess = webrtc_aec_preprocess,
-	.process = webrtc_aec_process,
-	.postprocess = webrtc_aec_postprocess,
-	.uninit = webrtc_aec_uninit,
-	.methods = webrtc_aec_methods,
-	.flags = MS_WEBRTC_AEC_FLAGS
-};
+MSFilterDesc ms_webrtc_aec_desc = {.id = MS_FILTER_PLUGIN_ID,
+                                   .name = MS_WEBRTC_AEC_NAME,
+                                   .text = MS_WEBRTC_AEC_DESCRIPTION,
+                                   .category = MS_WEBRTC_AEC_CATEGORY,
+                                   .enc_fmt = MS_WEBRTC_AEC_ENC_FMT,
+                                   .ninputs = MS_WEBRTC_AEC_NINPUTS,
+                                   .noutputs = MS_WEBRTC_AEC_NOUTPUTS,
+                                   .init = webrtc_aec_init,
+                                   .preprocess = webrtc_aec_preprocess,
+                                   .process = webrtc_aec_process,
+                                   .postprocess = webrtc_aec_postprocess,
+                                   .uninit = webrtc_aec_uninit,
+                                   .methods = webrtc_aec_methods,
+                                   .flags = MS_WEBRTC_AEC_FLAGS};
 
 #endif
 
@@ -517,51 +535,40 @@ MS_FILTER_DESC_EXPORT(ms_webrtc_aec_desc)
 
 #ifdef BUILD_AECM
 
-#define MS_WEBRTC_AECM_NAME        "MSWebRTCAECM"
-#define MS_WEBRTC_AECM_DESCRIPTION "Echo canceller for mobile using WebRTC library."
-#define MS_WEBRTC_AECM_CATEGORY    MS_FILTER_OTHER
-#define MS_WEBRTC_AECM_ENC_FMT     NULL
-#define MS_WEBRTC_AECM_NINPUTS     2
-#define MS_WEBRTC_AECM_NOUTPUTS    2
-#define MS_WEBRTC_AECM_FLAGS       0
+#define MS_WEBRTC_AECM_NAME "MSWebRTCAECM"
+#define MS_WEBRTC_AECM_DESCRIPTION                                             \
+  "Echo canceller for mobile using WebRTC library."
+#define MS_WEBRTC_AECM_CATEGORY MS_FILTER_OTHER
+#define MS_WEBRTC_AECM_ENC_FMT NULL
+#define MS_WEBRTC_AECM_NINPUTS 2
+#define MS_WEBRTC_AECM_NOUTPUTS 2
+#define MS_WEBRTC_AECM_FLAGS 0
 
 #ifdef _MSC_VER
 
 MSFilterDesc ms_webrtc_aecm_desc = {
-	MS_FILTER_PLUGIN_ID,
-	MS_WEBRTC_AECM_NAME,
-	MS_WEBRTC_AECM_DESCRIPTION,
-	MS_WEBRTC_AECM_CATEGORY,
-	MS_WEBRTC_AECM_ENC_FMT,
-	MS_WEBRTC_AECM_NINPUTS,
-	MS_WEBRTC_AECM_NOUTPUTS,
-	webrtc_aecm_init,
-	webrtc_aec_preprocess,
-	webrtc_aec_process,
-	webrtc_aec_postprocess,
-	webrtc_aec_uninit,
-	webrtc_aec_methods,
-	MS_WEBRTC_AECM_FLAGS
-};
+    MS_FILTER_PLUGIN_ID,     MS_WEBRTC_AECM_NAME,    MS_WEBRTC_AECM_DESCRIPTION,
+    MS_WEBRTC_AECM_CATEGORY, MS_WEBRTC_AECM_ENC_FMT, MS_WEBRTC_AECM_NINPUTS,
+    MS_WEBRTC_AECM_NOUTPUTS, webrtc_aecm_init,       webrtc_aec_preprocess,
+    webrtc_aec_process,      webrtc_aec_postprocess, webrtc_aec_uninit,
+    webrtc_aec_methods,      MS_WEBRTC_AECM_FLAGS};
 
 #else
 
-MSFilterDesc ms_webrtc_aecm_desc = {
-	.id = MS_FILTER_PLUGIN_ID,
-	.name = MS_WEBRTC_AECM_NAME,
-	.text = MS_WEBRTC_AECM_DESCRIPTION,
-	.category = MS_WEBRTC_AECM_CATEGORY,
-	.enc_fmt = MS_WEBRTC_AECM_ENC_FMT,
-	.ninputs = MS_WEBRTC_AECM_NINPUTS,
-	.noutputs = MS_WEBRTC_AECM_NOUTPUTS,
-	.init = webrtc_aecm_init,
-	.preprocess = webrtc_aec_preprocess,
-	.process = webrtc_aec_process,
-	.postprocess = webrtc_aec_postprocess,
-	.uninit = webrtc_aec_uninit,
-	.methods = webrtc_aec_methods,
-	.flags = MS_WEBRTC_AECM_FLAGS
-};
+MSFilterDesc ms_webrtc_aecm_desc = {.id = MS_FILTER_PLUGIN_ID,
+                                    .name = MS_WEBRTC_AECM_NAME,
+                                    .text = MS_WEBRTC_AECM_DESCRIPTION,
+                                    .category = MS_WEBRTC_AECM_CATEGORY,
+                                    .enc_fmt = MS_WEBRTC_AECM_ENC_FMT,
+                                    .ninputs = MS_WEBRTC_AECM_NINPUTS,
+                                    .noutputs = MS_WEBRTC_AECM_NOUTPUTS,
+                                    .init = webrtc_aecm_init,
+                                    .preprocess = webrtc_aec_preprocess,
+                                    .process = webrtc_aec_process,
+                                    .postprocess = webrtc_aec_postprocess,
+                                    .uninit = webrtc_aec_uninit,
+                                    .methods = webrtc_aec_methods,
+                                    .flags = MS_WEBRTC_AECM_FLAGS};
 
 #endif
 
-- 
GitLab

