changeset 373:128ec87489b6

libtwamr: integrate q_plsf_5.c
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 06 May 2024 04:03:21 +0000
parents 9cca139a20a8
children 61047a2912a2
files libtwamr/Makefile libtwamr/q_plsf_5.c
diffstat 2 files changed, 305 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/libtwamr/Makefile	Mon May 06 04:00:14 2024 +0000
+++ b/libtwamr/Makefile	Mon May 06 04:03:21 2024 +0000
@@ -9,8 +9,8 @@
 	enc_lag6.o ex_ctrl.o g_adapt.o g_code.o g_pitch.o gains_tab.o gc_pred.o\
 	gmed_n.o graytab.o inv_sqrt.o log2.o lsfwt.o lsp_lsf.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 qua_gain_tab.o reorder.o s10_8pf.o set_sign.o \
-	sqrt_l.o tls_flags.o window.o
+	q_plsf5_tab.o q_plsf_3.o q_plsf_5.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
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtwamr/q_plsf_5.c	Mon May 06 04:03:21 2024 +0000
@@ -0,0 +1,303 @@
+/*
+********************************************************************************
+*
+*      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             : q_plsf_5.c
+*      Purpose          : Quantization of 2 sets of LSF parameters using 1st 
+*                         order MA prediction and split by 5 matrix
+*                         quantization (split-MQ)
+*
+********************************************************************************
+*/
+ 
+/*
+********************************************************************************
+*                         MODULE INCLUDE FILE AND VERSION ID
+********************************************************************************
+*/
+#include "namespace.h"
+#include "q_plsf.h"
+ 
+/*
+********************************************************************************
+*                         INCLUDE FILES
+********************************************************************************
+*/
+#include "typedef.h"
+#include "basic_op.h"
+#include "no_count.h"
+#include "lsp_lsf.h"
+#include "reorder.h"
+#include "lsfwt.h"
+#include "q_plsf5_tab.h"
+
+/*
+********************************************************************************
+*                         LOCAL PROGRAM CODE
+********************************************************************************
+*/
+/* Quantization of a 4 dimensional subvector */
+
+static Word16 Vq_subvec (/* o : quantization index,            Q0  */
+    Word16 *lsf_r1,      /* i : 1st LSF residual vector,       Q15 */
+    Word16 *lsf_r2,      /* i : 2nd LSF residual vector,       Q15 */
+    const Word16 *dico,  /* i : quantization codebook,         Q15 */
+    Word16 *wf1,         /* i : 1st LSF weighting factors      Q13 */
+    Word16 *wf2,         /* i : 2nd LSF weighting factors      Q13 */  
+    Word16 dico_size     /* i : size of quantization codebook, Q0  */
+)
+{
+    Word16 index = 0; /* initialization only needed to keep gcc silent */
+    Word16 i, temp;
+    const Word16 *p_dico;
+    Word32 dist_min, dist;
+
+    dist_min = MAX_32;                                  move32 (); 
+    p_dico = dico;                                      move16 (); 
+
+    for (i = 0; i < dico_size; i++)
+    {
+        temp = sub (lsf_r1[0], *p_dico++);
+        temp = mult (wf1[0], temp);
+        dist = L_mult (temp, temp);
+
+        temp = sub (lsf_r1[1], *p_dico++);
+        temp = mult (wf1[1], temp);
+        dist = L_mac (dist, temp, temp);
+
+        temp = sub (lsf_r2[0], *p_dico++);
+        temp = mult (wf2[0], temp);
+        dist = L_mac (dist, temp, temp);
+
+        temp = sub (lsf_r2[1], *p_dico++);
+        temp = mult (wf2[1], temp);
+        dist = L_mac (dist, temp, temp);
+
+        test (); 
+        if (L_sub (dist, dist_min) < (Word32) 0)
+        {
+            dist_min = dist;                            move32 (); 
+            index = i;                                  move16 (); 
+        }
+    }
+
+    /* Reading the selected vector */
+
+    p_dico = &dico[shl (index, 2)];                     move16 (); 
+    lsf_r1[0] = *p_dico++;                              move16 (); 
+    lsf_r1[1] = *p_dico++;                              move16 (); 
+    lsf_r2[0] = *p_dico++;                              move16 (); 
+    lsf_r2[1] = *p_dico++;                              move16 (); 
+
+    return index;
+}
+
+/* Quantization of a 4 dimensional subvector with a signed codebook */
+
+static Word16 Vq_subvec_s ( /* o : quantization index            Q0  */
+    Word16 *lsf_r1,         /* i : 1st LSF residual vector       Q15 */
+    Word16 *lsf_r2,         /* i : and LSF residual vector       Q15 */
+    const Word16 *dico,     /* i : quantization codebook         Q15 */
+    Word16 *wf1,            /* i : 1st LSF weighting factors     Q13 */
+    Word16 *wf2,            /* i : 2nd LSF weighting factors     Q13 */
+    Word16 dico_size)       /* i : size of quantization codebook Q0  */  
+{
+    Word16 index = 0;  /* initialization only needed to keep gcc silent */
+    Word16 sign = 0;   /* initialization only needed to keep gcc silent */
+    Word16 i, temp;
+    const Word16 *p_dico;
+    Word32 dist_min, dist;
+
+    dist_min = MAX_32;                                  move32 (); 
+    p_dico = dico;                                      move16 (); 
+
+    for (i = 0; i < dico_size; i++)
+    {
+        /* test positive */
+
+        temp = sub (lsf_r1[0], *p_dico++);
+        temp = mult (wf1[0], temp);
+        dist = L_mult (temp, temp);
+
+        temp = sub (lsf_r1[1], *p_dico++);
+        temp = mult (wf1[1], temp);
+        dist = L_mac (dist, temp, temp);
+
+        temp = sub (lsf_r2[0], *p_dico++);
+        temp = mult (wf2[0], temp);
+        dist = L_mac (dist, temp, temp);
+
+        temp = sub (lsf_r2[1], *p_dico++);
+        temp = mult (wf2[1], temp);
+        dist = L_mac (dist, temp, temp);
+
+        test (); 
+        if (L_sub (dist, dist_min) < (Word32) 0)
+        {
+            dist_min = dist;                            move32 (); 
+            index = i;                                  move16 (); 
+            sign = 0;                                   move16 (); 
+        }
+        /* test negative */
+
+        p_dico -= 4;                                    move16 (); 
+        temp = add (lsf_r1[0], *p_dico++);
+        temp = mult (wf1[0], temp);
+        dist = L_mult (temp, temp);
+
+        temp = add (lsf_r1[1], *p_dico++);
+        temp = mult (wf1[1], temp);
+        dist = L_mac (dist, temp, temp);
+
+        temp = add (lsf_r2[0], *p_dico++);
+        temp = mult (wf2[0], temp);
+        dist = L_mac (dist, temp, temp);
+
+        temp = add (lsf_r2[1], *p_dico++);
+        temp = mult (wf2[1], temp);
+        dist = L_mac (dist, temp, temp);
+
+        test (); 
+        if (L_sub (dist, dist_min) < (Word32) 0)
+        {
+            dist_min = dist;                            move32 (); 
+            index = i;                                  move16 (); 
+            sign = 1;                                   move16 (); 
+        }
+    }
+
+    /* Reading the selected vector */
+
+    p_dico = &dico[shl (index, 2)];                     move16 (); 
+    test (); 
+    if (sign == 0)
+    {
+        lsf_r1[0] = *p_dico++;                          move16 (); 
+        lsf_r1[1] = *p_dico++;                          move16 (); 
+        lsf_r2[0] = *p_dico++;                          move16 (); 
+        lsf_r2[1] = *p_dico++;                          move16 (); 
+    }
+    else
+    {
+        lsf_r1[0] = negate (*p_dico++);                 move16 (); 
+        lsf_r1[1] = negate (*p_dico++);                 move16 (); 
+        lsf_r2[0] = negate (*p_dico++);                 move16 (); 
+        lsf_r2[1] = negate (*p_dico++);                 move16 (); 
+    }
+
+    index = shl (index, 1);
+    index = add (index, sign);
+
+    return index;
+}
+
+/*
+********************************************************************************
+*                         PUBLIC PROGRAM CODE
+********************************************************************************
+*/
+ 
+/*************************************************************************
+ *   FUNCTION:  Q_plsf_5()
+ *
+ *   PURPOSE:  Quantization of 2 sets of LSF parameters using 1st order MA
+ *             prediction and split by 5 matrix quantization (split-MQ)
+ *
+ *   DESCRIPTION:
+ *
+ *        p[i] = pred_factor*past_rq[i];   i=0,...,m-1
+ *        r1[i]= lsf1[i] - p[i];           i=0,...,m-1
+ *        r2[i]= lsf2[i] - p[i];           i=0,...,m-1
+ *   where:
+ *        lsf1[i]           1st mean-removed LSF vector.
+ *        lsf2[i]           2nd mean-removed LSF vector.
+ *        r1[i]             1st residual prediction vector.
+ *        r2[i]             2nd residual prediction vector.
+ *        past_r2q[i]       Past quantized residual (2nd vector).
+ *
+ *   The residual vectors r1[i] and r2[i] are jointly quantized using
+ *   split-MQ with 5 codebooks. Each 4th dimension submatrix contains 2
+ *   elements from each residual vector. The 5 submatrices are as follows:
+ *     {r1[0], r1[1], r2[0], r2[1]};  {r1[2], r1[3], r2[2], r2[3]};
+ *     {r1[4], r1[5], r2[4], r2[5]};  {r1[6], r1[7], r2[6], r2[7]};
+ *                    {r1[8], r1[9], r2[8], r2[9]};
+ *
+ *************************************************************************/
+void Q_plsf_5 (
+    Q_plsfState *st,
+    Word16 *lsp1,      /* i : 1st LSP vector,                     Q15 */
+    Word16 *lsp2,      /* i : 2nd LSP vector,                     Q15 */   
+    Word16 *lsp1_q,    /* o : quantized 1st LSP vector,           Q15 */
+    Word16 *lsp2_q,    /* o : quantized 2nd LSP vector,           Q15 */
+    Word16 *indice     /* o : quantization indices of 5 matrices, Q0  */
+)
+{
+    Word16 i;
+    Word16 lsf1[M], lsf2[M], wf1[M], wf2[M], lsf_p[M], lsf_r1[M], lsf_r2[M];
+    Word16 lsf1_q[M], lsf2_q[M];
+
+    /* convert LSFs to normalize frequency domain 0..16384  */
+
+    Lsp_lsf (lsp1, lsf1, M);
+    Lsp_lsf (lsp2, lsf2, M);
+
+    /* Compute LSF weighting factors (Q13) */
+    
+    Lsf_wt (lsf1, wf1);
+    Lsf_wt (lsf2, wf2);
+
+    /* Compute predicted LSF and prediction error */
+
+    for (i = 0; i < M; i++)
+    {
+        lsf_p[i] = add (mean_lsf[i], mult (st->past_rq[i], LSP_PRED_FAC_MR122));
+        move16 (); 
+        lsf_r1[i] = sub (lsf1[i], lsf_p[i]);           move16 (); 
+        lsf_r2[i] = sub (lsf2[i], lsf_p[i]);           move16 (); 
+    }
+
+    /*---- Split-MQ of prediction error ----*/
+
+    indice[0] = Vq_subvec (&lsf_r1[0], &lsf_r2[0], dico1_lsf,
+                           &wf1[0], &wf2[0], DICO1_SIZE);
+                                                        move16 (); 
+
+    indice[1] = Vq_subvec (&lsf_r1[2], &lsf_r2[2], dico2_lsf,
+                           &wf1[2], &wf2[2], DICO2_SIZE);
+                                                        move16 (); 
+
+    indice[2] = Vq_subvec_s (&lsf_r1[4], &lsf_r2[4], dico3_lsf,
+                             &wf1[4], &wf2[4], DICO3_SIZE);
+                                                        move16 (); 
+
+    indice[3] = Vq_subvec (&lsf_r1[6], &lsf_r2[6], dico4_lsf,
+                           &wf1[6], &wf2[6], DICO4_SIZE);
+                                                        move16 (); 
+
+    indice[4] = Vq_subvec (&lsf_r1[8], &lsf_r2[8], dico5_lsf,
+                           &wf1[8], &wf2[8], DICO5_SIZE);
+                                                        move16 (); 
+
+    /* Compute quantized LSFs and update the past quantized residual */
+    for (i = 0; i < M; i++)
+    {
+        lsf1_q[i] = add (lsf_r1[i], lsf_p[i]);          move16 (); 
+        lsf2_q[i] = add (lsf_r2[i], lsf_p[i]);          move16 (); 
+        st->past_rq[i] = lsf_r2[i];                     move16 (); 
+    }
+
+    /* verification that LSFs has minimum distance of LSF_GAP */
+
+    Reorder_lsf (lsf1_q, LSF_GAP, M);
+    Reorder_lsf (lsf2_q, LSF_GAP, M);
+
+    /*  convert LSFs to the cosine domain */
+    
+    Lsf_lsp (lsf1_q, lsp1_q, M);
+    Lsf_lsp (lsf2_q, lsp2_q, M);
+}