changeset 253:54f6bc41ed10

libtwamr: integrate a* modules
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 05 Apr 2024 06:08:15 +0000
parents 57b4053559ff
children f931e704adc5
files libtwamr/Makefile libtwamr/a_refl.c libtwamr/a_refl.h libtwamr/agc.c libtwamr/agc.h libtwamr/autocorr.c libtwamr/autocorr.h libtwamr/az_lsp.c libtwamr/az_lsp.h libtwamr/grid.tab libtwamr/inv_sqrt.c libtwamr/inv_sqrt.h libtwamr/inv_sqrt.tab libtwamr/namespace.h libtwamr/no_count.h libtwamr/oper_32b.c libtwamr/oper_32b.h
diffstat 17 files changed, 1605 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/libtwamr/Makefile	Fri Apr 05 01:02:23 2024 +0000
+++ b/libtwamr/Makefile	Fri Apr 05 06:08:15 2024 +0000
@@ -1,7 +1,7 @@
 CC=	gcc
 CFLAGS=	-O2
-OBJS=	basicop2.o tls_flags.o
-HDRS=	basic_op.h cnst.h int_defs.h namespace.h tw_amr.h typedef.h
+OBJS=	a_refl.o agc.o autocorr.o az_lsp.o basicop2.o inv_sqrt.o oper_32b.o \
+	tls_flags.o
 LIB=	libtwamr.a
 
 INSTALL_PREFIX=	/usr/local
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtwamr/a_refl.c	Fri Apr 05 06:08:15 2024 +0000
@@ -0,0 +1,128 @@
+/*
+********************************************************************************
+*
+*      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             : a_refl.c
+*      Purpose          : Convert from direct form coefficients to 
+*                         reflection coefficients
+*
+********************************************************************************
+*/
+/*
+********************************************************************************
+*                         MODULE INCLUDE FILE AND VERSION ID
+********************************************************************************
+*/
+#include "namespace.h"
+#include "a_refl.h"
+const char a_refl_id[] = "@(#)$Id $" a_refl_h;
+ 
+
+/*
+********************************************************************************
+*                         INCLUDE FILES
+********************************************************************************
+*/
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "no_count.h"
+#include "cnst.h"
+
+/*
+********************************************************************************
+*                         LOCAL VARIABLES AND TABLES
+********************************************************************************
+*/
+
+/*
+********************************************************************************
+*                         PUBLIC PROGRAM CODE
+********************************************************************************
+*/
+/*
+**************************************************************************
+*
+*  Function    : A_Refl
+*
+**************************************************************************
+*/ 
+void A_Refl(
+   Word16 a[],	      /* i   : Directform coefficients */
+   Word16 refl[]      /* o   : Reflection coefficients */
+)
+{				       
+   /* local variables */
+   Word16 i,j;
+   Word16 aState[M];
+   Word16 bState[M];
+   Word16 normShift;
+   Word16 normProd;
+   Word32 L_acc;
+   Word16 scale;
+   Word32 L_temp;
+   Word16 temp;
+   Word16 mult;
+
+   /* initialize states */
+   for (i = 0; i < M; i++)
+   {
+      aState[i] = a[i];                         move16 ();
+   }
+   
+   /* backward Levinson recursion */
+   for (i = M-1; i >= 0; i--)
+   {
+      if (sub(abs_s(aState[i]), 4096) >= 0)
+      {
+         goto ExitRefl;
+      }
+      
+      refl[i] = shl(aState[i], 3);
+
+      L_temp = L_mult(refl[i], refl[i]);
+      L_acc = L_sub(MAX_32, L_temp);
+      
+      normShift = norm_l(L_acc);
+      scale = sub(15, normShift);
+      
+      L_acc = L_shl(L_acc, normShift);
+      normProd = round(L_acc);
+
+      mult = div_s(16384, normProd);
+      
+      for (j = 0; j < i; j++)
+      {
+         L_acc = L_deposit_h(aState[j]);
+         L_acc = L_msu(L_acc, refl[i], aState[i-j-1]);
+         
+         temp = round(L_acc);
+         L_temp = L_mult(mult, temp);
+         L_temp = L_shr_r(L_temp, scale);
+         
+         if (L_sub(L_abs(L_temp), 32767) > 0)
+         {
+            goto ExitRefl;
+         }
+         
+         bState[j] = extract_l(L_temp);
+      }
+      
+      for (j = 0; j < i; j++)
+      {
+         aState[j] = bState[j];              move16 ();
+      }
+   }
+   return;
+
+ExitRefl:
+   for (i = 0; i < M; i++)
+   {
+      refl[i] = 0;                           move16 ();
+   }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtwamr/a_refl.h	Fri Apr 05 06:08:15 2024 +0000
@@ -0,0 +1,54 @@
+/*
+********************************************************************************
+*
+*      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             : a_refl.h
+*      Purpose          : Convert from direct form coefficients to 
+*                         reflection coefficients
+*
+********************************************************************************
+*/
+#ifndef a_refl_h
+#define a_refl_h "$Id $"
+
+/*
+********************************************************************************
+*                         INCLUDE FILES
+********************************************************************************
+*/
+#include "typedef.h"
+
+/*
+********************************************************************************
+*                         DEFINITION OF DATA TYPES
+********************************************************************************
+*/
+
+/*
+********************************************************************************
+*                         DECLARATION OF PROTOTYPES
+********************************************************************************
+*/
+
+/*************************************************************************
+ *
+ *   FUNCTION:  A_Refl()
+ *
+ *   PURPOSE: Convert from direct form coefficients to reflection coefficients
+ *
+ *   DESCRIPTION:
+ *       Directform coeffs in Q12 are converted to 
+ *       reflection coefficients Q15 
+ *
+ *************************************************************************/
+void A_Refl(
+   Word16 a[],	      /* i   : Directform coefficients */
+   Word16 refl[]      /* o   : Reflection coefficients */
+);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtwamr/agc.c	Fri Apr 05 06:08:15 2024 +0000
@@ -0,0 +1,320 @@
+/*
+*****************************************************************************
+*
+*      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             : agc.c
+*
+*****************************************************************************
+*/
+
+/*
+*****************************************************************************
+*                         MODULE INCLUDE FILE AND VERSION ID
+*****************************************************************************
+*/
+#include "namespace.h"
+#include "agc.h"
+const char agc_id[] = "@(#)$Id $" agc_h;
+
+/*
+*****************************************************************************
+*                         INCLUDE FILES
+*****************************************************************************
+*/
+#include <stdlib.h>
+#include <stdio.h>
+#include "typedef.h"
+#include "basic_op.h"
+#include "no_count.h"
+#include "cnst.h"
+#include "inv_sqrt.h"
+ 
+/*
+*****************************************************************************
+*                         LOCAL VARIABLES AND TABLES
+*****************************************************************************
+*/
+
+/*
+*****************************************************************************
+*                         LOCAL PROGRAM CODE
+*****************************************************************************
+*/
+
+static Word32 energy_old( /* o : return energy of signal     */
+    Word16 in[],          /* i : input signal (length l_trm) */
+    Word16 l_trm          /* i : signal length               */
+)
+{
+    Word32 s;
+    Word16 i, temp;
+
+    temp = shr (in[0], 2);
+    s = L_mult (temp, temp);
+    
+    for (i = 1; i < l_trm; i++)
+    {
+        temp = shr (in[i], 2);
+        s = L_mac (s, temp, temp);
+    }
+
+    return s;
+}
+
+static Word32 energy_new( /* o : return energy of signal     */
+    Word16 in[],          /* i : input signal (length l_trm) */
+    Word16 l_trm          /* i : signal length               */
+)
+{
+    Word32 s;
+    Word16 i;
+    Flag ov_save;
+
+    ov_save = Overflow; move16 (); /* save overflow flag in case energy_old */
+                                   /* must be called                        */
+    s = L_mult(in[0], in[0]);
+    for (i = 1; i < l_trm; i++)
+    {
+        s = L_mac(s, in[i], in[i]);
+    }
+    
+    /* check for overflow */
+    test (); 
+    if (L_sub (s, MAX_32) == 0L)
+    {
+        Overflow = ov_save; move16 (); /* restore overflow flag */
+        s = energy_old (in, l_trm); move32 (); /* function result */
+    }
+    else
+    {
+       s = L_shr(s, 4);
+    }
+
+    return s;
+}
+/*
+*****************************************************************************
+*                         PUBLIC PROGRAM CODE
+*****************************************************************************
+*/
+/*
+**************************************************************************
+*
+*  Function    : agc_init
+*  Purpose     : Allocates memory for agc state and initializes
+*                state memory
+*
+**************************************************************************
+*/
+int agc_init (agcState **state)
+{
+  agcState* s;
+ 
+  if (state == (agcState **) NULL){
+      fprintf(stderr, "agc_init: invalid parameter\n");
+      return -1;
+  }
+  *state = NULL;
+ 
+  /* allocate memory */
+  if ((s= (agcState *) malloc(sizeof(agcState))) == NULL){
+      fprintf(stderr, "agc_init: can not malloc state structure\n");
+      return -1;
+  }
+  
+  agc_reset(s);
+  *state = s;
+  
+  return 0;
+}
+ 
+/*
+**************************************************************************
+*
+*  Function    : agc_reset
+*  Purpose     : Reset of agc (i.e. set state memory to 1.0)
+*
+**************************************************************************
+*/
+int agc_reset (agcState *state)
+{
+  if (state == (agcState *) NULL){
+      fprintf(stderr, "agc_reset: invalid parameter\n");
+      return -1;
+  }
+  
+  state->past_gain = 4096;   /* initial value of past_gain = 1.0  */
+  
+  return 0;
+}
+ 
+/*
+**************************************************************************
+*
+*  Function    : agc_exit
+*  Purpose     : The memory used for state memory is freed
+*
+**************************************************************************
+*/
+void agc_exit (agcState **state)
+{
+  if (state == NULL || *state == NULL)
+      return;
+ 
+  /* deallocate memory */
+  free(*state);
+  *state = NULL;
+  
+  return;
+}
+ 
+/*
+**************************************************************************
+*
+*  Function    : agc
+*  Purpose     : Scales the postfilter output on a subframe basis
+*
+**************************************************************************
+*/
+int agc (
+    agcState *st,      /* i/o : agc state                        */
+    Word16 *sig_in,    /* i   : postfilter input signal  (l_trm) */
+    Word16 *sig_out,   /* i/o : postfilter output signal (l_trm) */
+    Word16 agc_fac,    /* i   : AGC factor                       */
+    Word16 l_trm       /* i   : subframe size                    */
+)
+{
+    Word16 i, exp;
+    Word16 gain_in, gain_out, g0, gain;
+    Word32 s;
+            
+    /* calculate gain_out with exponent */
+    s = energy_new(sig_out, l_trm); move32 (); /* function result */
+        
+    test (); 
+    if (s == 0)
+    {
+        st->past_gain = 0;          move16 (); 
+        return 0;
+    }
+    exp = sub (norm_l (s), 1);
+    gain_out = round (L_shl (s, exp));
+
+    /* calculate gain_in with exponent */
+    s = energy_new(sig_in, l_trm);   move32 (); /* function result */
+    
+    test (); 
+    if (s == 0)
+    {
+        g0 = 0;                 move16 (); 
+    }
+    else
+    {
+        i = norm_l (s);
+        gain_in = round (L_shl (s, i));
+        exp = sub (exp, i);
+
+        /*---------------------------------------------------*
+         *  g0 = (1-agc_fac) * sqrt(gain_in/gain_out);       *
+         *---------------------------------------------------*/
+
+        s = L_deposit_l (div_s (gain_out, gain_in));
+        s = L_shl (s, 7);       /* s = gain_out / gain_in */
+        s = L_shr (s, exp);     /* add exponent */
+
+        s = Inv_sqrt (s); move32 (); /* function result */
+        i = round (L_shl (s, 9));
+
+        /* g0 = i * (1-agc_fac) */
+        g0 = mult (i, sub (32767, agc_fac));
+    }
+
+    /* compute gain[n] = agc_fac * gain[n-1]
+                        + (1-agc_fac) * sqrt(gain_in/gain_out) */
+    /* sig_out[n] = gain[n] * sig_out[n]                        */
+
+    gain = st->past_gain;           move16 (); 
+
+    for (i = 0; i < l_trm; i++)
+    {
+        gain = mult (gain, agc_fac);
+        gain = add (gain, g0);
+        sig_out[i] = extract_h (L_shl (L_mult (sig_out[i], gain), 3));
+                                move16 (); 
+    }
+
+    st->past_gain = gain;           move16 (); 
+
+    return 0;
+}
+
+/*
+**************************************************************************
+*
+*  Function    : agc2
+*  Purpose     : Scales the excitation on a subframe basis
+*
+**************************************************************************
+*/
+void agc2 (
+ Word16 *sig_in,        /* i   : postfilter input signal  */
+ Word16 *sig_out,       /* i/o : postfilter output signal */
+ Word16 l_trm           /* i   : subframe size            */
+)
+{
+    Word16 i, exp;
+    Word16 gain_in, gain_out, g0;
+    Word32 s;
+    
+    /* calculate gain_out with exponent */
+    s = energy_new(sig_out, l_trm);   move32 (); /* function result */
+        
+    test (); 
+    if (s == 0)
+    {
+        return;
+    }
+    exp = sub (norm_l (s), 1);
+    gain_out = round (L_shl (s, exp));
+
+    /* calculate gain_in with exponent */
+    s = energy_new(sig_in, l_trm);   move32 (); /* function result */
+    
+    test (); 
+    if (s == 0)
+    {
+        g0 = 0;                 move16 (); 
+    }
+    else
+    {
+        i = norm_l (s);
+        gain_in = round (L_shl (s, i));
+        exp = sub (exp, i);
+
+        /*---------------------------------------------------*
+         *  g0 = sqrt(gain_in/gain_out);                     *
+         *---------------------------------------------------*/
+
+        s = L_deposit_l (div_s (gain_out, gain_in));
+        s = L_shl (s, 7);       /* s = gain_out / gain_in */
+        s = L_shr (s, exp);     /* add exponent */
+
+        s = Inv_sqrt (s); move32 (); /* function result */
+        g0 = round (L_shl (s, 9));
+    }
+
+    /* sig_out(n) = gain(n) sig_out(n) */
+
+    for (i = 0; i < l_trm; i++)
+    {
+        sig_out[i] = extract_h (L_shl (L_mult (sig_out[i], g0), 3));
+                                move16 (); 
+    }
+
+    return;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtwamr/agc.h	Fri Apr 05 06:08:15 2024 +0000
@@ -0,0 +1,111 @@
+/*
+*****************************************************************************
+*
+*      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             : agc.h
+*      Purpose          : Scales the postfilter output on a subframe basis
+*                       : by automatic control of the subframe gain.
+*
+*****************************************************************************
+*/
+#ifndef agc_h
+#define agc_h "$Id $"
+ 
+/*
+*****************************************************************************
+*                         INCLUDE FILES
+*****************************************************************************
+*/
+#include "typedef.h"
+ 
+/*
+*****************************************************************************
+*                         DEFINITION OF DATA TYPES
+*****************************************************************************
+*/
+typedef struct {
+    Word16 past_gain;
+} agcState;
+
+/*
+*****************************************************************************
+*                         DECLARATION OF PROTOTYPES
+*****************************************************************************
+*/
+/*
+**************************************************************************
+*
+*  Function    : agc_init
+*  Purpose     : Allocates memory for agc state and initializes
+*                state memory
+*  Description : Stores pointer to agc status struct in *st. This pointer
+*                has to be passed to agc in each call.
+*  Returns     : 0 on success
+*
+**************************************************************************
+*/
+int agc_init(agcState **st);
+
+/*
+**************************************************************************
+*
+*  Function    : agc_reset
+*  Purpose     : Reset of agc (i.e. set state memory to 1.0)
+*  Returns     : 0 on success
+*
+**************************************************************************
+*/
+int agc_reset (agcState *st);
+
+/*
+**************************************************************************
+*
+*  Function    : agc_exit
+*  Purpose     : The memory used for state memory is freed,
+*                de-initialize agc
+*
+**************************************************************************
+*/
+void agc_exit (agcState **st);
+
+/*
+**************************************************************************
+*
+*  Function    : agc
+*  Purpose     : Scales the postfilter output on a subframe basis
+*  Description : sig_out[n] = sig_out[n] * gain[n];
+*                where gain[n] is the gain at the nth sample given by
+*                gain[n] = agc_fac * gain[n-1] + (1 - agc_fac) g_in/g_out
+*                g_in/g_out is the square root of the ratio of energy at 
+*                the input and output of the postfilter.
+*
+**************************************************************************
+*/
+int agc (
+    agcState *st,      /* i/o : agc state                         */
+    Word16 *sig_in,    /* i   : postfilter input signal, (l_trm)  */
+    Word16 *sig_out,   /* i/o : postfilter output signal, (l_trm) */
+    Word16 agc_fac,    /* i   : AGC factor                        */
+    Word16 l_trm       /* i   : subframe size                     */
+);
+
+/*
+**************************************************************************
+*
+*  Function:  agc2
+*  Purpose:   Scales the excitation on a subframe basis
+*
+**************************************************************************
+*/
+void agc2 (
+    Word16 *sig_in,    /* i   : postfilter input signal   */
+    Word16 *sig_out,   /* i/o : postfilter output signal  */
+    Word16 l_trm       /* i   : subframe size             */
+);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtwamr/autocorr.c	Fri Apr 05 06:08:15 2024 +0000
@@ -0,0 +1,130 @@
+/*
+********************************************************************************
+*
+*      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             : autocorr.c
+*
+********************************************************************************
+*/
+/*
+********************************************************************************
+*                         MODULE INCLUDE FILE AND VERSION ID
+********************************************************************************
+*/
+#include "namespace.h"
+#include "autocorr.h"
+const char autocorr_id[] = "@(#)$Id $" autocorr_h;
+ 
+/*
+********************************************************************************
+*                         INCLUDE FILES
+********************************************************************************
+*/
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "no_count.h"
+#include "cnst.h"
+
+/*
+********************************************************************************
+*                         LOCAL VARIABLES AND TABLES
+********************************************************************************
+*/
+ 
+/*
+********************************************************************************
+*                         PUBLIC PROGRAM CODE
+********************************************************************************
+*/
+/*
+**************************************************************************
+*
+*  Function    : autocorr
+*  Purpose     : Compute autocorrelations of signal with windowing
+*
+**************************************************************************
+*/
+Word16 Autocorr (
+    Word16 x[],            /* (i)    : Input signal (L_WINDOW)            */
+    Word16 m,              /* (i)    : LPC order                          */
+    Word16 r_h[],          /* (o)    : Autocorrelations  (msb)            */
+    Word16 r_l[],          /* (o)    : Autocorrelations  (lsb)            */
+    const Word16 wind[]    /* (i)    : window for LPC analysis (L_WINDOW) */
+)
+{
+    Word16 i, j, norm;
+    Word16 y[L_WINDOW];
+    Word32 sum;
+    Word16 overfl, overfl_shft;
+
+    /* Windowing of signal */
+
+    for (i = 0; i < L_WINDOW; i++)
+    {
+        y[i] = mult_r (x[i], wind[i]); move16 (); 
+    }
+
+    /* Compute r[0] and test for overflow */
+
+    overfl_shft = 0;                   move16 (); 
+
+    do
+    {
+        overfl = 0;                    move16 (); 
+        sum = 0L;                      move32 ();
+
+        for (i = 0; i < L_WINDOW; i++)
+        {
+            sum = L_mac (sum, y[i], y[i]);
+        }
+
+        /* If overflow divide y[] by 4 */
+
+        test (); 
+        if (L_sub (sum, MAX_32) == 0L)
+        {
+            overfl_shft = add (overfl_shft, 4);
+            overfl = 1;                move16 (); /* Set the overflow flag */
+
+            for (i = 0; i < L_WINDOW; i++)
+            {
+                y[i] = shr (y[i], 2);  move16 (); 
+            }
+        }
+        test (); 
+    }
+    while (overfl != 0);
+
+    sum = L_add (sum, 1L);             /* Avoid the case of all zeros */
+
+    /* Normalization of r[0] */
+
+    norm = norm_l (sum);
+    sum = L_shl (sum, norm);
+    L_Extract (sum, &r_h[0], &r_l[0]); /* Put in DPF format (see oper_32b) */
+
+    /* r[1] to r[m] */
+
+    for (i = 1; i <= m; i++)
+    {
+        sum = 0;                       move32 (); 
+
+        for (j = 0; j < L_WINDOW - i; j++)
+        {
+            sum = L_mac (sum, y[j], y[j + i]);
+        }
+
+        sum = L_shl (sum, norm);
+        L_Extract (sum, &r_h[i], &r_l[i]);
+    }
+
+    norm = sub (norm, overfl_shft);
+
+    return norm;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtwamr/autocorr.h	Fri Apr 05 06:08:15 2024 +0000
@@ -0,0 +1,58 @@
+/*
+********************************************************************************
+*
+*      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             : autocorr.h
+*      Purpose          : Compute autocorrelations of signal with windowing
+*
+********************************************************************************
+*/
+#ifndef autocorr_h
+#define autocorr_h "$Id $"
+ 
+/*
+********************************************************************************
+*                         INCLUDE FILES
+********************************************************************************
+*/
+#include "typedef.h"
+ 
+/*
+********************************************************************************
+*                         DEFINITION OF DATA TYPES
+********************************************************************************
+*/
+ 
+/*
+********************************************************************************
+*                         DECLARATION OF PROTOTYPES
+********************************************************************************
+*/
+/*
+**************************************************************************
+*
+*  Function    : autocorr
+*  Purpose     : Compute autocorrelations of signal with windowing
+*  Description : - Windowing of input speech:   s'[n] = s[n] * w[n]
+*                - Autocorrelations of input speech:
+*                  r[k] = sum_{i=k}^{239} s'[i]*s'[i-k]    k=0,...,10
+*                The autocorrelations are expressed in normalized 
+*                double precision format.
+*  Returns     : Autocorrelation
+*
+**************************************************************************
+*/
+Word16 Autocorr (
+    Word16 x[],        /* (i)    : Input signal (L_WINDOW)             */
+    Word16 m,          /* (i)    : LPC order                           */
+    Word16 r_h[],      /* (o)    : Autocorrelations  (msb)  (MP1)      */
+    Word16 r_l[],      /* (o)    : Autocorrelations  (lsb)  (MP1)      */
+    const Word16 wind[]/* (i)    : window for LPC analysis. (L_WINDOW) */
+);
+ 
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtwamr/az_lsp.c	Fri Apr 05 06:08:15 2024 +0000
@@ -0,0 +1,282 @@
+/*
+********************************************************************************
+*
+*      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             : az_lsp.c
+*      Purpose          : Compute the LSPs from the LP coefficients
+*
+********************************************************************************
+*/
+/*
+********************************************************************************
+*                         MODULE INCLUDE FILE AND VERSION ID
+********************************************************************************
+*/
+#include "namespace.h"
+#include "az_lsp.h"
+const char az_lsp_id[] = "@(#)$Id $" az_lsp_h;
+/*
+********************************************************************************
+*                         INCLUDE FILES
+********************************************************************************
+*/
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "no_count.h"
+#include "cnst.h"
+ 
+/*
+********************************************************************************
+*                         LOCAL VARIABLES AND TABLES
+********************************************************************************
+*/
+#include "grid.tab"
+#define NC   M/2                  /* M = LPC order, NC = M/2 */
+
+/*
+********************************************************************************
+*                         LOCAL PROGRAM CODE
+********************************************************************************
+*/
+/*
+**************************************************************************
+*
+*  Function    : Chebps
+*  Purpose     : Evaluates the Chebyshev polynomial series
+*  Description : - The polynomial order is   n = m/2 = 5
+*                - The polynomial F(z) (F1(z) or F2(z)) is given by
+*                   F(w) = 2 exp(-j5w) C(x)
+*                  where
+*                   C(x) = T_n(x) + f(1)T_n-1(x) + ... +f(n-1)T_1(x) + f(n)/2
+*                  and T_m(x) = cos(mw) is the mth order Chebyshev
+*                  polynomial ( x=cos(w) )
+*  Returns     : C(x) for the input x.
+*
+**************************************************************************
+*/
+static Word16 Chebps (Word16 x,
+                      Word16 f[], /* (n) */
+                      Word16 n)
+{
+    Word16 i, cheb;
+    Word16 b0_h, b0_l, b1_h, b1_l, b2_h, b2_l;
+    Word32 t0;
+
+    b2_h = 256;                    move16 (); /* b2 = 1.0 */
+    b2_l = 0;                      move16 (); 
+
+    t0 = L_mult (x, 512);          /* 2*x                 */
+    t0 = L_mac (t0, f[1], 8192);   /* + f[1]              */
+    L_Extract (t0, &b1_h, &b1_l);  /* b1 = 2*x + f[1]     */
+
+    for (i = 2; i < n; i++)
+    {
+        t0 = Mpy_32_16 (b1_h, b1_l, x);         /* t0 = 2.0*x*b1        */
+        t0 = L_shl (t0, 1);
+        t0 = L_mac (t0, b2_h, (Word16) 0x8000); /* t0 = 2.0*x*b1 - b2   */
+        t0 = L_msu (t0, b2_l, 1);
+        t0 = L_mac (t0, f[i], 8192);            /* t0 = 2.0*x*b1 - b2 + f[i] */
+
+        L_Extract (t0, &b0_h, &b0_l);           /* b0 = 2.0*x*b1 - b2 + f[i]*/
+
+        b2_l = b1_l;               move16 ();   /* b2 = b1; */
+        b2_h = b1_h;               move16 (); 
+        b1_l = b0_l;               move16 ();   /* b1 = b0; */
+        b1_h = b0_h;               move16 (); 
+    }
+
+    t0 = Mpy_32_16 (b1_h, b1_l, x);             /* t0 = x*b1; */
+    t0 = L_mac (t0, b2_h, (Word16) 0x8000);     /* t0 = x*b1 - b2   */
+    t0 = L_msu (t0, b2_l, 1);
+    t0 = L_mac (t0, f[i], 4096);                /* t0 = x*b1 - b2 + f[i]/2 */
+
+    t0 = L_shl (t0, 6);
+
+    cheb = extract_h (t0);
+
+    return (cheb);
+}
+
+/*
+********************************************************************************
+*                         PUBLIC PROGRAM CODE
+********************************************************************************
+*/
+/*
+**************************************************************************
+*
+*  Function    : Az_lsp
+*  Purpose     : Compute the LSPs from  the LP coefficients
+*
+**************************************************************************
+*/
+void Az_lsp (
+    Word16 a[],         /* (i)  : predictor coefficients (MP1)               */
+    Word16 lsp[],       /* (o)  : line spectral pairs (M)                    */
+    Word16 old_lsp[]    /* (i)  : old lsp[] (in case not found 10 roots) (M) */
+)
+{
+    Word16 i, j, nf, ip;
+    Word16 xlow, ylow, xhigh, yhigh, xmid, ymid, xint;
+    Word16 x, y, sign, exp;
+    Word16 *coef;
+    Word16 f1[M / 2 + 1], f2[M / 2 + 1];
+    Word32 t0;
+
+    /*-------------------------------------------------------------*
+     *  find the sum and diff. pol. F1(z) and F2(z)                *
+     *    F1(z) <--- F1(z)/(1+z**-1) & F2(z) <--- F2(z)/(1-z**-1)  *
+     *                                                             *
+     * f1[0] = 1.0;                                                *
+     * f2[0] = 1.0;                                                *
+     *                                                             *
+     * for (i = 0; i< NC; i++)                                     *
+     * {                                                           *
+     *   f1[i+1] = a[i+1] + a[M-i] - f1[i] ;                       *
+     *   f2[i+1] = a[i+1] - a[M-i] + f2[i] ;                       *
+     * }                                                           *
+     *-------------------------------------------------------------*/
+
+    f1[0] = 1024;                  move16 (); /* f1[0] = 1.0 */
+    f2[0] = 1024;                  move16 (); /* f2[0] = 1.0 */
+
+    for (i = 0; i < NC; i++)
+    {
+        t0 = L_mult (a[i + 1], 8192);   /* x = (a[i+1] + a[M-i]) >> 2  */
+        t0 = L_mac (t0, a[M - i], 8192);
+        x = extract_h (t0);
+        /* f1[i+1] = a[i+1] + a[M-i] - f1[i] */
+        f1[i + 1] = sub (x, f1[i]);move16 (); 
+
+        t0 = L_mult (a[i + 1], 8192);   /* x = (a[i+1] - a[M-i]) >> 2 */
+        t0 = L_msu (t0, a[M - i], 8192);
+        x = extract_h (t0);
+        /* f2[i+1] = a[i+1] - a[M-i] + f2[i] */
+        f2[i + 1] = add (x, f2[i]);move16 (); 
+    }
+
+    /*-------------------------------------------------------------*
+     * find the LSPs using the Chebychev pol. evaluation           *
+     *-------------------------------------------------------------*/
+
+    nf = 0;                        move16 (); /* number of found frequencies */
+    ip = 0;                        move16 (); /* indicator for f1 or f2      */
+
+    coef = f1;                     move16 (); 
+
+    xlow = grid[0];                move16 (); 
+    ylow = Chebps (xlow, coef, NC);move16 (); 
+
+    j = 0;
+    test (); test (); 
+    /* while ( (nf < M) && (j < grid_points) ) */
+    while ((sub (nf, M) < 0) && (sub (j, grid_points) < 0))
+    {
+        j++;
+        xhigh = xlow;              move16 (); 
+        yhigh = ylow;              move16 (); 
+        xlow = grid[j];            move16 (); 
+        ylow = Chebps (xlow, coef, NC);
+                                   move16 (); 
+
+        test (); 
+        if (L_mult (ylow, yhigh) <= (Word32) 0L)
+        {
+
+            /* divide 4 times the interval */
+
+            for (i = 0; i < 4; i++)
+            {
+                /* xmid = (xlow + xhigh)/2 */
+                xmid = add (shr (xlow, 1), shr (xhigh, 1));
+                ymid = Chebps (xmid, coef, NC);
+                                   move16 (); 
+
+                test (); 
+                if (L_mult (ylow, ymid) <= (Word32) 0L)
+                {
+                    yhigh = ymid;  move16 (); 
+                    xhigh = xmid;  move16 (); 
+                }
+                else
+                {
+                    ylow = ymid;   move16 (); 
+                    xlow = xmid;   move16 (); 
+                }
+            }
+
+            /*-------------------------------------------------------------*
+             * Linear interpolation                                        *
+             *    xint = xlow - ylow*(xhigh-xlow)/(yhigh-ylow);            *
+             *-------------------------------------------------------------*/
+
+            x = sub (xhigh, xlow);
+            y = sub (yhigh, ylow);
+
+            test (); 
+            if (y == 0)
+            {
+                xint = xlow;       move16 (); 
+            }
+            else
+            {
+                sign = y;          move16 (); 
+                y = abs_s (y);
+                exp = norm_s (y);
+                y = shl (y, exp);
+                y = div_s ((Word16) 16383, y);
+                t0 = L_mult (x, y);
+                t0 = L_shr (t0, sub (20, exp));
+                y = extract_l (t0);     /* y= (xhigh-xlow)/(yhigh-ylow) */
+
+                test (); 
+                if (sign < 0)
+                    y = negate (y);
+
+                t0 = L_mult (ylow, y);
+                t0 = L_shr (t0, 11);
+                xint = sub (xlow, extract_l (t0)); /* xint = xlow - ylow*y */
+            }
+
+            lsp[nf] = xint;        move16 (); 
+            xlow = xint;           move16 (); 
+            nf++;
+
+            test (); 
+            if (ip == 0)
+            {
+                ip = 1;            move16 (); 
+                coef = f2;         move16 (); 
+            }
+            else
+            {
+                ip = 0;            move16 (); 
+                coef = f1;         move16 (); 
+            }
+            ylow = Chebps (xlow, coef, NC);
+                                   move16 (); 
+
+        }
+        test (); test (); 
+    }
+
+    /* Check if M roots found */
+
+    test (); 
+    if (sub (nf, M) < 0)
+    {
+        for (i = 0; i < M; i++)
+        {
+            lsp[i] = old_lsp[i];   move16 (); 
+        }
+
+    }
+    return;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtwamr/az_lsp.h	Fri Apr 05 06:08:15 2024 +0000
@@ -0,0 +1,65 @@
+/*
+********************************************************************************
+*
+*      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             : az_lsp.h
+*
+********************************************************************************
+*/
+#ifndef az_lsp_h
+#define az_lsp_h "$Id $"
+ 
+/*
+********************************************************************************
+*                         INCLUDE FILES
+********************************************************************************
+*/
+#include "typedef.h"
+ 
+/*
+********************************************************************************
+*                         DEFINITION OF DATA TYPES
+********************************************************************************
+*/
+ 
+/*
+********************************************************************************
+*                         DECLARATION OF PROTOTYPES
+********************************************************************************
+*/
+/*
+**************************************************************************
+*
+*  Function    : Az_lsp
+*  Purpose     : Compute the LSPs from the LP coefficients
+*  Description : - The sum and difference filters are computed
+*                  and divided by 1+z^{-1} and 1-z^{-1}, respectively.
+*
+*                  f1[i] = a[i] + a[11-i] - f1[i-1] ;   i=1,...,5
+*                  f2[i] = a[i] - a[11-i] + f2[i-1] ;   i=1,...,5
+*
+*                - The roots of F1(z) and F2(z) are found using
+*                  Chebyshev polynomial evaluation. The polynomials
+*                  are evaluated at 60 points regularly spaced in the
+*                  frequency domain. The sign change interval is
+*                  subdivided 4 times to better track the root. The
+*                  LSPs are found in the cosine domain [1,-1].
+*
+*                - If less than 10 roots are found, the LSPs from 
+*                  the past frame are used.
+*  Returns     : void
+*
+**************************************************************************
+*/
+void Az_lsp (
+    Word16 a[],        /* (i)  : predictor coefficients (MP1)              */
+    Word16 lsp[],      /* (o)  : line spectral pairs (M)                   */
+    Word16 old_lsp[]   /* (i)  : old lsp[] (in case not found 10 roots) (M)*/
+);
+ 
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtwamr/grid.tab	Fri Apr 05 06:08:15 2024 +0000
@@ -0,0 +1,41 @@
+/*
+********************************************************************************
+*
+*      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             : pow2.c
+*      Purpose          : Table for az_lsf()
+*      $Id $
+*
+********************************************************************************
+*/
+/*-------------------------------------------------------------*
+ *  Table for az_lsf()                                         *
+ *                                                             *
+ * grid[0] = 1.0;                                              *
+ * grid[grid_points+1] = -1.0;                                 *
+ * for (i = 1; i < grid_points; i++)                           *
+ *   grid[i] = cos((6.283185307*i)/(2.0*grid_points));         *
+ *                                                             *
+ *-------------------------------------------------------------*/
+
+#define grid_points 60
+
+static const Word16 grid[grid_points + 1] =
+{
+    32760, 32723, 32588, 32364, 32051, 31651,
+    31164, 30591, 29935, 29196, 28377, 27481,
+    26509, 25465, 24351, 23170, 21926, 20621,
+    19260, 17846, 16384, 14876, 13327, 11743,
+    10125, 8480, 6812, 5126, 3425, 1714,
+    0, -1714, -3425, -5126, -6812, -8480,
+    -10125, -11743, -13327, -14876, -16384, -17846,
+    -19260, -20621, -21926, -23170, -24351, -25465,
+    -26509, -27481, -28377, -29196, -29935, -30591,
+    -31164, -31651, -32051, -32364, -32588, -32723,
+    -32760
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtwamr/inv_sqrt.c	Fri Apr 05 06:08:15 2024 +0000
@@ -0,0 +1,98 @@
+/*
+********************************************************************************
+*
+*      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             : inv_sqrt.c
+*      Purpose          : Computes 1/sqrt(L_x),  where  L_x is positive.
+*                       : If L_x is negative or zero, 
+*                       : the result is 1 (3fff ffff).
+*      Description      :
+*            The function 1/sqrt(L_x) is approximated by a table and linear
+*            interpolation. The inverse square root is computed using the
+*            following steps:
+*                1- Normalization of L_x.
+*                2- If (30-exponent) is even then shift right once.
+*                3- exponent = (30-exponent)/2  +1
+*                4- i = bit25-b31 of L_x;  16<=i<=63  because of normalization.
+*                5- a = bit10-b24
+*                6- i -=16
+*                7- L_y = table[i]<<16 - (table[i] - table[i+1]) * a * 2
+*                8- L_y >>= exponent
+*
+********************************************************************************
+*/
+/*
+********************************************************************************
+*                         MODULE INCLUDE FILE AND VERSION ID
+********************************************************************************
+*/
+#include "namespace.h"
+#include "inv_sqrt.h"
+const char inv_sqrt_id[] = "@(#)$Id $" inv_sqrt_h;
+
+/*
+********************************************************************************
+*                         INCLUDE FILES
+********************************************************************************
+*/
+#include "typedef.h"
+#include "basic_op.h"
+#include "no_count.h"
+
+/*
+********************************************************************************
+*                         LOCAL VARIABLES AND TABLES
+********************************************************************************
+*/
+#include "inv_sqrt.tab" /* Table for inv_sqrt() */
+
+/*
+********************************************************************************
+*                         PUBLIC PROGRAM CODE
+********************************************************************************
+*/
+
+Word32 Inv_sqrt (       /* (o) : output value   */
+    Word32 L_x          /* (i) : input value    */
+)
+{
+    Word16 exp, i, a, tmp;
+    Word32 L_y;
+
+    test (); 
+    if (L_x <= (Word32) 0)
+        return ((Word32) 0x3fffffffL);
+
+    exp = norm_l (L_x);
+    L_x = L_shl (L_x, exp);     /* L_x is normalize */
+
+    exp = sub (30, exp);
+    test (); logic16 (); 
+    if ((exp & 1) == 0)         /* If exponent even -> shift right */
+    {
+        L_x = L_shr (L_x, 1);
+    }
+    exp = shr (exp, 1);
+    exp = add (exp, 1);
+
+    L_x = L_shr (L_x, 9);
+    i = extract_h (L_x);        /* Extract b25-b31 */
+    L_x = L_shr (L_x, 1);
+    a = extract_l (L_x);        /* Extract b10-b24 */
+    a = a & (Word16) 0x7fff;    logic16 (); 
+
+    i = sub (i, 16);
+
+    L_y = L_deposit_h (table[i]);       /* table[i] << 16          */
+    tmp = sub (table[i], table[i + 1]); /* table[i] - table[i+1])  */
+    L_y = L_msu (L_y, tmp, a);  /* L_y -=  tmp*a*2         */
+
+    L_y = L_shr (L_y, exp);     /* denormalization */
+
+    return (L_y);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtwamr/inv_sqrt.h	Fri Apr 05 06:08:15 2024 +0000
@@ -0,0 +1,54 @@
+/*
+********************************************************************************
+*
+*      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             : inv_sqrt.h
+*      Purpose          : Computes 1/sqrt(L_x),  where  L_x is positive.
+*                       : If L_x is negative or zero, the result is
+*                       : 1 (3fff ffff).
+*      Description      : The function 1/sqrt(L_x) is approximated by a table 
+*                       : and linear interpolation. The inverse square root is 
+*                       : computed using the following steps:
+*               1- Normalization of L_x.
+*               2- If (30-exponent) is even then shift right once.
+*               3- exponent = (30-exponent)/2  +1
+*               4- i = bit25-b31 of L_x;  16<=i<=63  because of normalization.
+*               5- a = bit10-b24
+*               6- i -=16
+*               7- L_y = table[i]<<16 - (table[i] - table[i+1]) * a * 2
+*               8- L_y >>= exponent
+*
+********************************************************************************
+*/
+#ifndef inv_sqrt_h
+#define inv_sqrt_h "$Id $"
+ 
+/*
+********************************************************************************
+*                         INCLUDE FILES
+********************************************************************************
+*/
+#include "typedef.h"
+
+/*
+********************************************************************************
+*                         DEFINITION OF DATA TYPES
+********************************************************************************
+*/
+ 
+/*
+********************************************************************************
+*                         DECLARATION OF PROTOTYPES
+********************************************************************************
+*/
+ 
+Word32 Inv_sqrt (      /* (o) : output value   (range: 0<=val<1)            */
+    Word32 L_x           /* (i) : input value    (range: 0<=val<=7fffffff)    */
+);
+ 
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtwamr/inv_sqrt.tab	Fri Apr 05 06:08:15 2024 +0000
@@ -0,0 +1,24 @@
+/*
+********************************************************************************
+*
+*      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             : inv_sqrt.tab
+*      Purpose          : Table for routine Inv_sqrt()
+*      $Id $
+*
+********************************************************************************
+*/
+static const Word16 table[49] =
+{
+
+    32767, 31790, 30894, 30070, 29309, 28602, 27945, 27330, 26755, 26214,
+    25705, 25225, 24770, 24339, 23930, 23541, 23170, 22817, 22479, 22155,
+    21845, 21548, 21263, 20988, 20724, 20470, 20225, 19988, 19760, 19539,
+    19326, 19119, 18919, 18725, 18536, 18354, 18176, 18004, 17837, 17674,
+    17515, 17361, 17211, 17064, 16921, 16782, 16646, 16514, 16384
+};
--- a/libtwamr/namespace.h	Fri Apr 05 01:02:23 2024 +0000
+++ b/libtwamr/namespace.h	Fri Apr 05 06:08:15 2024 +0000
@@ -58,4 +58,14 @@
 #define	Log2		AMR__Log2
 #define	Pow2		AMR__Pow2
 
+#define	A_Refl		AMR__A_Refl
+#define	Autocorr	AMR__Autocorr
+#define	Az_lsp		AMR__Az_lsp
+
+#define	agc_init	AMR__agc_init
+#define	agc_reset	AMR__agc_reset
+#define	agc_exit	AMR__agc_exit
+#define	agc		AMR__agc
+#define	agc2		AMR__agc2
+
 #endif	/* include guard */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtwamr/no_count.h	Fri Apr 05 06:08:15 2024 +0000
@@ -0,0 +1,12 @@
+/* no-op definitions for ETSI's move/logic/test counting calls */
+
+#ifndef	no_count_h
+#define	no_count_h
+
+static inline void move16(void) {}
+static inline void move32(void) {}
+static inline void logic16(void) {}
+static inline void logic32(void) {}
+static inline void test(void) {}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtwamr/oper_32b.c	Fri Apr 05 06:08:15 2024 +0000
@@ -0,0 +1,209 @@
+/*****************************************************************************
+ *                                                                           *
+ *  This file contains operations in double precision.                       *
+ *  These operations are not standard double precision operations.           *
+ *  They are used where single precision is not enough but the full 32 bits  *
+ *  precision is not necessary. For example, the function Div_32() has a     *
+ *  24 bits precision which is enough for our purposes.                      *
+ *                                                                           *
+ *  The double precision numbers use a special representation:               *
+ *                                                                           *
+ *     L_32 = hi<<16 + lo<<1                                                 *
+ *                                                                           *
+ *  L_32 is a 32 bit integer.                                                *
+ *  hi and lo are 16 bit signed integers.                                    *
+ *  As the low part also contains the sign, this allows fast multiplication. *
+ *                                                                           *
+ *      0x8000 0000 <= L_32 <= 0x7fff fffe.                                  *
+ *                                                                           *
+ *  We will use DPF (Double Precision Format )in this file to specify        *
+ *  this special format.                                                     *
+ *****************************************************************************
+*/
+
+#include "typedef.h"
+#include "namespace.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "no_count.h"
+
+/*****************************************************************************
+ *                                                                           *
+ *  Function L_Extract()                                                     *
+ *                                                                           *
+ *  Extract from a 32 bit integer two 16 bit DPF.                            *
+ *                                                                           *
+ *  Arguments:                                                               *
+ *                                                                           *
+ *   L_32      : 32 bit integer.                                             *
+ *               0x8000 0000 <= L_32 <= 0x7fff ffff.                         *
+ *   hi        : b16 to b31 of L_32                                          *
+ *   lo        : (L_32 - hi<<16)>>1                                          *
+ *****************************************************************************
+*/
+
+void L_Extract (Word32 L_32, Word16 *hi, Word16 *lo)
+{
+    *hi = extract_h (L_32);
+    *lo = extract_l (L_msu (L_shr (L_32, 1), *hi, 16384));
+    return;
+}
+
+/*****************************************************************************
+ *                                                                           *
+ *  Function L_Comp()                                                        *
+ *                                                                           *
+ *  Compose from two 16 bit DPF a 32 bit integer.                            *
+ *                                                                           *
+ *     L_32 = hi<<16 + lo<<1                                                 *
+ *                                                                           *
+ *  Arguments:                                                               *
+ *                                                                           *
+ *   hi        msb                                                           *
+ *   lo        lsf (with sign)                                               *
+ *                                                                           *
+ *   Return Value :                                                          *
+ *                                                                           *
+ *             32 bit long signed integer (Word32) whose value falls in the  *
+ *             range : 0x8000 0000 <= L_32 <= 0x7fff fff0.                   *
+ *                                                                           *
+ *****************************************************************************
+*/
+
+Word32 L_Comp (Word16 hi, Word16 lo)
+{
+    Word32 L_32;
+
+    L_32 = L_deposit_h (hi);
+    return (L_mac (L_32, lo, 1));       /* = hi<<16 + lo<<1 */
+}
+
+/*****************************************************************************
+ * Function Mpy_32()                                                         *
+ *                                                                           *
+ *   Multiply two 32 bit integers (DPF). The result is divided by 2**31      *
+ *                                                                           *
+ *   L_32 = (hi1*hi2)<<1 + ( (hi1*lo2)>>15 + (lo1*hi2)>>15 )<<1              *
+ *                                                                           *
+ *   This operation can also be viewed as the multiplication of two Q31      *
+ *   number and the result is also in Q31.                                   *
+ *                                                                           *
+ * Arguments:                                                                *
+ *                                                                           *
+ *  hi1         hi part of first number                                      *
+ *  lo1         lo part of first number                                      *
+ *  hi2         hi part of second number                                     *
+ *  lo2         lo part of second number                                     *
+ *                                                                           *
+ *****************************************************************************
+*/
+
+Word32 Mpy_32 (Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2)
+{
+    Word32 L_32;
+
+    L_32 = L_mult (hi1, hi2);
+    L_32 = L_mac (L_32, mult (hi1, lo2), 1);
+    L_32 = L_mac (L_32, mult (lo1, hi2), 1);
+
+    return (L_32);
+}
+
+/*****************************************************************************
+ * Function Mpy_32_16()                                                      *
+ *                                                                           *
+ *   Multiply a 16 bit integer by a 32 bit (DPF). The result is divided      *
+ *   by 2**15                                                                *
+ *                                                                           *
+ *                                                                           *
+ *   L_32 = (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1                                *
+ *                                                                           *
+ * Arguments:                                                                *
+ *                                                                           *
+ *  hi          hi part of 32 bit number.                                    *
+ *  lo          lo part of 32 bit number.                                    *
+ *  n           16 bit number.                                               *
+ *                                                                           *
+ *****************************************************************************
+*/
+
+Word32 Mpy_32_16 (Word16 hi, Word16 lo, Word16 n)
+{
+    Word32 L_32;
+
+    L_32 = L_mult (hi, n);
+    L_32 = L_mac (L_32, mult (lo, n), 1);
+
+    return (L_32);
+}
+
+/*****************************************************************************
+ *                                                                           *
+ *   Function Name : Div_32                                                  *
+ *                                                                           *
+ *   Purpose :                                                               *
+ *             Fractional integer division of two 32 bit numbers.            *
+ *             L_num / L_denom.                                              *
+ *             L_num and L_denom must be positive and L_num < L_denom.       *
+ *             L_denom = denom_hi<<16 + denom_lo<<1                          *
+ *             denom_hi is a normalize number.                               *
+ *                                                                           *
+ *   Inputs :                                                                *
+ *                                                                           *
+ *    L_num                                                                  *
+ *             32 bit long signed integer (Word32) whose value falls in the  *
+ *             range : 0x0000 0000 < L_num < L_denom                         *
+ *                                                                           *
+ *    L_denom = denom_hi<<16 + denom_lo<<1      (DPF)                        *
+ *                                                                           *
+ *       denom_hi                                                            *
+ *             16 bit positive normalized integer whose value falls in the   *
+ *             range : 0x4000 < hi < 0x7fff                                  *
+ *       denom_lo                                                            *
+ *             16 bit positive integer whose value falls in the              *
+ *             range : 0 < lo < 0x7fff                                       *
+ *                                                                           *
+ *   Return Value :                                                          *
+ *                                                                           *
+ *    L_div                                                                  *
+ *             32 bit long signed integer (Word32) whose value falls in the  *
+ *             range : 0x0000 0000 <= L_div <= 0x7fff ffff.                  *
+ *                                                                           *
+ *  Algorithm:                                                               *
+ *                                                                           *
+ *  - find = 1/L_denom.                                                      *
+ *      First approximation: approx = 1 / denom_hi                           *
+ *      1/L_denom = approx * (2.0 - L_denom * approx )                       *
+ *                                                                           *
+ *  -  result = L_num * (1/L_denom)                                          *
+ *****************************************************************************
+*/
+
+Word32 Div_32 (Word32 L_num, Word16 denom_hi, Word16 denom_lo)
+{
+    Word16 approx, hi, lo, n_hi, n_lo;
+    Word32 L_32;
+
+    /* First approximation: 1 / L_denom = 1/denom_hi */
+
+    approx = div_s ((Word16) 0x3fff, denom_hi);
+
+    /* 1/L_denom = approx * (2.0 - L_denom * approx) */
+
+    L_32 = Mpy_32_16 (denom_hi, denom_lo, approx);
+
+    L_32 = L_sub ((Word32) 0x7fffffffL, L_32);
+
+    L_Extract (L_32, &hi, &lo);
+
+    L_32 = Mpy_32_16 (hi, lo, approx);
+
+    /* L_num * (1/L_denom) */
+
+    L_Extract (L_32, &hi, &lo);
+    L_Extract (L_num, &n_hi, &n_lo);
+    L_32 = Mpy_32 (n_hi, n_lo, hi, lo);
+    L_32 = L_shl (L_32, 2);
+
+    return (L_32);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtwamr/oper_32b.h	Fri Apr 05 06:08:15 2024 +0000
@@ -0,0 +1,7 @@
+/* Double precision operations */
+
+void L_Extract (Word32 L_32, Word16 *hi, Word16 *lo);
+Word32 L_Comp (Word16 hi, Word16 lo);
+Word32 Mpy_32 (Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2);
+Word32 Mpy_32_16 (Word16 hi, Word16 lo, Word16 n);
+Word32 Div_32 (Word32 L_num, Word16 denom_hi, Word16 denom_lo);