]> code.delx.au - pulseaudio/blobdiff - src/modules/echo-cancel/adrian-aec.c
alsa: Allow channel count probe on open by mapping
[pulseaudio] / src / modules / echo-cancel / adrian-aec.c
index 6793e59d410f0194fc1827c44f8865ff9d5b59b9..1476ee4f80568761761f06957b22c7fbe9c60ac2 100644 (file)
  * Version 0.4 Leaky Normalized LMS - pre whitening algorithm
  */
 
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
 #include <math.h>
 #include <string.h>
+#include <stdint.h>
 
 #include <pulse/xmalloc.h>
 
@@ -39,7 +44,6 @@ static REAL dotp(REAL a[], REAL b[])
   return sum0 + sum1;
 }
 
-static REAL dotp_sse(REAL a[], REAL b[]) __attribute__((noinline));
 static REAL dotp_sse(REAL a[], REAL b[])
 {
 #ifdef __SSE__
@@ -70,7 +74,7 @@ AEC* AEC_init(int RATE, int have_vector)
   a->hangover = 0;
   memset(a->x, 0, sizeof(a->x));
   memset(a->xf, 0, sizeof(a->xf));
-  memset(a->w, 0, sizeof(a->w));
+  memset(a->w_arr, 0, sizeof(a->w_arr));
   a->j = NLMS_EXT;
   a->delta = 0.0f;
   AEC_setambient(a, NoiseFloor);
@@ -89,10 +93,15 @@ AEC* AEC_init(int RATE, int have_vector)
   a->dumpcnt = 0;
   memset(a->ws, 0, sizeof(a->ws));
 
-  if (have_vector)
+  if (have_vector) {
+      /* Get a 16-byte aligned location */
+      a->w = (REAL *) (((uintptr_t) a->w_arr) + (((uintptr_t) a->w_arr) % 16));
       a->dotp = dotp_sse;
-  else
+  } else {
+      /* We don't care about alignment, just use the array as-is */
+      a->w = a->w_arr;
       a->dotp = dotp;
+  }
 
   return a;
 }
@@ -107,8 +116,7 @@ AEC* AEC_init(int RATE, int have_vector)
 // mapped to 1.0 with a limited linear function.
 static float AEC_dtd(AEC *a, REAL d, REAL x)
 {
-  float stepsize;
-  float ratio, M;
+  float ratio, stepsize;
 
   // fast near-end and far-end average
   a->dfast += ALPHAFAST * (fabsf(d) - a->dfast);
@@ -129,16 +137,13 @@ static float AEC_dtd(AEC *a, REAL d, REAL x)
   // ratio of NFRs
   ratio = (a->dfast * a->xslow) / (a->dslow * a->xfast);
 
-  // begrenzte lineare Kennlinie
-  M = (STEPY2 - STEPY1) / (STEPX2 - STEPX1);
-  if (ratio < STEPX1) {
+  // Linear interpolation with clamping at the limits
+  if (ratio < STEPX1)
     stepsize = STEPY1;
-  } else if (ratio > STEPX2) {
+  else if (ratio > STEPX2)
     stepsize = STEPY2;
-  } else {
-    // Punktrichtungsform einer Geraden
-    stepsize = M * (ratio - STEPX1) + STEPY1;
-  }
+  else
+    stepsize = STEPY1 + (STEPY2 - STEPY1) * (ratio - STEPX1) / (STEPX2 - STEPX1);
 
   return stepsize;
 }