changeset 5:799b56cbccb6

EFR2 decoder: add post-processing step from AMR
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 03 Apr 2024 06:09:10 +0000
parents 5d7a6bc6960f
children 6119d2c1e7d9
files efr2/Makefile src/d_homing.c src/decoder.c src/post_pro.c src/post_pro.h
diffstat 5 files changed, 171 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/efr2/Makefile	Wed Apr 03 05:55:51 2024 +0000
+++ b/efr2/Makefile	Wed Apr 03 06:09:10 2024 +0000
@@ -21,7 +21,7 @@
        int_lpc.o count.o weight_a.o agc_amr.o set_zero.o preemph.o residu.o \
        syn_filt.o copy.o bits2prm.o reorder.o lsp_az.o inv_sqrt.o d_plsf_5.o \
        d_gains.o d1035pf.o log2.o pow2.o oper_32b.o lsp_lsf.o n_proc.o dtx.o \
-       d_homing.o
+       d_homing.o post_pro.o
 
 # Implicit Rules
 .c.o:
@@ -52,12 +52,12 @@
 d1035pf.o:  typedef.h basic_op.h count.h
 d_gains.o:  typedef.h basic_op.h oper_32b.h count.h sig_proc.h gains_tb.h \
 	    cnst.h dtx.h
-d_homing.o: typedef.h cnst.h dtx.h codec.h d_homing.h q_plsf_5.tab
+d_homing.o: typedef.h cnst.h dtx.h codec.h d_homing.h q_plsf_5.tab post_pro.h
 d_plsf_5.o: typedef.h basic_op.h count.h sig_proc.h q_plsf_5.tab cnst.h dtx.h
 dec_12k2.o: typedef.h basic_op.h sig_proc.h count.h codec.h cnst.h dtx.h
 dec_lag6.o: typedef.h basic_op.h count.h
 decoder.o:  typedef.h n_stack.h basic_op.h sig_proc.h count.h codec.h \
-            cnst.h d_homing.h
+            cnst.h d_homing.h post_pro.h
 dtx.o:      typedef.h basic_op.h cnst.h sig_proc.h count.h dtx.h
 e_homing.o: typedef.h cnst.h vad.h dtx.h codec.h sig_proc.h e_homing.h
 enc_lag6.o: typedef.h basic_op.h count.h
@@ -75,6 +75,7 @@
 oper_32b.o: typedef.h basic_op.h oper_32b.h count.h
 pitch_f6.o: typedef.h basic_op.h oper_32b.h count.h sig_proc.h codec.h
 pitch_ol.o: typedef.h basic_op.h oper_32b.h count.h sig_proc.h
+post_pro.o: typedef.h basic_op.h oper_32b.h count.h post_pro.h
 pow2.o:     typedef.h basic_op.h count.h pow2.tab
 pre_proc.o: typedef.h basic_op.h oper_32b.h count.h
 pred_lt6.o: typedef.h basic_op.h count.h
--- a/src/d_homing.c	Wed Apr 03 05:55:51 2024 +0000
+++ b/src/d_homing.c	Wed Apr 03 06:09:10 2024 +0000
@@ -25,6 +25,10 @@
 #include "d_homing.h"
 #include "q_plsf_5.tab"
 
+#ifdef EFR2_VARIANT
+#include "post_pro.h"
+#endif
+
 #define PRM_NO    57
 
 /***************************************************************************
@@ -340,5 +344,9 @@
     decoder_reset (); /* reset all the state variables in the speech decoder*/
     reset_rx_dtx ();  /* reset all the receive DTX and CN state variables */
 
+#ifdef EFR2_VARIANT
+    AMR_postproc_reset();
+#endif
+
     return;
 }
--- a/src/decoder.c	Wed Apr 03 05:55:51 2024 +0000
+++ b/src/decoder.c	Wed Apr 03 06:09:10 2024 +0000
@@ -32,6 +32,10 @@
 #include "cnst.h"
 #include "d_homing.h"
 
+#ifdef EFR2_VARIANT
+#include "post_pro.h"
+#endif
+
 
 /* These constants define the number of consecutive parameters
    that function decoder_homing_frame_test() checks */
@@ -180,12 +184,20 @@
             fwc ();             /* function worst case */
 #endif
 
+#ifdef EFR2_VARIANT
+            Post_Process(synth, L_FRAME);
+#endif
+
             for (i = 0; i < L_FRAME; i++) 
                 /* Upscale the 15 bit linear PCM to 16 bits,
                    then truncate to 13 bits */
             {
+#ifndef EFR2_VARIANT
                 temp = shl (synth[i], 1);
                 synth[i] = temp & 0xfff8;       logic16 (); move16 (); 
+#else
+                synth[i] &= 0xfff8;
+#endif
             }
 
 #if (WMOPS)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/post_pro.c	Wed Apr 03 06:09:10 2024 +0000
@@ -0,0 +1,139 @@
+/*
+********************************************************************************
+*
+*      GSM AMR-NB speech codec   R98   Version 7.6.0   December 12, 2001
+*                                R99   Version 3.3.0                
+*                                REL-4 Version 4.1.0                
+*
+********************************************************************************
+*
+*      File             : post_pro.c
+*      Purpose          : Postprocessing of output speech.
+*
+*                         - 2nd order high pass filtering with cut
+*                           off frequency at 60 Hz.
+*                         - Multiplication of output by two.
+*
+********************************************************************************
+*/
+ 
+ 
+/*
+********************************************************************************
+*                         MODULE INCLUDE FILE AND VERSION ID
+********************************************************************************
+*/
+#if 0
+#include "post_pro.h"
+const char post_pro_id[] = "@(#)$Id $" post_pro_h;
+#endif
+ 
+/*
+********************************************************************************
+*                         INCLUDE FILES
+********************************************************************************
+*/
+#include <stdlib.h>
+#include <stdio.h>
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "count.h"
+#include "post_pro.h"
+ 
+/*
+********************************************************************************
+*                         LOCAL VARIABLES AND TABLES
+********************************************************************************
+*/
+/* filter coefficients (fc = 60 Hz) */
+static const Word16 b[3] = {7699, -15398, 7699};
+static const Word16 a[3] = {8192, 15836, -7667};
+
+typedef struct {
+   Word16 y2_hi;
+   Word16 y2_lo;
+   Word16 y1_hi;
+   Word16 y1_lo;
+   Word16 x0;
+   Word16 x1;
+} Post_ProcessState;
+
+static Post_ProcessState ppstate;
+
+/*
+********************************************************************************
+*                         PUBLIC PROGRAM CODE
+********************************************************************************
+*/
+ 
+/*************************************************************************
+*
+*  Function:   Post_Process_reset
+*  Purpose:    Initializes state memory to zero
+*
+**************************************************************************
+*/
+void AMR_postproc_reset (void)
+{
+  Post_ProcessState *state = &ppstate;
+
+  state->y2_hi = 0;
+  state->y2_lo = 0;
+  state->y1_hi = 0;
+  state->y1_lo = 0;
+  state->x0 = 0;
+  state->x1 = 0;
+}
+ 
+/*************************************************************************
+ *
+ *  FUNCTION:  Post_Process()
+ *
+ *  PURPOSE: Postprocessing of input speech.
+ *
+ *  DESCRIPTION:
+ *     - 2nd order high pass filtering with cut off frequency at 60 Hz.
+ *     - Multiplication of output by two.
+ *                                                                        
+ * Algorithm:                                                             
+ *                                                                        
+ *  y[i] = b[0]*x[i]*2 + b[1]*x[i-1]*2 + b[2]*x[i-2]*2
+ *                     + a[1]*y[i-1]   + a[2]*y[i-2];                     
+ *                                                                        
+ *                                                                        
+ *************************************************************************/
+void Post_Process (
+    Word16 signal[],        /* i/o : signal                               */
+    Word16 lg               /* i   : length of signal                     */
+    )
+{
+    Post_ProcessState *st = &ppstate;
+    Word16 i, x2;
+    Word32 L_tmp;
+
+    test (); test ();
+    for (i = 0; i < lg; i++)
+    {
+        x2 = st->x1;                             move16 (); 
+        st->x1 = st->x0;                         move16 (); 
+        st->x0 = signal[i];                      move16 (); 
+        
+        /*  y[i] = b[0]*x[i]*2 + b[1]*x[i-1]*2 + b140[2]*x[i-2]/2  */
+        /*                     + a[1]*y[i-1] + a[2] * y[i-2];      */
+        
+        L_tmp = Mpy_32_16 (st->y1_hi, st->y1_lo, a[1]);
+        L_tmp = L_add (L_tmp, Mpy_32_16 (st->y2_hi, st->y2_lo, a[2]));
+        L_tmp = L_mac (L_tmp, st->x0, b[0]);
+        L_tmp = L_mac (L_tmp, st->x1, b[1]);
+        L_tmp = L_mac (L_tmp, x2, b[2]);
+        L_tmp = L_shl (L_tmp, 2);
+        
+        /* Multiplication by two of output speech with saturation. */
+        signal[i] = round(L_shl(L_tmp, 1));   move16 (); 
+        
+        st->y2_hi = st->y1_hi;                   move16 (); 
+        st->y2_lo = st->y1_lo;                   move16 (); 
+        L_Extract (L_tmp, &st->y1_hi, &st->y1_lo);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/post_pro.h	Wed Apr 03 06:09:10 2024 +0000
@@ -0,0 +1,8 @@
+/*
+ * Function declarations for post_pro.c: a hacked-up piece of code
+ * lifted from AMR source and integrated into the old ETSI EFR
+ * way of doing things.
+ */
+
+void AMR_postproc_reset (void);
+void Post_Process (Word16 signal[], Word16 lg);