123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287 |
- /*************************************************************************
- *
- * 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 "pstfilt.h"
- const char pstfilt_id[] = "@(#)$Id $" pstfilt_h;
-
- /*
- ********************************************************************************
- * INCLUDE FILES
- ********************************************************************************
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include "typedef.h"
- #include "mode.h"
- #include "basic_op.h"
- #include "set_zero.h"
- #include "weight_a.h"
- #include "residu.h"
- #include "copy.h"
- #include "syn_filt.h"
- #include "preemph.h"
- #include "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_init
- * Purpose: Allocates memory for filter structure and initializes
- * state memory
- *
- **************************************************************************
- */
- int Post_Filter_init (Post_FilterState **state)
- {
- Post_FilterState* s;
- if (state == (Post_FilterState **) NULL){
- wfprintf(stderr, "Post_Filter_init: invalid parameter\n");
- return -1;
- }
- *state = NULL;
- /* allocate memory */
- if ((s= (Post_FilterState *) wmalloc(sizeof(Post_FilterState))) == NULL){
- wfprintf(stderr, "Post_Filter_init: can not malloc state structure\n");
- return -1;
- }
- s->preemph_state = NULL;
- s->agc_state = NULL;
- if (preemphasis_init(&s->preemph_state) || agc_init(&s->agc_state)) {
- Post_Filter_exit(&s);
- return -1;
- }
-
- Post_Filter_reset(s);
- *state = s;
-
- return 0;
- }
- /*************************************************************************
- *
- * Function: Post_Filter_reset
- * Purpose: Initializes state memory to zero
- *
- **************************************************************************
- */
- int Post_Filter_reset (Post_FilterState *state)
- {
- if (state == (Post_FilterState *) NULL){
- wfprintf(stderr, "Post_Filter_reset: invalid parameter\n");
- return -1;
- }
-
- 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);
- return 0;
- }
- /*************************************************************************
- *
- * Function: Post_Filter_exit
- * Purpose: The memory used for state memory is freed
- *
- **************************************************************************
- */
- void Post_Filter_exit (Post_FilterState **state)
- {
- if (state == NULL || *state == NULL)
- return;
- agc_exit(&(*state)->agc_state);
- preemphasis_exit(&(*state)->preemph_state);
-
- /* deallocate memory */
- wfree(*state);
- *state = NULL;
-
- return;
- }
- /*
- **************************************************************************
- * 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_ex(mode, MR122) == 0 || sub_ex(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_ex (h[0], h[0]);
- for (i = 1; i < L_H; i++)
- {
- L_tmp = L_mac_ex (L_tmp, h[i], h[i]);
- }
- temp1 = extract_h_ex (L_tmp);
-
- L_tmp = L_mult_ex (h[0], h[1]);
- for (i = 1; i < L_H - 1; i++)
- {
- L_tmp = L_mac_ex (L_tmp, h[i], h[i + 1]);
- }
- temp2 = extract_h_ex (L_tmp);
-
- test ();
- if (temp2 <= 0)
- {
- temp2 = 0; move16 ();
- }
- else
- {
- temp2 = mult_ex (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;
- }
|