FreeCalypso > hg > gsm-codec-lib
changeset 385:c713061b6edf
libtwamr: integrate levinson.c
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 06 May 2024 06:01:56 +0000 |
parents | a8dab7028e4d |
children | 9adfe3863a41 |
files | libtwamr/Makefile libtwamr/levinson.c libtwamr/levinson.h libtwamr/namespace.list |
diffstat | 4 files changed, 316 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/libtwamr/Makefile Mon May 06 05:56:50 2024 +0000 +++ b/libtwamr/Makefile Mon May 06 06:01:56 2024 +0000 @@ -8,11 +8,11 @@ dec_lag6.o dhf_check.o dhf_tables.o e_homing.o ec_gains.o enc_lag3.o \ enc_lag6.o ex_ctrl.o g_adapt.o g_code.o g_pitch.o gain_q.o gains_tab.o \ gc_pred.o gmed_n.o graytab.o hp_max.o int_lpc.o int_lsf.o inter_36.o \ - inv_sqrt.o lag_wind.o log2.o lsfwt.o lsp_az.o lsp_lsf.o mac_32.o \ - oper_32b.o pow2.o prmno.o q_gain_c.o q_gain_p.o q_plsf.o q_plsf3_tab.o \ - q_plsf5_tab.o q_plsf_3.o q_plsf_5.o qgain475.o qgain795.o qua_gain.o \ - qua_gain_tab.o reorder.o s10_8pf.o set_sign.o sqrt_l.o tls_flags.o \ - window.o + inv_sqrt.o lag_wind.o levinson.o log2.o lsfwt.o lsp_az.o lsp_lsf.o \ + mac_32.o oper_32b.o pow2.o prmno.o q_gain_c.o q_gain_p.o q_plsf.o \ + q_plsf3_tab.o q_plsf5_tab.o q_plsf_3.o q_plsf_5.o qgain475.o qgain795.o\ + qua_gain.o qua_gain_tab.o reorder.o s10_8pf.o set_sign.o sqrt_l.o \ + tls_flags.o window.o HDRS= namespace.h LIB= libtwamr.a
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libtwamr/levinson.c Mon May 06 06:01:56 2024 +0000 @@ -0,0 +1,248 @@ +/* +***************************************************************************** +* +* 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 : levinson.c +* Purpose : Levinson-Durbin algorithm in double precision. +* : To compute the LP filter parameters from the +* : speech autocorrelations. +* +***************************************************************************** +*/ + +/* +***************************************************************************** +* MODULE INCLUDE FILE AND VERSION ID +***************************************************************************** +*/ +#include "namespace.h" +#include "levinson.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 +***************************************************************************** +*/ +/*---------------------------------------------------------------* + * Constants (defined in "cnst.h") * + *---------------------------------------------------------------* + * M : LPC order + *---------------------------------------------------------------*/ + +/* +***************************************************************************** +* PUBLIC PROGRAM CODE +***************************************************************************** +*/ + +/************************************************************************* +* +* Function: Levinson_reset +* Purpose: Initializes state memory to zero +* +************************************************************************** +*/ +void Levinson_reset (LevinsonState *state) +{ + Word16 i; + + state->old_A[0] = 4096; + for(i = 1; i < M + 1; i++) + state->old_A[i] = 0; +} + +/************************************************************************* + * + * FUNCTION: Levinson() + * + * PURPOSE: Levinson-Durbin algorithm in double precision. To compute the + * LP filter parameters from the speech autocorrelations. + * + * DESCRIPTION: + * R[i] autocorrelations. + * A[i] filter coefficients. + * K reflection coefficients. + * Alpha prediction gain. + * + * Initialisation: + * A[0] = 1 + * K = -R[1]/R[0] + * A[1] = K + * Alpha = R[0] * (1-K**2] + * + * Do for i = 2 to M + * + * S = SUM ( R[j]*A[i-j] ,j=1,i-1 ) + R[i] + * + * K = -S / Alpha + * + * An[j] = A[j] + K*A[i-j] for j=1 to i-1 + * where An[i] = new A[i] + * An[i]=K + * + * Alpha=Alpha * (1-K**2) + * + * END + * + *************************************************************************/ +int Levinson ( + LevinsonState *st, + Word16 Rh[], /* i : Rh[m+1] Vector of autocorrelations (msb) */ + Word16 Rl[], /* i : Rl[m+1] Vector of autocorrelations (lsb) */ + Word16 A[], /* o : A[m] LPC coefficients (m = 10) */ + Word16 rc[] /* o : rc[4] First 4 reflection coefficients */ +) +{ + Word16 i, j; + Word16 hi, lo; + Word16 Kh, Kl; /* reflexion coefficient; hi and lo */ + Word16 alp_h, alp_l, alp_exp; /* Prediction gain; hi lo and exponent */ + Word16 Ah[M + 1], Al[M + 1]; /* LPC coef. in double prec. */ + Word16 Anh[M + 1], Anl[M + 1];/* LPC coef.for next iteration in double + prec. */ + Word32 t0, t1, t2; /* temporary variable */ + + /* K = A[1] = -R[1] / R[0] */ + + t1 = L_Comp (Rh[1], Rl[1]); + t2 = L_abs (t1); /* abs R[1] */ + t0 = Div_32 (t2, Rh[0], Rl[0]); /* R[1]/R[0] */ + test (); + if (t1 > 0) + t0 = L_negate (t0); /* -R[1]/R[0] */ + L_Extract (t0, &Kh, &Kl); /* K in DPF */ + + rc[0] = round (t0); move16 (); + + t0 = L_shr (t0, 4); /* A[1] in */ + L_Extract (t0, &Ah[1], &Al[1]); /* A[1] in DPF */ + + /* Alpha = R[0] * (1-K**2) */ + + t0 = Mpy_32 (Kh, Kl, Kh, Kl); /* K*K */ + t0 = L_abs (t0); /* Some case <0 !! */ + t0 = L_sub ((Word32) 0x7fffffffL, t0); /* 1 - K*K */ + L_Extract (t0, &hi, &lo); /* DPF format */ + t0 = Mpy_32 (Rh[0], Rl[0], hi, lo); /* Alpha in */ + + /* Normalize Alpha */ + + alp_exp = norm_l (t0); + t0 = L_shl (t0, alp_exp); + L_Extract (t0, &alp_h, &alp_l); /* DPF format */ + + /*--------------------------------------* + * ITERATIONS I=2 to M * + *--------------------------------------*/ + + for (i = 2; i <= M; i++) + { + /* t0 = SUM ( R[j]*A[i-j] ,j=1,i-1 ) + R[i] */ + + t0 = 0; move32 (); + for (j = 1; j < i; j++) + { + t0 = L_add (t0, Mpy_32 (Rh[j], Rl[j], Ah[i - j], Al[i - j])); + } + t0 = L_shl (t0, 4); + + t1 = L_Comp (Rh[i], Rl[i]); + t0 = L_add (t0, t1); /* add R[i] */ + + /* K = -t0 / Alpha */ + + t1 = L_abs (t0); + t2 = Div_32 (t1, alp_h, alp_l); /* abs(t0)/Alpha */ + test (); + if (t0 > 0) + t2 = L_negate (t2); /* K =-t0/Alpha */ + t2 = L_shl (t2, alp_exp); /* denormalize; compare to Alpha */ + L_Extract (t2, &Kh, &Kl); /* K in DPF */ + + test (); + if (sub (i, 5) < 0) + { + rc[i - 1] = round (t2); move16 (); + } + /* Test for unstable filter. If unstable keep old A(z) */ + + test (); + if (sub (abs_s (Kh), 32750) > 0) + { + for (j = 0; j <= M; j++) + { + A[j] = st->old_A[j]; move16 (); + } + + for (j = 0; j < 4; j++) + { + rc[j] = 0; move16 (); + } + + return 0; + } + /*------------------------------------------* + * Compute new LPC coeff. -> An[i] * + * An[j]= A[j] + K*A[i-j] , j=1 to i-1 * + * An[i]= K * + *------------------------------------------*/ + + for (j = 1; j < i; j++) + { + t0 = Mpy_32 (Kh, Kl, Ah[i - j], Al[i - j]); + t0 = L_add(t0, L_Comp(Ah[j], Al[j])); + L_Extract (t0, &Anh[j], &Anl[j]); + } + t2 = L_shr (t2, 4); + L_Extract (t2, &Anh[i], &Anl[i]); + + /* Alpha = Alpha * (1-K**2) */ + + t0 = Mpy_32 (Kh, Kl, Kh, Kl); /* K*K */ + t0 = L_abs (t0); /* Some case <0 !! */ + t0 = L_sub ((Word32) 0x7fffffffL, t0); /* 1 - K*K */ + L_Extract (t0, &hi, &lo); /* DPF format */ + t0 = Mpy_32 (alp_h, alp_l, hi, lo); + + /* Normalize Alpha */ + + j = norm_l (t0); + t0 = L_shl (t0, j); + L_Extract (t0, &alp_h, &alp_l); /* DPF format */ + alp_exp = add (alp_exp, j); /* Add normalization to + alp_exp */ + + /* A[j] = An[j] */ + + for (j = 1; j <= i; j++) + { + Ah[j] = Anh[j]; move16 (); + Al[j] = Anl[j]; move16 (); + } + } + + A[0] = 4096; move16 (); + for (i = 1; i <= M; i++) + { + t0 = L_Comp (Ah[i], Al[i]); + st->old_A[i] = A[i] = round (L_shl (t0, 1));move16 (); move16 (); + } + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libtwamr/levinson.h Mon May 06 06:01:56 2024 +0000 @@ -0,0 +1,62 @@ +/* +******************************************************************************** +* +* 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 : levinson.h +* Purpose : Levinson-Durbin algorithm in double precision. +* : To compute the LP filter parameters from the +* : speech autocorrelations. +* +******************************************************************************** +*/ +#ifndef levinson_h +#define levinson_h "$Id $" + +/* +******************************************************************************** +* INCLUDE FILES +******************************************************************************** +*/ +#include "typedef.h" +#include "cnst.h" + +/* +******************************************************************************** +* LOCAL VARIABLES AND TABLES +******************************************************************************** +*/ + +/* +******************************************************************************** +* DEFINITION OF DATA TYPES +******************************************************************************** +*/ +typedef struct { + Word16 old_A[M + 1]; /* Last A(z) for case of unstable filter */ +} LevinsonState; + +/* +******************************************************************************** +* DECLARATION OF PROTOTYPES +******************************************************************************** +*/ + +void Levinson_reset (LevinsonState *st); +/* reset of pre processing state (i.e. set state memory to zero) + returns 0 on success + */ + +int Levinson ( + LevinsonState *st, + Word16 Rh[], /* i : Rh[m+1] Vector of autocorrelations (msb) */ + Word16 Rl[], /* i : Rl[m+1] Vector of autocorrelations (lsb) */ + Word16 A[], /* o : A[m] LPC coefficients (m = 10) */ + Word16 rc[] /* o : rc[4] First 4 reflection coefficients */ +); + +#endif
--- a/libtwamr/namespace.list Mon May 06 05:56:50 2024 +0000 +++ b/libtwamr/namespace.list Mon May 06 06:01:56 2024 +0000 @@ -25,7 +25,7 @@ G_code G_pitch Int_lpc_1and3 Int_lpc_1and3_2 Int_lpc_1to3 Int_lpc_1to3_2 Int_lsf Interpol_3or6 -Lag_window +Lag_window Levinson Levinson_reset Lsf_lsp Lsp_lsf Reorder_lsf Lsf_wt Lsp_Az Q_plsf_reset Q_plsf_3 Q_plsf_5 Qua_gain