123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724 |
- /**********************************************************************
- Each of the companies; Lucent, Motorola, Nokia, and Qualcomm (hereinafter
- referred to individually as "Source" or collectively as "Sources") do
- hereby state:
- To the extent to which the Source(s) may legally and freely do so, the
- Source(s), upon submission of a Contribution, grant(s) a free,
- irrevocable, non-exclusive, license to the Third Generation Partnership
- Project 2 (3GPP2) and its Organizational Partners: ARIB, CCSA, TIA, TTA,
- and TTC, under the Source's copyright or copyright license rights in the
- Contribution, to, in whole or in part, copy, make derivative works,
- perform, display and distribute the Contribution and derivative works
- thereof consistent with 3GPP2's and each Organizational Partner's
- policies and procedures, with the right to (i) sublicense the foregoing
- rights consistent with 3GPP2's and each Organizational Partner's policies
- and procedures and (ii) copyright and sell, if applicable) in 3GPP2's name
- or each Organizational Partner's name any 3GPP2 or transposed Publication
- even though this Publication may contain the Contribution or a derivative
- work thereof. The Contribution shall disclose any known limitations on
- the Source's rights to license as herein provided.
- When a Contribution is submitted by the Source(s) to assist the
- formulating groups of 3GPP2 or any of its Organizational Partners, it
- is proposed to the Committee as a basis for discussion and is not to
- be construed as a binding proposal on the Source(s). The Source(s)
- specifically reserve(s) the right to amend or modify the material
- contained in the Contribution. Nothing contained in the Contribution
- shall, except as herein expressly provided, be construed as conferring
- by implication, estoppel or otherwise, any license or right under (i)
- any existing or later issuing patent, whether or not the use of
- information in the document necessarily employs an invention of any
- existing or later issued patent, (ii) any copyright, (iii) any
- trademark, or (iv) any other intellectual property right.
- With respect to the Software necessary for the practice of any or
- all Normative portions of the Enhanced Variable Rate Codec (EVRC) as
- it exists on the date of submittal of this form, should the EVRC be
- approved as a Specification or Report by 3GPP2, or as a transposed
- Standard by any of the 3GPP2's Organizational Partners, the Source(s)
- state(s) that a worldwide license to reproduce, use and distribute the
- Software, the license rights to which are held by the Source(s), will
- be made available to applicants under terms and conditions that are
- reasonable and non-discriminatory, which may include monetary compensation,
- and only to the extent necessary for the practice of any or all of the
- Normative portions of the EVRC or the field of use of practice of the
- EVRC Specification, Report, or Standard. The statement contained above
- is irrevocable and shall be binding upon the Source(s). In the event
- the rights of the Source(s) in and to copyright or copyright license
- rights subject to such commitment are assigned or transferred, the
- Source(s) shall notify the assignee or transferee of the existence of
- such commitments.
- *******************************************************************/
-
- /*======================================================================*/
- /* Enhanced Variable Rate Codec - Bit-Exact C Specification */
- /* Copyright (C) 1997-1998 Telecommunications Industry Association. */
- /* All rights reserved. */
- /*----------------------------------------------------------------------*/
- /* Note: Reproduction and use of this software for the design and */
- /* development of North American Wideband CDMA Digital */
- /* Cellular Telephony Standards is authorized by the TIA. */
- /* The TIA does not authorize the use of this software for any */
- /* other purpose. */
- /* */
- /* The availability of this software does not provide any license */
- /* by implication, estoppel, or otherwise under any patent rights */
- /* of TIA member companies or others covering any use of the */
- /* contents herein. */
- /* */
- /* Any copies of this software or derivative works must include */
- /* this and all other proprietary notices. */
- /*======================================================================*/
- /* ns127.c */
- /*****************************************************************
- *
- * EVRC Noise Suppression
- *
- * Input: The input to the function is a Shortword pointer to the
- * array of data to be noise suppressed.
- *
- * Output: There is no return value. The input array is replaced
- * with the noise suppressed values.
- *
- *
- * Written by: Tenkasi V. Ramabadran
- * Date: December 28, 1994
- *
- * Last Modified: James Ashley
- * Date: November 7, 1996
- *
- * Version Date Description
- *
- * 1.0 12/01/95 Released to TIA TR45.5.1.1
- * 1.1 02/14/96 Init Noise to first 4 frames
- * 1.2 02/19/96 Bug fix in frame_cnt declaration
- * 03/27/96 Revised for Fixed Point Calculations
- * 05/28/96 Adjust thresholds for -6 dB input level,
- * add block_norm/denorm around FFT/IFFT,
- * general scaling cleanup.
- * 1.3 08/09/96 Adjusted thresholds to 0dB input level,
- * Modified block_denormalization to provide 6 db adjustment.
- * 1.4 10/15/96 Apply block_norm call to farray_ptr instead of data_buffer
- * (fixes high level input problems). (JPA)
- * 1.5 11/07/96 Fix bug in block_norm(). (JPA)
- *****************************************************************/
- #include <stdio.h>
- /* Includes */
- //#include "mathevrc.h"
- #include "dsp_math.h"
- #include "mathdp31.h"
- #include "mathadv.h"
- /* Defines */
- #define FRM_LEN 80
- #define DELAY 24
- #define FFT_LEN 128
- #define NUM_CHAN 16
- #define LO_CHAN 0
- #define MID_CHAN 5
- #define HI_CHAN 15
- #define TRUE 1
- #define FALSE 0
- #define UPDATE_THLD 35
- #define METRIC_THLD 45
- #define INDEX_THLD 12
- #define SETBACK_THLD 12
- #define SNR_THLD 6
- #define INDEX_CNT_THLD 5
- #define HYSTER_CNT_THLD 6
- #define UPDATE_CNT_THLD 50
- /* Define the following if 0db input to ns */
- #define INPUT_0_DB
- #ifdef INPUT_MINUS_6_DB
- #define NOISE_FLOOR_CHAN 64 /* 1.0/4 scaled as 23,8 */
- #define MIN_CHAN_ENRG 4 /* 0.0625/4 scaled as 23,8 */
- #define MIN_NOISE_ENRG 4 /* 0.0625/4 scaled as 23,8 */
- #define INE_CHAN 1024 /* 16.0/4 scaled as 23,8 */
- #define INE_NOISE 1024 /* 16.0/4 scaled as 23,8 */
- #define HIGH_TCE_DB 1408 /* 44.0 scaled as 10,5 */
- #define LOW_TCE_DB 768 /* 24.0 scaled as 10,5 */
- #endif
- #ifdef INPUT_0_DB
- #define NOISE_FLOOR_CHAN 256 /* 1.0 scaled as 23,8 */
- #define MIN_CHAN_ENRG 16 /* 0.0625 scaled as 23,8 */
- #define MIN_NOISE_ENRG 16 /* 0.0625 scaled as 23,8 */
- #define INE_CHAN 4096 /* 16.0 scaled as 23,8 */
- #define INE_NOISE 4096 /* 16.0 scaled as 23,8 */
- #define HIGH_TCE_DB 1600 /* 50.0 scaled as 10,5 */
- #define LOW_TCE_DB 960 /* 30.0 scaled as 10,5 */
- #endif
- #define TCE_RANGE (HIGH_TCE_DB - LOW_TCE_DB)
- #define HIGH_ALPHA_S5_10 1023
- #define LOW_ALPHA_S5_10 511
- #define HIGH_ALPHA 32440 /* 0.99 scaled as 0,15 */
- #define LOW_ALPHA 16383 /* 0.50 scaled as 0,15 */
- #define ALPHA_RANGE (HIGH_ALPHA - LOW_ALPHA)
- #define ALPHA_RAN_DIV_TCE_RAN 803 /* (0.99 - 0.50) / 20 scaled as 0,15 */
- #define DEV_THLD 896 /* 28.0 scaled as 10,5 */
- #define PRE_EMP_FAC -26214 /* -0.8 scaled as 0,15 */
- #define CEE_SM_FAC 1181116006 /* 0.55 scaled as 0,31 */
- #define ONE_MINUS_CEE_SM_FAC 966367642 /* 0.55 scaled as 0,31 */
- #define MIN_GAIN -27262976 /* (-13.0) scaled as 11,20 */
- #define GAIN_SLOPE 14879 /* 0.45 scaled as 0,15 */
- #define CNE_SM_FAC 3277 /* 0.1 scaled as 0,15 */
- #define ONE_MINUS_CNE_SM_FAC (32767-CNE_SM_FAC)
- #define DE_EMP_FAC 26214 /* 0.8 scaled as 0,15 */
- #define LOG_OFFSET 626255212 /* 9.3319 scaled as 5,26 */
- #define ONE_OVER_20 1638 /* 1/20 scaled as 0,15 */
- #define TEN_S5_10 10270 /* 10.0 scaled as 5,10 */
- #define CONST_0_1875_S10_21 393216 /* 0.1875 scaled as 10,21 */
- #define CONST_2_667_S5_10 2731 /* 2.667 scaled as 5,10 */
- #define FFT_HEADROOM 2
- #define IFFT_HEADROOM 4
- /* Local functions */
- Shortword block_norm(Shortword * data, Shortword size, Shortword headroom)
- {
- Shortword i, max, scnt, adata;
- //max = abs(data[0]);
- max = abs_s(data[0]); //maolin 2014-07-22
- for (i = 1; i < size; i++)
- {
- //adata = abs(data[i]);
- adata = abs_s(data[i]); //maolin 2014-07-22
- if (adata > max)
- max = adata;
- }
- scnt = norm_s(max) - headroom;
- for (i = 0; i < size; i++)
- {
- data[i] = shift_r(data[i], scnt);
- }
- return (scnt);
- }
- void block_denorm(Shortword * data, Shortword size, Shortword scnt)
- {
- Shortword i;
- for (i = 0; i < size; i++)
- {
- data[i] = shift_r(data[i], negate(scnt));
- }
- return;
- }
- /* The noise supression function */
- void noise_suprs(Shortword * farray_ptr)
- {
- /*
- * The channel table is defined below. In this table, the
- * lower and higher frequency coefficients for each of the 16
- * channels are specified. The table excludes the coefficients
- * with numbers 0 (DC), 1, and 64 (Foldover frequency). For
- * these coefficients, the gain is always set at 1.0 (0 dB).
- */
- static Shortword ch_tbl[NUM_CHAN][2] =
- {
- {2, 3},
- {4, 5},
- {6, 7},
- {8, 9},
- {10, 11},
- {12, 13},
- {14, 16},
- {17, 19},
- {20, 22},
- {23, 26},
- {27, 30},
- {31, 35},
- {36, 41},
- {42, 48},
- {49, 55},
- {56, 63}
- };
- static Shortword ch_tbl_sh[NUM_CHAN][2] =
- {
- {TRUE, 1},
- {TRUE, 1},
- {TRUE, 1},
- {TRUE, 1},
- {TRUE, 1},
- {TRUE, 1},
- {FALSE, 10922},
- {FALSE, 10922},
- {FALSE, 10922},
- {TRUE, 2},
- {TRUE, 2},
- {FALSE, 6553},
- {FALSE, 5462},
- {FALSE, 4681},
- {FALSE, 4681},
- {TRUE, 3}
- };
- /*
- * The voice metric table is defined below. It is a non-
- * linear table with a deadband near zero. It maps the SNR
- * index (quantized SNR value) to a number that is a measure
- * of voice quality.
- */
- static int vm_tbl[90] =
- {
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 3, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7,
- 8, 8, 9, 9, 10, 10, 11, 12, 12, 13, 13, 14, 15,
- 15, 16, 17, 17, 18, 19, 20, 20, 21, 22, 23, 24,
- 24, 25, 26, 27, 28, 28, 29, 30, 31, 32, 33, 34,
- 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45,
- 46, 47, 48, 49, 50, 50, 50, 50, 50, 50, 50, 50,
- 50, 50
- };
- static Shortword window[DELAY + FRM_LEN] =
- {
- 35, 315, 869, 1690, 2761, 4066, 5581, 7281, 9137,
- 11117, 13187, 15312, 17455, 19580, 21650, 23630,
- 25486, 27186, 28701, 30006, 31077, 31898, 32452,
- 32732, 32767, 32767, 32767, 32767, 32767, 32767,
- 32767, 32767, 32767, 32767, 32767, 32767, 32767,
- 32767, 32767, 32767, 32767, 32767, 32767, 32767,
- 32767, 32767, 32767, 32767, 32767, 32767, 32767,
- 32767, 32767, 32767, 32767, 32767, 32767, 32767,
- 32767, 32767, 32767, 32767, 32767, 32767, 32767,
- 32767, 32767, 32767, 32767, 32767, 32767, 32767,
- 32767, 32767, 32767, 32767, 32767, 32767, 32767,
- 32767, 32732, 32452, 31898, 31077, 30006, 28701,
- 27186, 25486, 23630, 21650, 19580, 17455, 15312,
- 13187, 11117, 9137, 7281, 5581, 4066, 2761, 1690,
- 869, 315, 35
- };
- static Shortword first = TRUE;
- static Shortword pre_emp_mem;
- static Shortword de_emp_mem;
- static Shortword overlap[FFT_LEN - FRM_LEN];
- static Shortword ch_gain[FFT_LEN / 2]; /* scaled as 0,15 */
- static Shortword update_cnt;
- static Shortword window_overlap[DELAY];
- static Shortword hyster_cnt;
- static Shortword last_update_cnt;
- static Shortword ch_enrg_long_db[NUM_CHAN]; /* scaled as 10,5 */
- static Longword frame_cnt;
- static Longword ch_enrg[NUM_CHAN]; /* scaled as 23,8 */
- static Longword ch_noise[NUM_CHAN]; /* scaled as 15,16 (change to 23,8) */
- static Shortword last_normb_shift; /* last block norm shift count */
- Longword enrg; /* scaled as 30,1 */
- Longword tne; /* scaled as 15,16 (change to 23,8) */
- Longword tce; /* scaled as 23,8 */
- Longword gain; /* scaled as 11,20 */
- Shortword data_buffer[FFT_LEN];
- Shortword ch_snr[NUM_CHAN]; /* scaled as 15,0 */
- Shortword ftmp2; /* scaled as 0,15 */
- Shortword vm_sum; /* scaled as 15,0 */
- Shortword ch_enrg_dev; /* scaled as 10,5 */
- Shortword ch_enrg_db[NUM_CHAN]; /* scaled as 10,5 */
- Shortword alpha; /* scaled as 0,15 */
- int i, j, j1, j2;
- int update_flag, modify_flag, index_cnt;
- Longword Ltmp, Ltmp1, Ltmp2, Ltmp3;
- Shortword tmp, tmp1, tmp2, norm_shift, norm_shift1;
- Shortword normb_shift; /* block norm shift count */
- /* Functions */
- void r_fft(short *, short);
- /* Init the window function, channel gains one time */
- if (first == TRUE)
- {
- ch_gain[0] = ch_gain[1] = SW_MAX;
- for (i = LO_CHAN; i <= HI_CHAN; i++)
- ch_enrg[i] = 0;
- for (i = 0; i < DELAY; i++)
- window_overlap[i] = 0;
- for (i = 0; i < FFT_LEN - FRM_LEN; i++)
- overlap[i] = 0;
- pre_emp_mem = 0;
- de_emp_mem = 0;
- update_cnt = 0;
- frame_cnt = 0;
- }
- /* Increment frame counter */
- frame_cnt++;
- /* Block normalize the input */
- normb_shift = block_norm(farray_ptr, FRM_LEN, FFT_HEADROOM);
- /*
- * Preemphasize the input data and store in the data buffer with
- * appropriate delay
- */
- for (i = 0; i < DELAY; i++)
- data_buffer[i] = shift_r(window_overlap[i], normb_shift-last_normb_shift);
- pre_emp_mem = shift_r(pre_emp_mem, normb_shift-last_normb_shift);
- last_normb_shift = normb_shift;
- data_buffer[DELAY] = add(*farray_ptr, mult(PRE_EMP_FAC, pre_emp_mem));
- for (i = DELAY + 1, j = 1; i < DELAY + FRM_LEN; i++, j++)
- data_buffer[i] = add(*(farray_ptr + j), mult(PRE_EMP_FAC, *(farray_ptr + j - 1)));
- pre_emp_mem = *(farray_ptr + FRM_LEN - 1);
- for (i = DELAY + FRM_LEN; i < FFT_LEN; i++)
- data_buffer[i] = 0;
- /* update window_overlap buffer */
- for (i = 0, j = FRM_LEN; i < DELAY; i++, j++)
- window_overlap[i] = data_buffer[j];
- /* Apply window to frame prior to FFT */
- for (i = 0; i < FRM_LEN + DELAY; i++)
- data_buffer[i] = mult_r(data_buffer[i], window[i]);
- /* Perform FFT on the data buffer */
- r_fft(data_buffer, +1);
- /* Estimate the energy in each channel */
- for (i = LO_CHAN; i <= HI_CHAN; i++)
- {
- enrg = 0;
- j1 = ch_tbl[i][0];
- j2 = ch_tbl[i][1];
- for (j = j1; j <= j2; j++)
- {
- enrg = L_mac(enrg, data_buffer[2 * j], data_buffer[2 * j]);
- enrg = L_mac(enrg, data_buffer[2 * j + 1], data_buffer[2 * j + 1]);
- }
- if (ch_tbl_sh[i][0] == TRUE)
- enrg = L_shr(enrg, ch_tbl_sh[i][1]);
- else
- {
- norm_shift = norm_l(enrg);
- tmp = extract_h(L_shl(enrg, norm_shift));
- enrg = L_mult(tmp, ch_tbl_sh[i][1]);
- enrg = L_shr(enrg, norm_shift);
- }
- if (first == TRUE)
- ch_enrg[i] = L_shl(enrg, 7 - (2 * normb_shift)); /* rescaled from 30,1 to 23,8 (w/block denorm) */
- else
- {
- norm_shift = norm_l(enrg);
- Ltmp1 = L_shl(enrg, norm_shift);
- Ltmp1 = L_mpy_ls(CEE_SM_FAC, extract_h(Ltmp1));
- Ltmp1 = L_shr(Ltmp1, norm_shift);
- Ltmp2 = L_shl(Ltmp1, 7 - (2 * normb_shift)); /* rescaled from 30,1 to 23,8 (w/block denorm) */
- norm_shift = norm_l(ch_enrg[i]);
- Ltmp1 = L_shl(ch_enrg[i], norm_shift);
- Ltmp3 = L_mpy_ls(ONE_MINUS_CEE_SM_FAC, extract_h(Ltmp1));
- Ltmp3 = L_shr(Ltmp3, norm_shift);
- ch_enrg[i] = L_add(Ltmp3, Ltmp2);
- }
- if (ch_enrg[i] < MIN_CHAN_ENRG)
- ch_enrg[i] = MIN_CHAN_ENRG;
- }
- /* Initialize channel noise estimate to channel energy of first four frames */
- if (frame_cnt <= 4)
- {
- for (i = LO_CHAN; i <= HI_CHAN; i++)
- {
- if (ch_enrg[i] < INE_CHAN)
- ch_noise[i] = INE_NOISE;
- else
- ch_noise[i] = ch_enrg[i];
- }
- }
- /* Compute the channel SNR indices */
- for (i = LO_CHAN; i <= HI_CHAN; i++)
- {
- norm_shift = norm_l(ch_noise[i]);
- Ltmp = L_shl(ch_noise[i], norm_shift);
- norm_shift1 = norm_l(ch_enrg[i]);
- Ltmp3 = L_shl(ch_enrg[i], norm_shift1 - 1);
- Ltmp2 = L_divide(Ltmp3, Ltmp);
- Ltmp2 = L_shr(Ltmp2, 27 - 1 + norm_shift1 - norm_shift); /* scaled as 27,4 */
- if (Ltmp2 == 0)
- Ltmp2 = 1;
- Ltmp1 = fnLog10(Ltmp2);
- Ltmp3 = L_add(Ltmp1, LOG_OFFSET - 80807124); /* -round32(log10(2^4)*2^26 */
- Ltmp2 = L_mult(TEN_S5_10, extract_h(Ltmp3));
- if (Ltmp2 < 0)
- Ltmp2 = 0;
- /* 0.1875 scaled as 10,21 */
- Ltmp1 = L_add(Ltmp2, CONST_0_1875_S10_21);
- /* tmp / 0.375 2.667 scaled as 5,10, Ltmp is scaled 15,16 */
- Ltmp = L_mult(extract_h(Ltmp1), CONST_2_667_S5_10);
- ch_snr[i] = extract_h(Ltmp);
- }
- /* Compute the sum of voice metrics */
- vm_sum = 0;
- for (i = LO_CHAN; i <= HI_CHAN; i++)
- {
- if (ch_snr[i] < 89)
- j = ch_snr[i];
- else
- j = 89;
- vm_sum = add(vm_sum, vm_tbl[j]);
- }
- /* Compute the total noise estimate (tne) and total channel energy estimate (tce) */
- tne = tce = 0;
- for (i = LO_CHAN; i <= HI_CHAN; i++)
- {
- tne = L_add(tne, ch_noise[i]);
- tce = L_add(tce, ch_enrg[i]);
- }
- /* Calculate log spectral deviation */
- for (i = LO_CHAN; i <= HI_CHAN; i++)
- {
- Ltmp = ch_enrg[i];
- if (Ltmp == 0)
- Ltmp = 1;
- Ltmp1 = fnLog10(Ltmp);
- Ltmp2 = L_add(Ltmp1, LOG_OFFSET - 161614248); /* -round32(log10(2^8)*2^26) */
- ch_enrg_db[i] = mult(TEN_S5_10, extract_h(Ltmp2));
- }
- if (first == TRUE)
- for (i = LO_CHAN; i <= HI_CHAN; i++)
- ch_enrg_long_db[i] = ch_enrg_db[i];
- ch_enrg_dev = 0;
- for (i = LO_CHAN; i <= HI_CHAN; i++)
- {
- tmp = abs_s(sub(ch_enrg_long_db[i], ch_enrg_db[i]));
- ch_enrg_dev = add(ch_enrg_dev, tmp);
- }
- /*
- * Calculate long term integration constant as a function of total channel energy (tce)
- * (i.e., high tce (-40 dB) -> slow integration (alpha = 0.99),
- * low tce (-60 dB) -> fast integration (alpha = 0.50)
- */
- Ltmp1 = fnLog10(tce);
- Ltmp2 = L_add(Ltmp1, LOG_OFFSET - 161614248); /* -round32(log10(2^8)*2^26) */
- tmp = mult(TEN_S5_10, extract_h(Ltmp2));
- tmp2 = sub(HIGH_TCE_DB, tmp); /* HIGH_TCE_DB and tmp scaled as 10,5 */
- tmp2 = shl(tmp2, 5); /* move scale to 5,10 get more fraction */
- tmp1 = mult(ALPHA_RAN_DIV_TCE_RAN, tmp2);
- alpha = sub(HIGH_ALPHA_S5_10, tmp1);
- if (alpha > HIGH_ALPHA_S5_10)
- alpha = HIGH_ALPHA;
- else if (alpha < LOW_ALPHA_S5_10)
- alpha = LOW_ALPHA;
- else
- alpha = shl(alpha, 5); /* rescale from 5,10 to 0,15 alpha is a fraction */
- /* Calc long term log spectral energy */
- tmp = sub(SW_MAX, alpha);
- for (i = LO_CHAN; i <= HI_CHAN; i++)
- {
- Ltmp1 = L_mult(tmp, ch_enrg_db[i]);
- Ltmp2 = L_mult(alpha, ch_enrg_long_db[i]);
- ch_enrg_long_db[i] = extract_h(L_add(Ltmp1, Ltmp2));
- }
- /* Set or reset the update flag */
- update_flag = FALSE;
- if (vm_sum <= UPDATE_THLD)
- {
- update_flag = TRUE;
- update_cnt = 0;
- }
- else if (tce > NOISE_FLOOR_CHAN && ch_enrg_dev < DEV_THLD)
- {
- update_cnt++;
- if (update_cnt >= UPDATE_CNT_THLD)
- update_flag = TRUE;
- }
- if (update_cnt == last_update_cnt)
- hyster_cnt++;
- else
- hyster_cnt = 0;
- last_update_cnt = update_cnt;
- if (hyster_cnt > HYSTER_CNT_THLD)
- update_cnt = 0;
- /* Set or reset modify flag */
- index_cnt = 0;
- for (i = MID_CHAN; i <= HI_CHAN; i++)
- if (ch_snr[i] >= INDEX_THLD)
- index_cnt++;
- modify_flag = (index_cnt < INDEX_CNT_THLD) ? TRUE : FALSE;
- /* Modify the SNR indices */
- if (modify_flag == TRUE)
- {
- for (i = LO_CHAN; i <= HI_CHAN; i++)
- if ((vm_sum <= METRIC_THLD) || (ch_snr[i] <= SETBACK_THLD))
- ch_snr[i] = 1;
- }
- /* Compute the channel gains */
- Ltmp1 = fnLog10(tne);
- Ltmp1 = L_add(Ltmp1, LOG_OFFSET - 161614248); /* -round32(log10(2^8)*2^26) */
- Ltmp1 = L_negate(Ltmp1);
- gain = L_mpy_ls(Ltmp1, TEN_S5_10);
- if (gain < MIN_GAIN)
- gain = MIN_GAIN;
- for (i = LO_CHAN; i <= HI_CHAN; i++)
- {
- if (ch_snr[i] <= SNR_THLD)
- ch_snr[i] = SNR_THLD;
- tmp = sub(ch_snr[i], SNR_THLD);
- Ltmp1 = L_mult(tmp, GAIN_SLOPE);
- Ltmp2 = L_shl(Ltmp1, 5); /* rescaled to 10,5 */
- Ltmp = L_add(Ltmp2, gain); /* gain scaled as 10,5 */
- if (Ltmp > 0)
- Ltmp = 0;
- Ltmp1 = L_mpy_ls(Ltmp, ONE_OVER_20);
- Ltmp1 = L_shl(Ltmp1, 5); /* rescale Ltmp1 to 5,26 */
- if (Ltmp1 == 0)
- Ltmp1 = -1;
- Ltmp2 = fnExp10(Ltmp1);
- ftmp2 = extract_h(Ltmp2);
- j1 = ch_tbl[i][0], j2 = ch_tbl[i][1];
- for (j = j1; j <= j2; j++)
- {
- ch_gain[j] = ftmp2;
- }
- }
- /* Update the channel noise estimates */
- if (update_flag == TRUE)
- {
- for (i = LO_CHAN; i <= HI_CHAN; i++)
- {
- norm_shift = norm_l(ch_noise[i]);
- Ltmp = L_shl(ch_noise[i], norm_shift);
- Ltmp1 = L_mult(extract_h(Ltmp), ONE_MINUS_CNE_SM_FAC);
- Ltmp1 = L_shr(Ltmp1, norm_shift);
- norm_shift = norm_l(ch_enrg[i]);
- Ltmp = L_shl(ch_enrg[i], norm_shift);
- Ltmp2 = L_mult(extract_h(Ltmp), CNE_SM_FAC);
- Ltmp2 = L_shr(Ltmp2, norm_shift);
- ch_noise[i] = L_add(Ltmp1, Ltmp2);
- if (ch_noise[i] < MIN_NOISE_ENRG)
- ch_noise[i] = MIN_NOISE_ENRG;
- }
- }
- /* Filter the input data in the frequency domain and perform IFFT */
- for (i = 0; i < FFT_LEN / 2; i++)
- {
- data_buffer[2 * i] = mult(data_buffer[2 * i], ch_gain[i]);
- data_buffer[2 * i + 1] = mult(data_buffer[2 * i + 1], ch_gain[i]);
- }
- /* Block normalize data_buffer */
- norm_shift = block_norm(data_buffer, FFT_LEN, IFFT_HEADROOM);
- /* Inverse FFT */
- r_fft(data_buffer, -1);
- /* Block denormalize data_buffer */
- /* block_denorm(data_buffer, FFT_LEN, normb_shift + norm_shift); */
- block_denorm(data_buffer, FFT_LEN, normb_shift + norm_shift + 1);
- /* Overlap add the filtered data from previous block.
- * Save data from this block for the next. */
- for (i = 0; i < FFT_LEN - FRM_LEN; i++)
- data_buffer[i] = add(data_buffer[i], overlap[i]);
- for (i = FRM_LEN; i < FFT_LEN; i++)
- overlap[i - FRM_LEN] = data_buffer[i];
- /* Deemphasize the filtered speech and write it out to farray */
- tmp = mult(DE_EMP_FAC, de_emp_mem);
- *farray_ptr = add(data_buffer[0], tmp);
- for (i = 1; i < FRM_LEN; i++)
- {
- tmp = mult_r(DE_EMP_FAC, *(farray_ptr + i - 1));
- *(farray_ptr + i) = add(data_buffer[i], tmp);
- }
- de_emp_mem = *(farray_ptr + FRM_LEN - 1);
- first = FALSE;
- } /* end noise_suprs () */
|