FreeCalypso > hg > gsm-codec-lib
view libtwamr/pstfilt.c @ 478:936a08cc73ce
doc/AMR-library-API: describe the decoder
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 19 May 2024 21:32:31 +0000 |
parents | 59655481e45b |
children |
line wrap: on
line source
/************************************************************************* * * 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; }