diff libtwamr/pstfilt.c @ 401:59655481e45b

libtwamr: integrate pstfilt.c
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 06 May 2024 19:44:15 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtwamr/pstfilt.c	Mon May 06 19:44:15 2024 +0000
@@ -0,0 +1,217 @@
+/*************************************************************************
+*
+*      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             : pstfilt.c
+*      Purpose          : Performs adaptive postfiltering on the synthesis
+*                       : speech
+*
+********************************************************************************
+*/
+
+/*
+********************************************************************************
+*                         MODULE INCLUDE FILE AND VERSION ID
+********************************************************************************
+*/
+#include "namespace.h"
+#include "pstfilt.h"
+ 
+/*
+********************************************************************************
+*                         INCLUDE FILES
+********************************************************************************
+*/
+#include "tw_amr.h"
+#include "typedef.h"
+#include "basic_op.h"
+#include "memops.h"
+#include "weight_a.h"
+#include "residu.h"
+#include "syn_filt.h"
+#include "preemph.h"
+#include "no_count.h"
+#include "cnst.h"
+
+/*
+********************************************************************************
+*                         LOCAL VARIABLES AND TABLES
+********************************************************************************
+*/
+/*---------------------------------------------------------------*
+ *    Postfilter constant parameters (defined in "cnst.h")       *
+ *---------------------------------------------------------------*
+ *   L_FRAME     : Frame size.                                   *
+ *   L_SUBFR     : Sub-frame size.                               *
+ *   M           : LPC order.                                    *
+ *   MP1         : LPC order+1                                   *
+ *   MU          : Factor for tilt compensation filter           *
+ *   AGC_FAC     : Factor for automatic gain control             *
+ *---------------------------------------------------------------*/
+
+#define L_H 22  /* size of truncated impulse response of A(z/g1)/A(z/g2) */
+
+/* Spectral expansion factors */
+static const Word16 gamma3_MR122[M] = {
+  22938, 16057, 11240, 7868, 5508,
+  3856, 2699, 1889, 1322, 925
+};
+
+static const Word16 gamma3[M] = {
+  18022, 9912, 5451, 2998, 1649, 907, 499, 274, 151, 83
+};
+
+static const Word16 gamma4_MR122[M] = {
+  24576, 18432, 13824, 10368, 7776,
+  5832, 4374, 3281, 2461, 1846
+};
+
+static const Word16 gamma4[M] = {
+  22938, 16057, 11240, 7868, 5508, 3856, 2699, 1889, 1322, 925
+};
+
+/*
+********************************************************************************
+*                         PUBLIC PROGRAM CODE
+********************************************************************************
+*/
+
+/*************************************************************************
+*
+*  Function:   Post_Filter_reset
+*  Purpose:    Initializes state memory to zero
+*
+**************************************************************************
+*/
+void Post_Filter_reset (Post_FilterState *state)
+{
+  Set_zero (state->mem_syn_pst, M);
+  Set_zero (state->res2, L_SUBFR);
+  Set_zero (state->synth_buf, L_FRAME + M);
+  agc_reset(&state->agc_state);
+  preemphasis_reset(&state->preemph_state);
+}
+
+/*
+**************************************************************************
+*  Function:  Post_Filter
+*  Purpose:   postfiltering of synthesis speech.
+*  Description:
+*      The postfiltering process is described as follows:
+*
+*          - inverse filtering of syn[] through A(z/0.7) to get res2[]
+*          - tilt compensation filtering; 1 - MU*k*z^-1
+*          - synthesis filtering through 1/A(z/0.75)
+*          - adaptive gain control
+*
+**************************************************************************
+*/
+int Post_Filter (
+    Post_FilterState *st, /* i/o : post filter states                        */
+    enum Mode mode,       /* i   : AMR mode                                  */
+    Word16 *syn,          /* i/o : synthesis speech (postfiltered is output) */
+    Word16 *Az_4          /* i   : interpolated LPC parameters in all subfr. */
+)
+{
+    /*-------------------------------------------------------------------*
+     *           Declaration of parameters                               *
+     *-------------------------------------------------------------------*/
+
+    Word16 Ap3[MP1], Ap4[MP1];  /* bandwidth expanded LP parameters */
+    Word16 *Az;                 /* pointer to Az_4:                 */
+                                /*  LPC parameters in each subframe */
+    Word16 i_subfr;             /* index for beginning of subframe  */
+    Word16 h[L_H];
+
+    Word16 i;
+    Word16 temp1, temp2;
+    Word32 L_tmp;
+    Word16 *syn_work = &st->synth_buf[M]; move16 ();
+
+    /*-----------------------------------------------------*
+     * Post filtering                                      *
+     *-----------------------------------------------------*/
+
+    Copy (syn, syn_work , L_FRAME);
+
+    Az = Az_4;
+
+    for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
+    {
+       /* Find weighted filter coefficients Ap3[] and ap[4] */
+
+       test (); test ();
+       if (sub(mode, MR122) == 0 || sub(mode, MR102) == 0)
+       {
+          Weight_Ai (Az, gamma3_MR122, Ap3);
+          Weight_Ai (Az, gamma4_MR122, Ap4);
+       }
+       else
+       {
+          Weight_Ai (Az, gamma3, Ap3);
+          Weight_Ai (Az, gamma4, Ap4);
+       }
+       
+       /* filtering of synthesis speech by A(z/0.7) to find res2[] */
+       
+       Residu (Ap3, &syn_work[i_subfr], st->res2, L_SUBFR);
+       
+       /* tilt compensation filter */
+       
+       /* impulse response of A(z/0.7)/A(z/0.75) */
+
+       Copy (Ap3, h, M + 1);
+       Set_zero (&h[M + 1], L_H - M - 1);
+       Syn_filt (Ap4, h, h, L_H, &h[M + 1], 0);
+        
+       /* 1st correlation of h[] */
+       
+       L_tmp = L_mult (h[0], h[0]);
+       for (i = 1; i < L_H; i++)
+       {
+          L_tmp = L_mac (L_tmp, h[i], h[i]);
+       }
+       temp1 = extract_h (L_tmp);
+       
+       L_tmp = L_mult (h[0], h[1]);
+       for (i = 1; i < L_H - 1; i++)
+       {
+          L_tmp = L_mac (L_tmp, h[i], h[i + 1]);
+       }
+       temp2 = extract_h (L_tmp);
+       
+       test (); 
+       if (temp2 <= 0)
+       {
+          temp2 = 0;          move16 (); 
+       }
+       else
+       {
+          temp2 = mult (temp2, MU);
+          temp2 = div_s (temp2, temp1);
+       }
+
+       preemphasis (&st->preemph_state, st->res2, temp2, L_SUBFR);
+
+       /* filtering through  1/A(z/0.75) */
+
+       Syn_filt (Ap4, st->res2, &syn[i_subfr], L_SUBFR, st->mem_syn_pst, 1);
+
+       /* scale output to input */
+
+       agc (&st->agc_state, &syn_work[i_subfr], &syn[i_subfr],
+            AGC_FAC, L_SUBFR);
+       
+       Az += MP1;
+    }
+
+    /* update syn_work[] buffer */
+
+    Copy (&syn_work[L_FRAME - M], &syn_work[-M], M);
+
+    return 0;
+}