changeset 415:01c4becb9fda

libtwamr: integrate pitch_ol.c
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 07 May 2024 03:01:01 +0000
parents 028ed5114e52
children 48c7f8e8c9af
files libtwamr/Makefile libtwamr/namespace.list libtwamr/pitch_ol.c libtwamr/pitch_ol.h
diffstat 4 files changed, 409 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/libtwamr/Makefile	Tue May 07 02:06:47 2024 +0000
+++ b/libtwamr/Makefile	Tue May 07 03:01:01 2024 +0000
@@ -10,13 +10,13 @@
 	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 lflg_upd.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 ph_disp.o pitch_fr.o post_pro.o\
-	pow2.o pre_big.o pre_proc.o pred_lt.o preemph.o prm2bits.o prmno.o \
-	pstfilt.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 \
-	r_fft.o reorder.o residu.o s10_8pf.o set_sign.o sid_sync.o spreproc.o \
-	spstproc.o sqrt_l.o syn_filt.o tls_flags.o ton_stab.o vad1.o vad2.o \
-	vad_reset.o weight_a.o window.o
+	lsp_lsf.o lsp_tab.o mac_32.o oper_32b.o ph_disp.o pitch_fr.o pitch_ol.o\
+	post_pro.o pow2.o pre_big.o pre_proc.o pred_lt.o preemph.o prm2bits.o \
+	prmno.o pstfilt.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 r_fft.o reorder.o residu.o s10_8pf.o set_sign.o \
+	sid_sync.o spreproc.o spstproc.o sqrt_l.o syn_filt.o tls_flags.o \
+	ton_stab.o vad1.o vad2.o vad_reset.o weight_a.o window.o
 HDRS=	a_refl.h agc.h autocorr.h az_lsp.h b_cn_cod.h basic_op.h bgnscd.h \
 	bitno.h bits2prm.h c1035pf.h c2_11pf.h c2_9pf.h c3_14pf.h c4_17pf.h \
 	c8_31pf.h c_g_aver.h calc_cor.h calc_en.h cbsearch.h cl_ltp.h cnst.h \
@@ -28,10 +28,10 @@
 	int_lpc.h int_lsf.h inter_36.h inv_sqrt.h lag_wind.h levinson.h log2.h \
 	lpc.h lsfwt.h lsp.h lsp_avg.h lsp_az.h lsp_lsf.h lsp_tab.h mac_32.h \
 	memops.h namespace.h no_count.h oper_32b.h ph_disp.h pitch_fr.h \
-	post_pro.h pow2.h pre_big.h pre_proc.h pred_lt.h preemph.h prm2bits.h \
-	pstfilt.h q_gain_c.h q_gain_p.h q_plsf.h q_plsf3_tab.h q_plsf5_tab.h \
-	qgain475.h qgain795.h qua_gain.h qua_gain_tab.h reorder.h residu.h \
-	s10_8pf.h set_sign.h sid_sync.h spreproc.h spstproc.h sqrt_l.h \
+	pitch_ol.h post_pro.h pow2.h pre_big.h pre_proc.h pred_lt.h preemph.h \
+	prm2bits.h pstfilt.h q_gain_c.h q_gain_p.h q_plsf.h q_plsf3_tab.h \
+	q_plsf5_tab.h qgain475.h qgain795.h qua_gain.h qua_gain_tab.h reorder.h\
+	residu.h s10_8pf.h set_sign.h sid_sync.h spreproc.h spstproc.h sqrt_l.h\
 	syn_filt.h ton_stab.h tw_amr.h typedef.h vad.h vad1.h vad2.h weight_a.h\
 	window.h
 LIB=	libtwamr.a
--- a/libtwamr/namespace.list	Tue May 07 02:06:47 2024 +0000
+++ b/libtwamr/namespace.list	Tue May 07 03:01:01 2024 +0000
@@ -27,7 +27,7 @@
 Int_lsf Interpol_3or6
 Lag_window Levinson Levinson_reset
 Lsf_lsp Lsp_lsf Reorder_lsf Lsf_wt Lsp_Az
-Pitch_fr Pitch_fr_reset
+Pitch_fr Pitch_fr_reset Pitch_ol
 Pre_Process Pre_Process_reset Pred_lt_3or6
 Post_Filter Post_Filter_reset Post_Process Post_Process_reset
 Q_plsf_reset Q_plsf_3 Q_plsf_5 Qua_gain
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtwamr/pitch_ol.c	Tue May 07 03:01:01 2024 +0000
@@ -0,0 +1,347 @@
+/*
+********************************************************************************
+*
+*      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             : pitch_ol.c
+*      Purpose          : Compute the open loop pitch lag.
+*
+********************************************************************************
+*/
+/*
+********************************************************************************
+*                         MODULE INCLUDE FILE AND VERSION ID
+********************************************************************************
+*/
+#include "namespace.h"
+#include "pitch_ol.h"
+/*
+********************************************************************************
+*                         INCLUDE FILES
+********************************************************************************
+*/
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "no_count.h"
+#include "cnst.h"
+#include "inv_sqrt.h"
+#include "vad.h"
+#include "calc_cor.h"
+#include "hp_max.h"
+ 
+/*
+********************************************************************************
+*                         LOCAL VARIABLES AND TABLES
+********************************************************************************
+*/
+#define THRESHOLD 27853
+
+/*
+********************************************************************************
+*                         LOCAL PROGRAM CODE
+********************************************************************************
+*/
+/*************************************************************************
+ *
+ *  FUNCTION:  Lag_max
+ *
+ *  PURPOSE: Find the lag that has maximum correlation of scal_sig[] in a
+ *           given delay range.
+ *
+ *  DESCRIPTION:
+ *      The correlation is given by
+ *           cor[t] = <scal_sig[n],scal_sig[n-t]>,  t=lag_min,...,lag_max
+ *      The functions outputs the maximum correlation after normalization
+ *      and the corresponding lag.
+ *
+ *************************************************************************/
+static Word16 Lag_max ( /* o   : lag found                               */
+    vadState *vadSt,    /* i/o : VAD state struct                        */
+    Word32 corr[],      /* i   : correlation vector.                     */
+    Word16 scal_sig[],  /* i   : scaled signal.                          */    
+    Word16 scal_fac,    /* i   : scaled signal factor.                   */
+    Word16 scal_flag,   /* i   : if 1 use EFR compatible scaling         */
+    Word16 L_frame,     /* i   : length of frame to compute pitch        */
+    Word16 lag_max,     /* i   : maximum lag                             */
+    Word16 lag_min,     /* i   : minimum lag                             */
+    Word16 *cor_max,    /* o   : normalized correlation of selected lag  */
+    Word32 *rmax,       /* o   : max(<s[i]*s[j]>)                        */
+    Word32 *r0,         /* o   : residual energy                         */
+    Flag dtx            /* i   : dtx flag; use dtx=1, do not use dtx=0   */
+    )
+{
+    Word16 i, j;
+    Word16 *p;
+    Word32 max, t0;
+    Word16 max_h, max_l, ener_h, ener_l;
+    Word16 p_max = 0; /* initialization only needed to keep gcc silent */
+    
+    max = MIN_32;               move32 (); 
+    p_max = lag_max;            move16 ();
+   
+    for (i = lag_max, j = (PIT_MAX-lag_max-1); i >= lag_min; i--, j--)  
+    {
+       test ();  
+       if (L_sub (corr[-i], max) >= 0) 
+       { 
+          max = corr[-i];       move32 ();  
+          p_max = i;            move16 ();  
+       } 
+    }
+    
+    /* compute energy */
+
+    t0 = 0;                     move32 ();     
+    p = &scal_sig[-p_max];      move16 (); 
+    for (i = 0; i < L_frame; i++, p++)
+    {
+        t0 = L_mac (t0, *p, *p);
+    }
+    /* 1/sqrt(energy) */
+
+    if (dtx)
+    {  /* no test() call since this if is only in simulation env */
+       *rmax = max;		move32();
+       *r0 = t0;		move32();
+       /* check tone */
+       if (!vadSt->use_vad2)
+           vad_tone_detection (&vadSt->u.v1, max, t0);
+    }
+    
+    t0 = Inv_sqrt (t0); move32 (); /* function result */
+
+    test();
+    if (scal_flag)
+    {
+       t0 = L_shl (t0, 1);
+    }
+    
+    /* max = max/sqrt(energy)  */
+
+    L_Extract (max, &max_h, &max_l);
+    L_Extract (t0, &ener_h, &ener_l);
+
+    t0 = Mpy_32 (max_h, max_l, ener_h, ener_l);
+    
+    test();
+    if (scal_flag)
+    {
+      t0 = L_shr (t0, scal_fac);
+      *cor_max = extract_h (L_shl (t0, 15)); /* divide by 2 */
+    }
+    else
+    {
+      *cor_max = extract_l(t0);
+    }
+
+    return (p_max);
+}
+
+/*
+********************************************************************************
+*                         PUBLIC PROGRAM CODE
+********************************************************************************
+*/
+/*************************************************************************
+ *
+ *  FUNCTION:  Pitch_ol
+ *
+ *  PURPOSE: Compute the open loop pitch lag.
+ *
+ *  DESCRIPTION:
+ *      The open-loop pitch lag is determined based on the perceptually
+ *      weighted speech signal. This is done in the following steps:
+ *        - find three maxima of the correlation <sw[n],sw[n-T]>,
+ *          dividing the search range into three parts:
+ *               pit_min ... 2*pit_min-1
+ *             2*pit_min ... 4*pit_min-1
+ *             4*pit_min ...   pit_max
+ *        - divide each maximum by <sw[n-t], sw[n-t]> where t is the delay at
+ *          that maximum correlation.
+ *        - select the delay of maximum normalized correlation (among the
+ *          three candidates) while favoring the lower delay ranges.
+ *
+ *************************************************************************/
+Word16 Pitch_ol (      /* o   : open loop pitch lag                         */
+    vadState *vadSt,   /* i/o : VAD state struct                            */
+    enum Mode mode,    /* i   : coder mode                                  */
+    Word16 signal[],   /* i   : signal used to compute the open loop pitch  */
+                       /*    signal[-pit_max] to signal[-1] should be known */
+    Word16 pit_min,    /* i   : minimum pitch lag                           */
+    Word16 pit_max,    /* i   : maximum pitch lag                           */
+    Word16 L_frame,    /* i   : length of frame to compute pitch            */
+    Word16 idx,        /* i   : frame index                                 */
+    Flag dtx           /* i   : dtx flag; use dtx=1, do not use dtx=0       */
+    )
+{
+    Word16 i, j;
+    Word16 max1, max2, max3;
+    Word16 p_max1, p_max2, p_max3;
+    Word16 scal_flag = 0;
+    Word32 t0;
+    Word32  r01, r02, r03;
+    Word32  rmax1, rmax2, rmax3;
+    Word16 corr_hp_max;
+    Word32 corr[PIT_MAX+1], *corr_ptr;
+
+    /* Scaled signal */
+
+    Word16 scaled_signal[L_FRAME + PIT_MAX];
+    Word16 *scal_sig, scal_fac;
+
+    if (dtx && !vadSt->use_vad2)
+    {  /* no test() call since this if is only in simulation env */
+       /* update tone detection */
+       test(); test();
+       if ((sub(mode, MR475) == 0) || (sub(mode, MR515) == 0))
+       {
+          vad_tone_detection_update (&vadSt->u.v1, 1);
+       }
+       else
+       {
+          vad_tone_detection_update (&vadSt->u.v1, 0);
+       }
+    }
+
+    scal_sig = &scaled_signal[pit_max]; move16 (); 
+
+    t0 = 0L;                            move32 (); 
+    for (i = -pit_max; i < L_frame; i++)
+    {
+        t0 = L_mac (t0, signal[i], signal[i]);
+    }
+   
+    /*--------------------------------------------------------*
+     * Scaling of input signal.                               *
+     *                                                        *
+     *   if Overflow        -> scal_sig[i] = signal[i]>>3     *
+     *   else if t0 < 1^20  -> scal_sig[i] = signal[i]<<3     *
+     *   else               -> scal_sig[i] = signal[i]        *
+     *--------------------------------------------------------*/
+
+    /*--------------------------------------------------------*
+     *  Verification for risk of overflow.                    *
+     *--------------------------------------------------------*/
+
+    test ();
+    if (L_sub (t0, MAX_32) == 0L)               /* Test for overflow */
+    {
+        for (i = -pit_max; i < L_frame; i++)
+        {
+            scal_sig[i] = shr (signal[i], 3);   move16 (); 
+        }
+        scal_fac = 3;                           move16 (); 
+    }
+    else if (L_sub (t0, (Word32) 1048576L) < (Word32) 0)
+        /* if (t0 < 2^20) */
+    {
+		test (); 
+        for (i = -pit_max; i < L_frame; i++)
+        {
+            scal_sig[i] = shl (signal[i], 3);   move16 (); 
+        }
+        scal_fac = -3;                          move16 (); 
+    }
+    else
+    {
+		test (); 
+        for (i = -pit_max; i < L_frame; i++)
+        {
+            scal_sig[i] = signal[i];            move16 (); 
+        }
+        scal_fac = 0;                           move16 (); 
+    }
+
+    /* calculate all coreelations of scal_sig, from pit_min to pit_max */
+    corr_ptr = &corr[pit_max];                  move32 ();
+    comp_corr (scal_sig, L_frame, pit_max, pit_min, corr_ptr); 
+    
+    /*--------------------------------------------------------------------*
+     *  The pitch lag search is divided in three sections.                *
+     *  Each section cannot have a pitch multiple.                        *
+     *  We find a maximum for each section.                               *
+     *  We compare the maximum of each section by favoring small lags.    *
+     *                                                                    *
+     *  First section:  lag delay = pit_max     downto 4*pit_min          *
+     *  Second section: lag delay = 4*pit_min-1 downto 2*pit_min          *
+     *  Third section:  lag delay = 2*pit_min-1 downto pit_min            *
+     *--------------------------------------------------------------------*/
+
+    /* mode dependent scaling in Lag_max */
+    test (); 
+    if (sub(mode, MR122) == 0)
+    {
+       scal_flag = 1;                           move16 (); 
+    }
+    else
+    {
+       scal_flag = 0;                           move16 ();    
+    } 
+    
+    j = shl (pit_min, 2);
+    p_max1 = Lag_max (vadSt, corr_ptr, scal_sig, scal_fac, scal_flag, L_frame,
+                      pit_max, j, &max1, &rmax1, &r01, dtx);
+
+    i = sub (j, 1);
+    j = shl (pit_min, 1);
+    p_max2 = Lag_max (vadSt, corr_ptr, scal_sig, scal_fac, scal_flag, L_frame,
+                      i, j, &max2, &rmax2, &r02, dtx);
+
+    i = sub (j, 1);
+    p_max3 = Lag_max (vadSt, corr_ptr, scal_sig, scal_fac, scal_flag, L_frame,
+                      i, pit_min, &max3, &rmax3, &r03, dtx);
+
+    if (dtx && !vadSt->use_vad2)
+    {  /* no test() call since this if is only in simulation env */
+       test ();
+       if (sub(idx, 1) == 0)
+       {
+          /* calculate max high-passed filtered correlation of all lags */
+          hp_max (corr_ptr, scal_sig, L_frame, pit_max, pit_min, &corr_hp_max); 
+          
+          /* update complex background detector */
+          vad_complex_detection_update(&vadSt->u.v1, corr_hp_max);
+       }
+    }
+
+    /*--------------------------------------------------------------------*
+     * Compare the 3 sections maximum, and favor small lag.               *
+     *--------------------------------------------------------------------*/
+    
+    test (); 
+    if (sub (mult (max1, THRESHOLD), max2) < 0)
+    {
+        max1 = max2;                       move16 (); 
+        p_max1 = p_max2;                   move16 (); 
+        if (dtx)
+        {
+            rmax1 = rmax2;                 move32 ();
+            r01 = r02;                     move32 ();
+        }
+    }
+    test (); 
+    if (sub (mult (max1, THRESHOLD), max3) < 0)
+    {
+        p_max1 = p_max3;                   move16 (); 
+        if (dtx)
+        {
+            rmax1 = rmax3;                 move32 ();
+            r01 = r03;                     move32 ();
+        }
+    }
+
+    if (dtx && vadSt->use_vad2)
+    {
+        /* Save max correlation */
+        vadSt->u.v2.L_Rmax = L_add(vadSt->u.v2.L_Rmax, rmax1);
+        /* Save max energy */
+        vadSt->u.v2.L_R0 =   L_add(vadSt->u.v2.L_R0, r01);
+    }
+
+    return (p_max1);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtwamr/pitch_ol.h	Tue May 07 03:01:01 2024 +0000
@@ -0,0 +1,50 @@
+/*
+********************************************************************************
+*
+*      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             : pitch_ol.h
+*      Purpose          : Compute the open loop pitch lag.
+*
+********************************************************************************
+*/
+#ifndef pitch_ol_h
+#define pitch_ol_h "$Id $"
+ 
+/*
+********************************************************************************
+*                         INCLUDE FILES
+********************************************************************************
+*/
+#include "tw_amr.h"
+#include "typedef.h"
+#include "vad.h"
+
+/*
+********************************************************************************
+*                         DEFINITION OF DATA TYPES
+********************************************************************************
+*/
+ 
+/*
+********************************************************************************
+*                         DECLARATION OF PROTOTYPES
+********************************************************************************
+*/
+Word16 Pitch_ol (      /* o   : open loop pitch lag                         */
+    vadState *vadSt,   /* i/o : VAD state struct                            */
+    enum Mode mode,    /* i   : coder mode                                  */
+    Word16 signal[],   /* i   : signal used to compute the open loop pitch  */
+                       /*    signal[-pit_max] to signal[-1] should be known */
+    Word16 pit_min,    /* i   : minimum pitch lag                           */
+    Word16 pit_max,    /* i   : maximum pitch lag                           */
+    Word16 L_frame,    /* i   : length of frame to compute pitch            */
+    Word16 idx,        /* i   : frame index                                 */
+    Flag dtx           /* i   : dtx flag; use dtx=1, do not use dtx=0       */
+    );
+ 
+#endif