diff src/autocorr.c @ 0:56410792419a

src: original EFR source from ETSI
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 03 Apr 2024 05:31:37 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/autocorr.c	Wed Apr 03 05:31:37 2024 +0000
@@ -0,0 +1,99 @@
+/*************************************************************************
+ *
+ *  FUNCTION:  autocorr
+ *
+ *  PURPOSE:   Compute autocorrelations of signal with windowing
+ *
+ *  DESCRIPTION:
+ *       - Windowing of input speech:   s'[n] = s[n] * w[n]
+ *       - Autocorrelations of input speech:
+ *             r[k] = sum_{i=k}^{239} s'[i]*s'[i-k]    k=0,...,10
+ *         The autocorrelations are expressed in normalized double precision
+ *         format.
+ *
+ *************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "count.h"
+#include "cnst.h"
+
+Word16 Autocorr (
+    Word16 x[],         /* (i)    : Input signal                    */
+    Word16 m,           /* (i)    : LPC order                       */
+    Word16 r_h[],       /* (o)    : Autocorrelations  (msb)         */
+    Word16 r_l[],       /* (o)    : Autocorrelations  (lsb)         */
+    Word16 wind[]       /* (i)    : window for LPC analysis         */
+)
+{
+    Word16 i, j, norm;
+    Word16 y[L_WINDOW];
+    Word32 sum;
+    Word16 overfl, overfl_shft;
+
+    /* Windowing of signal */
+
+    for (i = 0; i < L_WINDOW; i++)
+    {
+        y[i] = mult_r (x[i], wind[i]); move16 (); 
+    }
+
+    /* Compute r[0] and test for overflow */
+
+    overfl_shft = 0;                   move16 (); 
+
+    do
+    {
+        overfl = 0;                    move16 (); 
+        sum = 0L;                      move32 ();
+
+        for (i = 0; i < L_WINDOW; i++)
+        {
+            sum = L_mac (sum, y[i], y[i]);
+        }
+
+        /* If overflow divide y[] by 4 */
+
+        test (); 
+        if (L_sub (sum, MAX_32) == 0L)
+        {
+            overfl_shft = add (overfl_shft, 4);
+            overfl = 1;                move16 (); /* Set the overflow flag */
+
+            for (i = 0; i < L_WINDOW; i++)
+            {
+                y[i] = shr (y[i], 2);  move16 (); 
+            }
+        }
+        test (); 
+    }
+    while (overfl != 0);
+
+    sum = L_add (sum, 1L);             /* Avoid the case of all zeros */
+
+    /* Normalization of r[0] */
+
+    norm = norm_l (sum);
+    sum = L_shl (sum, norm);
+    L_Extract (sum, &r_h[0], &r_l[0]); /* Put in DPF format (see oper_32b) */
+
+    /* r[1] to r[m] */
+
+    for (i = 1; i <= m; i++)
+    {
+        sum = 0;                       move32 (); 
+
+        for (j = 0; j < L_WINDOW - i; j++)
+        {
+            sum = L_mac (sum, y[j], y[j + i]);
+        }
+
+        sum = L_shl (sum, norm);
+        L_Extract (sum, &r_h[i], &r_l[i]);
+    }
+
+    norm = sub (norm, overfl_shft);
+
+    return norm;
+}