FreeCalypso > hg > gsm-codec-lib
diff libtwamr/pstfilt.c @ 401:59655481e45b
libtwamr: integrate pstfilt.c
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 06 May 2024 19:44:15 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libtwamr/pstfilt.c Mon May 06 19:44:15 2024 +0000 @@ -0,0 +1,217 @@ +/************************************************************************* +* +* 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 : pstfilt.c +* Purpose : Performs adaptive postfiltering on the synthesis +* : speech +* +******************************************************************************** +*/ + +/* +******************************************************************************** +* MODULE INCLUDE FILE AND VERSION ID +******************************************************************************** +*/ +#include "namespace.h" +#include "pstfilt.h" + +/* +******************************************************************************** +* INCLUDE FILES +******************************************************************************** +*/ +#include "tw_amr.h" +#include "typedef.h" +#include "basic_op.h" +#include "memops.h" +#include "weight_a.h" +#include "residu.h" +#include "syn_filt.h" +#include "preemph.h" +#include "no_count.h" +#include "cnst.h" + +/* +******************************************************************************** +* LOCAL VARIABLES AND TABLES +******************************************************************************** +*/ +/*---------------------------------------------------------------* + * Postfilter constant parameters (defined in "cnst.h") * + *---------------------------------------------------------------* + * L_FRAME : Frame size. * + * L_SUBFR : Sub-frame size. * + * M : LPC order. * + * MP1 : LPC order+1 * + * MU : Factor for tilt compensation filter * + * AGC_FAC : Factor for automatic gain control * + *---------------------------------------------------------------*/ + +#define L_H 22 /* size of truncated impulse response of A(z/g1)/A(z/g2) */ + +/* Spectral expansion factors */ +static const Word16 gamma3_MR122[M] = { + 22938, 16057, 11240, 7868, 5508, + 3856, 2699, 1889, 1322, 925 +}; + +static const Word16 gamma3[M] = { + 18022, 9912, 5451, 2998, 1649, 907, 499, 274, 151, 83 +}; + +static const Word16 gamma4_MR122[M] = { + 24576, 18432, 13824, 10368, 7776, + 5832, 4374, 3281, 2461, 1846 +}; + +static const Word16 gamma4[M] = { + 22938, 16057, 11240, 7868, 5508, 3856, 2699, 1889, 1322, 925 +}; + +/* +******************************************************************************** +* PUBLIC PROGRAM CODE +******************************************************************************** +*/ + +/************************************************************************* +* +* Function: Post_Filter_reset +* Purpose: Initializes state memory to zero +* +************************************************************************** +*/ +void Post_Filter_reset (Post_FilterState *state) +{ + Set_zero (state->mem_syn_pst, M); + Set_zero (state->res2, L_SUBFR); + Set_zero (state->synth_buf, L_FRAME + M); + agc_reset(&state->agc_state); + preemphasis_reset(&state->preemph_state); +} + +/* +************************************************************************** +* Function: Post_Filter +* Purpose: postfiltering of synthesis speech. +* Description: +* The postfiltering process is described as follows: +* +* - inverse filtering of syn[] through A(z/0.7) to get res2[] +* - tilt compensation filtering; 1 - MU*k*z^-1 +* - synthesis filtering through 1/A(z/0.75) +* - adaptive gain control +* +************************************************************************** +*/ +int Post_Filter ( + Post_FilterState *st, /* i/o : post filter states */ + enum Mode mode, /* i : AMR mode */ + Word16 *syn, /* i/o : synthesis speech (postfiltered is output) */ + Word16 *Az_4 /* i : interpolated LPC parameters in all subfr. */ +) +{ + /*-------------------------------------------------------------------* + * Declaration of parameters * + *-------------------------------------------------------------------*/ + + Word16 Ap3[MP1], Ap4[MP1]; /* bandwidth expanded LP parameters */ + Word16 *Az; /* pointer to Az_4: */ + /* LPC parameters in each subframe */ + Word16 i_subfr; /* index for beginning of subframe */ + Word16 h[L_H]; + + Word16 i; + Word16 temp1, temp2; + Word32 L_tmp; + Word16 *syn_work = &st->synth_buf[M]; move16 (); + + /*-----------------------------------------------------* + * Post filtering * + *-----------------------------------------------------*/ + + Copy (syn, syn_work , L_FRAME); + + Az = Az_4; + + for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) + { + /* Find weighted filter coefficients Ap3[] and ap[4] */ + + test (); test (); + if (sub(mode, MR122) == 0 || sub(mode, MR102) == 0) + { + Weight_Ai (Az, gamma3_MR122, Ap3); + Weight_Ai (Az, gamma4_MR122, Ap4); + } + else + { + Weight_Ai (Az, gamma3, Ap3); + Weight_Ai (Az, gamma4, Ap4); + } + + /* filtering of synthesis speech by A(z/0.7) to find res2[] */ + + Residu (Ap3, &syn_work[i_subfr], st->res2, L_SUBFR); + + /* tilt compensation filter */ + + /* impulse response of A(z/0.7)/A(z/0.75) */ + + Copy (Ap3, h, M + 1); + Set_zero (&h[M + 1], L_H - M - 1); + Syn_filt (Ap4, h, h, L_H, &h[M + 1], 0); + + /* 1st correlation of h[] */ + + L_tmp = L_mult (h[0], h[0]); + for (i = 1; i < L_H; i++) + { + L_tmp = L_mac (L_tmp, h[i], h[i]); + } + temp1 = extract_h (L_tmp); + + L_tmp = L_mult (h[0], h[1]); + for (i = 1; i < L_H - 1; i++) + { + L_tmp = L_mac (L_tmp, h[i], h[i + 1]); + } + temp2 = extract_h (L_tmp); + + test (); + if (temp2 <= 0) + { + temp2 = 0; move16 (); + } + else + { + temp2 = mult (temp2, MU); + temp2 = div_s (temp2, temp1); + } + + preemphasis (&st->preemph_state, st->res2, temp2, L_SUBFR); + + /* filtering through 1/A(z/0.75) */ + + Syn_filt (Ap4, st->res2, &syn[i_subfr], L_SUBFR, st->mem_syn_pst, 1); + + /* scale output to input */ + + agc (&st->agc_state, &syn_work[i_subfr], &syn[i_subfr], + AGC_FAC, L_SUBFR); + + Az += MP1; + } + + /* update syn_work[] buffer */ + + Copy (&syn_work[L_FRAME - M], &syn_work[-M], M); + + return 0; +}