changeset 390:bde9f5804670

libtwamr: integrate ph_disp.c
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 06 May 2024 18:20:22 +0000
parents 9cd332a94c97
children be8edf9e6bc1
files libtwamr/Makefile libtwamr/namespace.list libtwamr/ph_disp.c libtwamr/ph_disp.h libtwamr/ph_disp.tab
diffstat 5 files changed, 474 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/libtwamr/Makefile	Mon May 06 06:49:54 2024 +0000
+++ b/libtwamr/Makefile	Mon May 06 18:20:22 2024 +0000
@@ -9,10 +9,10 @@
 	enc_lag6.o ex_ctrl.o g_adapt.o g_code.o g_pitch.o gain_q.o gains_tab.o \
 	gc_pred.o gmed_n.o graytab.o hp_max.o int_lpc.o int_lsf.o inter_36.o \
 	inv_sqrt.o lag_wind.o levinson.o log2.o lpc.o lsfwt.o lsp.o lsp_avg.o \
-	lsp_az.o lsp_lsf.o lsp_tab.o mac_32.o oper_32b.o pow2.o prmno.o \
-	q_gain_c.o q_gain_p.o q_plsf.o q_plsf3_tab.o q_plsf5_tab.o q_plsf_3.o \
-	q_plsf_5.o qgain475.o qgain795.o qua_gain.o qua_gain_tab.o reorder.o \
-	s10_8pf.o set_sign.o sqrt_l.o tls_flags.o window.o
+	lsp_az.o lsp_lsf.o lsp_tab.o mac_32.o oper_32b.o ph_disp.o pow2.o \
+	prmno.o q_gain_c.o q_gain_p.o q_plsf.o q_plsf3_tab.o q_plsf5_tab.o \
+	q_plsf_3.o q_plsf_5.o qgain475.o qgain795.o qua_gain.o qua_gain_tab.o \
+	reorder.o s10_8pf.o set_sign.o sqrt_l.o tls_flags.o window.o
 HDRS=	namespace.h
 LIB=	libtwamr.a
 
--- a/libtwamr/namespace.list	Mon May 06 06:49:54 2024 +0000
+++ b/libtwamr/namespace.list	Mon May 06 18:20:22 2024 +0000
@@ -41,6 +41,7 @@
 gc_pred gc_pred_copy gc_pred_reset gc_pred_update gc_pred_average_limited
 gmed_n hp_max
 lpc lpc_reset lsp lsp_reset lsp_avg lsp_avg_reset
+ph_disp ph_disp_reset ph_disp_lock ph_disp_release
 q_gain_code q_gain_pitch
 
 Bits2prm Prm2bits
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtwamr/ph_disp.c	Mon May 06 18:20:22 2024 +0000
@@ -0,0 +1,311 @@
+/*
+********************************************************************************
+*
+*      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             : ph_disp.c
+*      Purpose          : Perform adaptive phase dispersion of the excitation
+*                         signal.
+*
+********************************************************************************
+*/
+/*
+********************************************************************************
+*                         MODULE INCLUDE FILE AND VERSION ID
+********************************************************************************
+*/
+#include "namespace.h"
+#include "ph_disp.h"
+
+/*
+********************************************************************************
+*                         INCLUDE FILES
+********************************************************************************
+*/
+#include "typedef.h"
+#include "basic_op.h"
+#include "no_count.h"
+#include "cnst.h"
+#include "memops.h"
+
+/*
+********************************************************************************
+*                         LOCAL VARIABLES AND TABLES
+********************************************************************************
+*/
+
+#include "ph_disp.tab"
+
+/*
+********************************************************************************
+*                         PUBLIC PROGRAM CODE
+********************************************************************************
+*/
+
+/*************************************************************************
+*
+*  Function:   ph_disp_reset
+*
+**************************************************************************
+*/
+void ph_disp_reset (ph_dispState *state)
+{
+   Word16 i;
+
+   for (i=0; i<PHDGAINMEMSIZE; i++)
+   {
+       state->gainMem[i] = 0;
+   }
+   state->prevState = 0;
+   state->prevCbGain = 0;
+   state->lockFull = 0;
+   state->onset = 0;          /* assume no onset in start */ 
+}
+
+/*************************************************************************
+*
+*  Function:   ph_disp_lock
+*
+**************************************************************************
+*/
+void ph_disp_lock (ph_dispState *state)
+{
+  state->lockFull = 1;
+  return;
+}
+
+/*************************************************************************
+*
+*  Function:   ph_disp_release
+*
+**************************************************************************
+*/
+void ph_disp_release (ph_dispState *state)
+{
+  state->lockFull = 0;
+  return;
+}
+
+
+/*************************************************************************
+*
+*  Function:   ph_disp
+*
+*              Adaptive phase dispersion; forming of total excitation
+*              (for synthesis part of decoder)
+*
+**************************************************************************
+*/
+void ph_disp (
+      ph_dispState *state, /* i/o     : State struct                     */
+      enum Mode mode,      /* i       : codec mode                       */
+      Word16 x[],          /* i/o Q0  : in:  LTP excitation signal       */
+                           /*           out: total excitation signal     */
+      Word16 cbGain,       /* i   Q1  : Codebook gain                    */
+      Word16 ltpGain,      /* i   Q14 : LTP gain                         */
+      Word16 inno[],       /* i/o Q13 : Innovation vector (Q12 for 12.2) */
+      Word16 pitch_fac,    /* i   Q14 : pitch factor used to scale the
+                                        LTP excitation (Q13 for 12.2)    */
+      Word16 tmp_shift     /* i   Q0  : shift factor applied to sum of   
+                                        scaled LTP ex & innov. before
+                                        rounding                         */
+)
+{
+   Word16 i, i1;
+   Word16 tmp1;
+   Word32 L_temp;
+   Word16 impNr;           /* indicator for amount of disp./filter used */
+
+   Word16 inno_sav[L_SUBFR];
+   Word16 ps_poss[L_SUBFR];
+   Word16 j, nze, nPulse, ppos;
+   const Word16 *ph_imp;   /* Pointer to phase dispersion filter */
+
+   /* Update LTP gain memory */
+   for (i = PHDGAINMEMSIZE-1; i > 0; i--)
+   {
+       state->gainMem[i] = state->gainMem[i-1];                    move16 ();
+   }
+   state->gainMem[0] = ltpGain;                                    move16 ();
+   
+   /* basic adaption of phase dispersion */
+   test ();
+   if (sub(ltpGain, PHDTHR2LTP) < 0) {    /* if (ltpGain < 0.9) */
+       test ();
+       if (sub(ltpGain, PHDTHR1LTP) > 0)
+       {  /* if (ltpGain > 0.6 */
+          impNr = 1; /* medium dispersion */                      move16 ();
+       }
+       else
+       {
+          impNr = 0; /* maximum dispersion */                     move16 ();
+       }
+   }
+   else
+   {
+      impNr = 2; /* no dispersion */                              move16 ();
+   }
+   
+   /* onset indicator */
+   /* onset = (cbGain  > onFact * cbGainMem[0]) */
+                                                                   move32 ();
+   tmp1 = round(L_shl(L_mult(state->prevCbGain, ONFACTPLUS1), 2));
+   test ();
+   if (sub(cbGain, tmp1) > 0)
+   {
+       state->onset = ONLENGTH;                                    move16 ();
+   }
+   else
+   {
+       test (); 
+       if (state->onset > 0)
+       {
+           state->onset = sub (state->onset, 1);                   move16 ();
+       }
+   }
+   
+   /* if not onset, check ltpGain buffer and use max phase dispersion if
+      half or more of the ltpGain-parameters say so */
+   test ();
+   if (state->onset == 0)
+   {
+       /* Check LTP gain memory and set filter accordingly */
+       i1 = 0;                                                     move16 ();
+       for (i = 0; i < PHDGAINMEMSIZE; i++)
+       {
+           test ();
+           if (sub(state->gainMem[i], PHDTHR1LTP) < 0)
+           {
+               i1 = add (i1, 1);
+           }
+       }
+       test ();
+       if (sub(i1, 2) > 0)
+       {
+           impNr = 0;                                              move16 ();
+       }
+       
+   }
+   /* Restrict decrease in phase dispersion to one step if not onset */
+   test (); test ();
+   if ((sub(impNr, add(state->prevState, 1)) > 0) && (state->onset == 0))
+   {
+       impNr = sub (impNr, 1);
+   }
+   /* if onset, use one step less phase dispersion */
+   test (); test ();
+   if((sub(impNr, 2) < 0) && (state->onset > 0))
+   {
+       impNr = add (impNr, 1);
+   }
+   
+   /* disable for very low levels */
+   test ();
+   if(sub(cbGain, 10) < 0)
+   {
+       impNr = 2;                                                  move16 ();
+   }
+   
+   test ();
+   if(sub(state->lockFull, 1) == 0)
+   {
+       impNr = 0;                                                  move16 ();
+   }
+
+   /* update static memory */
+   state->prevState = impNr;                                       move16 ();
+   state->prevCbGain = cbGain;                                     move16 ();
+  
+   /* do phase dispersion for all modes but 12.2 and 7.4;
+      don't modify the innovation if impNr >=2 (= no phase disp) */
+   test (); test (); test(); test();
+   if (sub(mode, MR122) != 0 && 
+       sub(mode, MR102) != 0 &&
+       sub(mode, MR74) != 0 &&
+       sub(impNr, 2) < 0)
+   {
+       /* track pulse positions, save innovation,
+          and initialize new innovation          */
+       nze = 0;                                                    move16 ();
+       for (i = 0; i < L_SUBFR; i++)
+       {
+           move16 (); test();
+           if (inno[i] != 0)
+           {
+               ps_poss[nze] = i;                                   move16 ();
+               nze = add (nze, 1);
+           }
+           inno_sav[i] = inno[i];                                  move16 ();
+           inno[i] = 0;                                            move16 ();
+       }
+       /* Choose filter corresponding to codec mode and dispersion criterium */
+       test ();
+       if (sub (mode, MR795) == 0)
+       {
+           test ();
+           if (impNr == 0)
+           {
+               ph_imp = ph_imp_low_MR795;                            move16 ();
+           }
+           else
+           {
+               ph_imp = ph_imp_mid_MR795;                            move16 ();
+           }
+       }
+       else
+       {
+           test ();
+           if (impNr == 0)
+           {
+               ph_imp = ph_imp_low;                                  move16 ();
+           }
+           else
+           {
+               ph_imp = ph_imp_mid;                                  move16 ();
+           }
+       }
+       
+       /* Do phase dispersion of innovation */
+       for (nPulse = 0; nPulse < nze; nPulse++)
+       {
+           ppos = ps_poss[nPulse];                                   move16 ();
+           
+           /* circular convolution with impulse response */
+           j = 0;                                                    move16 ();
+           for (i = ppos; i < L_SUBFR; i++)
+           {
+               /* inno[i1] += inno_sav[ppos] * ph_imp[i1-ppos] */
+               tmp1 = mult(inno_sav[ppos], ph_imp[j++]);
+               inno[i] = add(inno[i], tmp1);                         move16 ();
+           }    
+           
+           for (i = 0; i < ppos; i++)
+           {
+               /* inno[i] += inno_sav[ppos] * ph_imp[L_SUBFR-ppos+i] */
+               tmp1 = mult(inno_sav[ppos], ph_imp[j++]);
+               inno[i] = add(inno[i], tmp1);                         move16 ();
+           }
+       }
+   }
+       
+   /* compute total excitation for synthesis part of decoder
+      (using modified innovation if phase dispersion is active) */
+   for (i = 0; i < L_SUBFR; i++)
+   {
+       /* x[i] = gain_pit*x[i] + cbGain*code[i]; */
+       L_temp = L_mult (        x[i],    pitch_fac);
+                                                /* 12.2: Q0 * Q13 */
+                                                /*  7.4: Q0 * Q14 */
+       L_temp = L_mac  (L_temp, inno[i], cbGain);
+                                                /* 12.2: Q12 * Q1 */
+                                                /*  7.4: Q13 * Q1 */
+       L_temp = L_shl (L_temp, tmp_shift);                 /* Q16 */           
+       x[i] = round (L_temp);                                        move16 (); 
+   }
+
+   return;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtwamr/ph_disp.h	Mon May 06 18:20:22 2024 +0000
@@ -0,0 +1,107 @@
+/*
+********************************************************************************
+*
+*      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             : ph_disp.h
+*      Purpose          : Phase dispersion of excitation signal
+*
+********************************************************************************
+*/
+
+#ifndef ph_disp_h
+#define ph_disp_h "$Id $"
+ 
+/*
+********************************************************************************
+*                         INCLUDE FILES
+********************************************************************************
+*/
+#include "tw_amr.h"
+#include "typedef.h"
+
+/*
+********************************************************************************
+*                         LOCAL VARIABLES AND TABLES
+********************************************************************************
+*/
+#define PHDGAINMEMSIZE 5
+#define PHDTHR1LTP     9830  /* 0.6 in Q14 */
+#define PHDTHR2LTP     14746 /* 0.9 in Q14 */
+#define ONFACTPLUS1    16384 /* 2.0 in Q13   */
+#define ONLENGTH 2
+/*
+********************************************************************************
+*                         DEFINITION OF DATA TYPES
+********************************************************************************
+*/
+typedef struct {
+  Word16 gainMem[PHDGAINMEMSIZE];
+  Word16 prevState;
+  Word16 prevCbGain;
+  Word16 lockFull;
+  Word16 onset;
+} ph_dispState;
+ 
+/*
+********************************************************************************
+*                         DECLARATION OF PROTOTYPES
+********************************************************************************
+*/
+
+/*************************************************************************
+*
+*  Function:   ph_disp_reset
+*  Purpose:    Initializes state memory
+*
+**************************************************************************
+*/
+void ph_disp_reset (ph_dispState *state);
+
+/*************************************************************************
+*
+*  Function:   ph_disp_lock
+*  Purpose:    mark phase dispersion as locked in state struct
+*
+**************************************************************************
+*/
+void ph_disp_lock (ph_dispState *state);
+
+/*************************************************************************
+*
+*  Function:   ph_disp_release
+*  Purpose:    mark phase dispersion as unlocked in state struct
+*
+**************************************************************************
+*/
+void ph_disp_release (ph_dispState *state);
+
+/*************************************************************************
+*
+*  Function:   ph_disp
+*  Purpose:    perform phase dispersion according to the specified codec
+*              mode and computes total excitation for synthesis part
+*              if decoder
+*
+**************************************************************************
+*/
+void ph_disp (
+      ph_dispState *state, /* i/o     : State struct                     */
+      enum Mode mode,      /* i       : codec mode                       */
+      Word16 x[],          /* i/o Q0  : in:  LTP excitation signal       */
+                           /*           out: total excitation signal     */
+      Word16 cbGain,       /* i   Q1  : Codebook gain                    */
+      Word16 ltpGain,      /* i   Q14 : LTP gain                         */
+      Word16 inno[],       /* i   Q13 : Innovation vector (Q12 for 12.2) */
+      Word16 pitch_fac,    /* i   Q14 : pitch factor used to scale the
+                                        LTP excitation (Q13 for 12.2)    */
+      Word16 tmp_shift     /* i   Q0  : shift factor applied to sum of   
+                                        scaled LTP ex & innov. before
+                                        rounding                         */
+);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtwamr/ph_disp.tab	Mon May 06 18:20:22 2024 +0000
@@ -0,0 +1,51 @@
+/*
+********************************************************************************
+*
+*      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             : ph_disp.tab
+*      Purpose          : Table of impulse responses of phase dispersion filters
+*      $Id $
+*
+********************************************************************************
+*/
+
+/* The following tables are constant, but not declared constant due to
+   compiler warnings in conjunction with the program code              */
+
+/* All impulse responses are in Q15 */
+
+static const Word16 ph_imp_low_MR795[] = 
+{
+  26777,    801,   2505,   -683,  -1382,    582,    604,  -1274,   3511,  -5894,
+   4534,   -499,  -1940,   3011,  -5058,   5614,  -1990,  -1061,  -1459,   4442,
+   -700,  -5335,   4609,    452,   -589,  -3352,   2953,   1267,  -1212,  -2590,
+   1731,   3670,  -4475,   -975,   4391,  -2537,    949,  -1363,   -979,   5734
+};
+static const Word16 ph_imp_mid_MR795[] = 
+{
+  30274,   3831,  -4036,   2972,  -1048,  -1002,   2477,  -3043,   2815,  -2231,
+   1753,  -1611,   1714,  -1775,   1543,  -1008,    429,   -169,    472,  -1264,
+   2176,  -2706,   2523,  -1621,    344,    826,  -1529,   1724,  -1657,   1701,
+  -2063,   2644,  -3060,   2897,  -1978,    557,    780,  -1369,    842,    655
+};
+
+static const Word16 ph_imp_low[] =
+{
+  14690,  11518,   1268,  -2761,  -5671,   7514,    -35,  -2807,  -3040,   4823,
+   2952,  -8424,   3785,   1455,   2179,  -8637,   8051,  -2103,  -1454,    777,
+   1108,  -2385,   2254,   -363,   -674,  -2103,   6046,  -5681,   1072,   3123,
+  -5058,   5312,  -2329,  -3728,   6924,  -3889,    675,  -1775,     29,  10145
+};
+static const Word16 ph_imp_mid[] =
+{
+  30274,   3831,  -4036,   2972,  -1048,  -1002,   2477,  -3043,   2815,  -2231,
+   1753,  -1611,   1714,  -1775,   1543,  -1008,    429,   -169,    472,  -1264,
+   2176,  -2706,   2523,  -1621,    344,    826,  -1529,   1724,  -1657,   1701,
+  -2063,   2644,  -3060,   2897,  -1978,    557,    780,  -1369,    842,    655
+};
+