FreeCalypso > hg > gsm-codec-lib
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);