ns127.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724
  1. /**********************************************************************
  2. Each of the companies; Lucent, Motorola, Nokia, and Qualcomm (hereinafter
  3. referred to individually as "Source" or collectively as "Sources") do
  4. hereby state:
  5. To the extent to which the Source(s) may legally and freely do so, the
  6. Source(s), upon submission of a Contribution, grant(s) a free,
  7. irrevocable, non-exclusive, license to the Third Generation Partnership
  8. Project 2 (3GPP2) and its Organizational Partners: ARIB, CCSA, TIA, TTA,
  9. and TTC, under the Source's copyright or copyright license rights in the
  10. Contribution, to, in whole or in part, copy, make derivative works,
  11. perform, display and distribute the Contribution and derivative works
  12. thereof consistent with 3GPP2's and each Organizational Partner's
  13. policies and procedures, with the right to (i) sublicense the foregoing
  14. rights consistent with 3GPP2's and each Organizational Partner's policies
  15. and procedures and (ii) copyright and sell, if applicable) in 3GPP2's name
  16. or each Organizational Partner's name any 3GPP2 or transposed Publication
  17. even though this Publication may contain the Contribution or a derivative
  18. work thereof. The Contribution shall disclose any known limitations on
  19. the Source's rights to license as herein provided.
  20. When a Contribution is submitted by the Source(s) to assist the
  21. formulating groups of 3GPP2 or any of its Organizational Partners, it
  22. is proposed to the Committee as a basis for discussion and is not to
  23. be construed as a binding proposal on the Source(s). The Source(s)
  24. specifically reserve(s) the right to amend or modify the material
  25. contained in the Contribution. Nothing contained in the Contribution
  26. shall, except as herein expressly provided, be construed as conferring
  27. by implication, estoppel or otherwise, any license or right under (i)
  28. any existing or later issuing patent, whether or not the use of
  29. information in the document necessarily employs an invention of any
  30. existing or later issued patent, (ii) any copyright, (iii) any
  31. trademark, or (iv) any other intellectual property right.
  32. With respect to the Software necessary for the practice of any or
  33. all Normative portions of the Enhanced Variable Rate Codec (EVRC) as
  34. it exists on the date of submittal of this form, should the EVRC be
  35. approved as a Specification or Report by 3GPP2, or as a transposed
  36. Standard by any of the 3GPP2's Organizational Partners, the Source(s)
  37. state(s) that a worldwide license to reproduce, use and distribute the
  38. Software, the license rights to which are held by the Source(s), will
  39. be made available to applicants under terms and conditions that are
  40. reasonable and non-discriminatory, which may include monetary compensation,
  41. and only to the extent necessary for the practice of any or all of the
  42. Normative portions of the EVRC or the field of use of practice of the
  43. EVRC Specification, Report, or Standard. The statement contained above
  44. is irrevocable and shall be binding upon the Source(s). In the event
  45. the rights of the Source(s) in and to copyright or copyright license
  46. rights subject to such commitment are assigned or transferred, the
  47. Source(s) shall notify the assignee or transferee of the existence of
  48. such commitments.
  49. *******************************************************************/
  50. /*======================================================================*/
  51. /* Enhanced Variable Rate Codec - Bit-Exact C Specification */
  52. /* Copyright (C) 1997-1998 Telecommunications Industry Association. */
  53. /* All rights reserved. */
  54. /*----------------------------------------------------------------------*/
  55. /* Note: Reproduction and use of this software for the design and */
  56. /* development of North American Wideband CDMA Digital */
  57. /* Cellular Telephony Standards is authorized by the TIA. */
  58. /* The TIA does not authorize the use of this software for any */
  59. /* other purpose. */
  60. /* */
  61. /* The availability of this software does not provide any license */
  62. /* by implication, estoppel, or otherwise under any patent rights */
  63. /* of TIA member companies or others covering any use of the */
  64. /* contents herein. */
  65. /* */
  66. /* Any copies of this software or derivative works must include */
  67. /* this and all other proprietary notices. */
  68. /*======================================================================*/
  69. /* ns127.c */
  70. /*****************************************************************
  71. *
  72. * EVRC Noise Suppression
  73. *
  74. * Input: The input to the function is a Shortword pointer to the
  75. * array of data to be noise suppressed.
  76. *
  77. * Output: There is no return value. The input array is replaced
  78. * with the noise suppressed values.
  79. *
  80. *
  81. * Written by: Tenkasi V. Ramabadran
  82. * Date: December 28, 1994
  83. *
  84. * Last Modified: James Ashley
  85. * Date: November 7, 1996
  86. *
  87. * Version Date Description
  88. *
  89. * 1.0 12/01/95 Released to TIA TR45.5.1.1
  90. * 1.1 02/14/96 Init Noise to first 4 frames
  91. * 1.2 02/19/96 Bug fix in frame_cnt declaration
  92. * 03/27/96 Revised for Fixed Point Calculations
  93. * 05/28/96 Adjust thresholds for -6 dB input level,
  94. * add block_norm/denorm around FFT/IFFT,
  95. * general scaling cleanup.
  96. * 1.3 08/09/96 Adjusted thresholds to 0dB input level,
  97. * Modified block_denormalization to provide 6 db adjustment.
  98. * 1.4 10/15/96 Apply block_norm call to farray_ptr instead of data_buffer
  99. * (fixes high level input problems). (JPA)
  100. * 1.5 11/07/96 Fix bug in block_norm(). (JPA)
  101. *****************************************************************/
  102. #include <stdio.h>
  103. /* Includes */
  104. //#include "mathevrc.h"
  105. #include "dsp_math.h"
  106. #include "mathdp31.h"
  107. #include "mathadv.h"
  108. /* Defines */
  109. #define FRM_LEN 80
  110. #define DELAY 24
  111. #define FFT_LEN 128
  112. #define NUM_CHAN 16
  113. #define LO_CHAN 0
  114. #define MID_CHAN 5
  115. #define HI_CHAN 15
  116. #define TRUE 1
  117. #define FALSE 0
  118. #define UPDATE_THLD 35
  119. #define METRIC_THLD 45
  120. #define INDEX_THLD 12
  121. #define SETBACK_THLD 12
  122. #define SNR_THLD 6
  123. #define INDEX_CNT_THLD 5
  124. #define HYSTER_CNT_THLD 6
  125. #define UPDATE_CNT_THLD 50
  126. /* Define the following if 0db input to ns */
  127. #define INPUT_0_DB
  128. #ifdef INPUT_MINUS_6_DB
  129. #define NOISE_FLOOR_CHAN 64 /* 1.0/4 scaled as 23,8 */
  130. #define MIN_CHAN_ENRG 4 /* 0.0625/4 scaled as 23,8 */
  131. #define MIN_NOISE_ENRG 4 /* 0.0625/4 scaled as 23,8 */
  132. #define INE_CHAN 1024 /* 16.0/4 scaled as 23,8 */
  133. #define INE_NOISE 1024 /* 16.0/4 scaled as 23,8 */
  134. #define HIGH_TCE_DB 1408 /* 44.0 scaled as 10,5 */
  135. #define LOW_TCE_DB 768 /* 24.0 scaled as 10,5 */
  136. #endif
  137. #ifdef INPUT_0_DB
  138. #define NOISE_FLOOR_CHAN 256 /* 1.0 scaled as 23,8 */
  139. #define MIN_CHAN_ENRG 16 /* 0.0625 scaled as 23,8 */
  140. #define MIN_NOISE_ENRG 16 /* 0.0625 scaled as 23,8 */
  141. #define INE_CHAN 4096 /* 16.0 scaled as 23,8 */
  142. #define INE_NOISE 4096 /* 16.0 scaled as 23,8 */
  143. #define HIGH_TCE_DB 1600 /* 50.0 scaled as 10,5 */
  144. #define LOW_TCE_DB 960 /* 30.0 scaled as 10,5 */
  145. #endif
  146. #define TCE_RANGE (HIGH_TCE_DB - LOW_TCE_DB)
  147. #define HIGH_ALPHA_S5_10 1023
  148. #define LOW_ALPHA_S5_10 511
  149. #define HIGH_ALPHA 32440 /* 0.99 scaled as 0,15 */
  150. #define LOW_ALPHA 16383 /* 0.50 scaled as 0,15 */
  151. #define ALPHA_RANGE (HIGH_ALPHA - LOW_ALPHA)
  152. #define ALPHA_RAN_DIV_TCE_RAN 803 /* (0.99 - 0.50) / 20 scaled as 0,15 */
  153. #define DEV_THLD 896 /* 28.0 scaled as 10,5 */
  154. #define PRE_EMP_FAC -26214 /* -0.8 scaled as 0,15 */
  155. #define CEE_SM_FAC 1181116006 /* 0.55 scaled as 0,31 */
  156. #define ONE_MINUS_CEE_SM_FAC 966367642 /* 0.55 scaled as 0,31 */
  157. #define MIN_GAIN -27262976 /* (-13.0) scaled as 11,20 */
  158. #define GAIN_SLOPE 14879 /* 0.45 scaled as 0,15 */
  159. #define CNE_SM_FAC 3277 /* 0.1 scaled as 0,15 */
  160. #define ONE_MINUS_CNE_SM_FAC (32767-CNE_SM_FAC)
  161. #define DE_EMP_FAC 26214 /* 0.8 scaled as 0,15 */
  162. #define LOG_OFFSET 626255212 /* 9.3319 scaled as 5,26 */
  163. #define ONE_OVER_20 1638 /* 1/20 scaled as 0,15 */
  164. #define TEN_S5_10 10270 /* 10.0 scaled as 5,10 */
  165. #define CONST_0_1875_S10_21 393216 /* 0.1875 scaled as 10,21 */
  166. #define CONST_2_667_S5_10 2731 /* 2.667 scaled as 5,10 */
  167. #define FFT_HEADROOM 2
  168. #define IFFT_HEADROOM 4
  169. /* Local functions */
  170. Shortword block_norm(Shortword * data, Shortword size, Shortword headroom)
  171. {
  172. Shortword i, max, scnt, adata;
  173. //max = abs(data[0]);
  174. max = abs_s(data[0]); //maolin 2014-07-22
  175. for (i = 1; i < size; i++)
  176. {
  177. //adata = abs(data[i]);
  178. adata = abs_s(data[i]); //maolin 2014-07-22
  179. if (adata > max)
  180. max = adata;
  181. }
  182. scnt = norm_s(max) - headroom;
  183. for (i = 0; i < size; i++)
  184. {
  185. data[i] = shift_r(data[i], scnt);
  186. }
  187. return (scnt);
  188. }
  189. void block_denorm(Shortword * data, Shortword size, Shortword scnt)
  190. {
  191. Shortword i;
  192. for (i = 0; i < size; i++)
  193. {
  194. data[i] = shift_r(data[i], negate(scnt));
  195. }
  196. return;
  197. }
  198. /* The noise supression function */
  199. void noise_suprs(Shortword * farray_ptr)
  200. {
  201. /*
  202. * The channel table is defined below. In this table, the
  203. * lower and higher frequency coefficients for each of the 16
  204. * channels are specified. The table excludes the coefficients
  205. * with numbers 0 (DC), 1, and 64 (Foldover frequency). For
  206. * these coefficients, the gain is always set at 1.0 (0 dB).
  207. */
  208. static Shortword ch_tbl[NUM_CHAN][2] =
  209. {
  210. {2, 3},
  211. {4, 5},
  212. {6, 7},
  213. {8, 9},
  214. {10, 11},
  215. {12, 13},
  216. {14, 16},
  217. {17, 19},
  218. {20, 22},
  219. {23, 26},
  220. {27, 30},
  221. {31, 35},
  222. {36, 41},
  223. {42, 48},
  224. {49, 55},
  225. {56, 63}
  226. };
  227. static Shortword ch_tbl_sh[NUM_CHAN][2] =
  228. {
  229. {TRUE, 1},
  230. {TRUE, 1},
  231. {TRUE, 1},
  232. {TRUE, 1},
  233. {TRUE, 1},
  234. {TRUE, 1},
  235. {FALSE, 10922},
  236. {FALSE, 10922},
  237. {FALSE, 10922},
  238. {TRUE, 2},
  239. {TRUE, 2},
  240. {FALSE, 6553},
  241. {FALSE, 5462},
  242. {FALSE, 4681},
  243. {FALSE, 4681},
  244. {TRUE, 3}
  245. };
  246. /*
  247. * The voice metric table is defined below. It is a non-
  248. * linear table with a deadband near zero. It maps the SNR
  249. * index (quantized SNR value) to a number that is a measure
  250. * of voice quality.
  251. */
  252. static int vm_tbl[90] =
  253. {
  254. 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  255. 3, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7,
  256. 8, 8, 9, 9, 10, 10, 11, 12, 12, 13, 13, 14, 15,
  257. 15, 16, 17, 17, 18, 19, 20, 20, 21, 22, 23, 24,
  258. 24, 25, 26, 27, 28, 28, 29, 30, 31, 32, 33, 34,
  259. 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45,
  260. 46, 47, 48, 49, 50, 50, 50, 50, 50, 50, 50, 50,
  261. 50, 50
  262. };
  263. static Shortword window[DELAY + FRM_LEN] =
  264. {
  265. 35, 315, 869, 1690, 2761, 4066, 5581, 7281, 9137,
  266. 11117, 13187, 15312, 17455, 19580, 21650, 23630,
  267. 25486, 27186, 28701, 30006, 31077, 31898, 32452,
  268. 32732, 32767, 32767, 32767, 32767, 32767, 32767,
  269. 32767, 32767, 32767, 32767, 32767, 32767, 32767,
  270. 32767, 32767, 32767, 32767, 32767, 32767, 32767,
  271. 32767, 32767, 32767, 32767, 32767, 32767, 32767,
  272. 32767, 32767, 32767, 32767, 32767, 32767, 32767,
  273. 32767, 32767, 32767, 32767, 32767, 32767, 32767,
  274. 32767, 32767, 32767, 32767, 32767, 32767, 32767,
  275. 32767, 32767, 32767, 32767, 32767, 32767, 32767,
  276. 32767, 32732, 32452, 31898, 31077, 30006, 28701,
  277. 27186, 25486, 23630, 21650, 19580, 17455, 15312,
  278. 13187, 11117, 9137, 7281, 5581, 4066, 2761, 1690,
  279. 869, 315, 35
  280. };
  281. static Shortword first = TRUE;
  282. static Shortword pre_emp_mem;
  283. static Shortword de_emp_mem;
  284. static Shortword overlap[FFT_LEN - FRM_LEN];
  285. static Shortword ch_gain[FFT_LEN / 2]; /* scaled as 0,15 */
  286. static Shortword update_cnt;
  287. static Shortword window_overlap[DELAY];
  288. static Shortword hyster_cnt;
  289. static Shortword last_update_cnt;
  290. static Shortword ch_enrg_long_db[NUM_CHAN]; /* scaled as 10,5 */
  291. static Longword frame_cnt;
  292. static Longword ch_enrg[NUM_CHAN]; /* scaled as 23,8 */
  293. static Longword ch_noise[NUM_CHAN]; /* scaled as 15,16 (change to 23,8) */
  294. static Shortword last_normb_shift; /* last block norm shift count */
  295. Longword enrg; /* scaled as 30,1 */
  296. Longword tne; /* scaled as 15,16 (change to 23,8) */
  297. Longword tce; /* scaled as 23,8 */
  298. Longword gain; /* scaled as 11,20 */
  299. Shortword data_buffer[FFT_LEN];
  300. Shortword ch_snr[NUM_CHAN]; /* scaled as 15,0 */
  301. Shortword ftmp2; /* scaled as 0,15 */
  302. Shortword vm_sum; /* scaled as 15,0 */
  303. Shortword ch_enrg_dev; /* scaled as 10,5 */
  304. Shortword ch_enrg_db[NUM_CHAN]; /* scaled as 10,5 */
  305. Shortword alpha; /* scaled as 0,15 */
  306. int i, j, j1, j2;
  307. int update_flag, modify_flag, index_cnt;
  308. Longword Ltmp, Ltmp1, Ltmp2, Ltmp3;
  309. Shortword tmp, tmp1, tmp2, norm_shift, norm_shift1;
  310. Shortword normb_shift; /* block norm shift count */
  311. /* Functions */
  312. void r_fft(short *, short);
  313. /* Init the window function, channel gains one time */
  314. if (first == TRUE)
  315. {
  316. ch_gain[0] = ch_gain[1] = SW_MAX;
  317. for (i = LO_CHAN; i <= HI_CHAN; i++)
  318. ch_enrg[i] = 0;
  319. for (i = 0; i < DELAY; i++)
  320. window_overlap[i] = 0;
  321. for (i = 0; i < FFT_LEN - FRM_LEN; i++)
  322. overlap[i] = 0;
  323. pre_emp_mem = 0;
  324. de_emp_mem = 0;
  325. update_cnt = 0;
  326. frame_cnt = 0;
  327. }
  328. /* Increment frame counter */
  329. frame_cnt++;
  330. /* Block normalize the input */
  331. normb_shift = block_norm(farray_ptr, FRM_LEN, FFT_HEADROOM);
  332. /*
  333. * Preemphasize the input data and store in the data buffer with
  334. * appropriate delay
  335. */
  336. for (i = 0; i < DELAY; i++)
  337. data_buffer[i] = shift_r(window_overlap[i], normb_shift-last_normb_shift);
  338. pre_emp_mem = shift_r(pre_emp_mem, normb_shift-last_normb_shift);
  339. last_normb_shift = normb_shift;
  340. data_buffer[DELAY] = add(*farray_ptr, mult(PRE_EMP_FAC, pre_emp_mem));
  341. for (i = DELAY + 1, j = 1; i < DELAY + FRM_LEN; i++, j++)
  342. data_buffer[i] = add(*(farray_ptr + j), mult(PRE_EMP_FAC, *(farray_ptr + j - 1)));
  343. pre_emp_mem = *(farray_ptr + FRM_LEN - 1);
  344. for (i = DELAY + FRM_LEN; i < FFT_LEN; i++)
  345. data_buffer[i] = 0;
  346. /* update window_overlap buffer */
  347. for (i = 0, j = FRM_LEN; i < DELAY; i++, j++)
  348. window_overlap[i] = data_buffer[j];
  349. /* Apply window to frame prior to FFT */
  350. for (i = 0; i < FRM_LEN + DELAY; i++)
  351. data_buffer[i] = mult_r(data_buffer[i], window[i]);
  352. /* Perform FFT on the data buffer */
  353. r_fft(data_buffer, +1);
  354. /* Estimate the energy in each channel */
  355. for (i = LO_CHAN; i <= HI_CHAN; i++)
  356. {
  357. enrg = 0;
  358. j1 = ch_tbl[i][0];
  359. j2 = ch_tbl[i][1];
  360. for (j = j1; j <= j2; j++)
  361. {
  362. enrg = L_mac(enrg, data_buffer[2 * j], data_buffer[2 * j]);
  363. enrg = L_mac(enrg, data_buffer[2 * j + 1], data_buffer[2 * j + 1]);
  364. }
  365. if (ch_tbl_sh[i][0] == TRUE)
  366. enrg = L_shr(enrg, ch_tbl_sh[i][1]);
  367. else
  368. {
  369. norm_shift = norm_l(enrg);
  370. tmp = extract_h(L_shl(enrg, norm_shift));
  371. enrg = L_mult(tmp, ch_tbl_sh[i][1]);
  372. enrg = L_shr(enrg, norm_shift);
  373. }
  374. if (first == TRUE)
  375. ch_enrg[i] = L_shl(enrg, 7 - (2 * normb_shift)); /* rescaled from 30,1 to 23,8 (w/block denorm) */
  376. else
  377. {
  378. norm_shift = norm_l(enrg);
  379. Ltmp1 = L_shl(enrg, norm_shift);
  380. Ltmp1 = L_mpy_ls(CEE_SM_FAC, extract_h(Ltmp1));
  381. Ltmp1 = L_shr(Ltmp1, norm_shift);
  382. Ltmp2 = L_shl(Ltmp1, 7 - (2 * normb_shift)); /* rescaled from 30,1 to 23,8 (w/block denorm) */
  383. norm_shift = norm_l(ch_enrg[i]);
  384. Ltmp1 = L_shl(ch_enrg[i], norm_shift);
  385. Ltmp3 = L_mpy_ls(ONE_MINUS_CEE_SM_FAC, extract_h(Ltmp1));
  386. Ltmp3 = L_shr(Ltmp3, norm_shift);
  387. ch_enrg[i] = L_add(Ltmp3, Ltmp2);
  388. }
  389. if (ch_enrg[i] < MIN_CHAN_ENRG)
  390. ch_enrg[i] = MIN_CHAN_ENRG;
  391. }
  392. /* Initialize channel noise estimate to channel energy of first four frames */
  393. if (frame_cnt <= 4)
  394. {
  395. for (i = LO_CHAN; i <= HI_CHAN; i++)
  396. {
  397. if (ch_enrg[i] < INE_CHAN)
  398. ch_noise[i] = INE_NOISE;
  399. else
  400. ch_noise[i] = ch_enrg[i];
  401. }
  402. }
  403. /* Compute the channel SNR indices */
  404. for (i = LO_CHAN; i <= HI_CHAN; i++)
  405. {
  406. norm_shift = norm_l(ch_noise[i]);
  407. Ltmp = L_shl(ch_noise[i], norm_shift);
  408. norm_shift1 = norm_l(ch_enrg[i]);
  409. Ltmp3 = L_shl(ch_enrg[i], norm_shift1 - 1);
  410. Ltmp2 = L_divide(Ltmp3, Ltmp);
  411. Ltmp2 = L_shr(Ltmp2, 27 - 1 + norm_shift1 - norm_shift); /* scaled as 27,4 */
  412. if (Ltmp2 == 0)
  413. Ltmp2 = 1;
  414. Ltmp1 = fnLog10(Ltmp2);
  415. Ltmp3 = L_add(Ltmp1, LOG_OFFSET - 80807124); /* -round32(log10(2^4)*2^26 */
  416. Ltmp2 = L_mult(TEN_S5_10, extract_h(Ltmp3));
  417. if (Ltmp2 < 0)
  418. Ltmp2 = 0;
  419. /* 0.1875 scaled as 10,21 */
  420. Ltmp1 = L_add(Ltmp2, CONST_0_1875_S10_21);
  421. /* tmp / 0.375 2.667 scaled as 5,10, Ltmp is scaled 15,16 */
  422. Ltmp = L_mult(extract_h(Ltmp1), CONST_2_667_S5_10);
  423. ch_snr[i] = extract_h(Ltmp);
  424. }
  425. /* Compute the sum of voice metrics */
  426. vm_sum = 0;
  427. for (i = LO_CHAN; i <= HI_CHAN; i++)
  428. {
  429. if (ch_snr[i] < 89)
  430. j = ch_snr[i];
  431. else
  432. j = 89;
  433. vm_sum = add(vm_sum, vm_tbl[j]);
  434. }
  435. /* Compute the total noise estimate (tne) and total channel energy estimate (tce) */
  436. tne = tce = 0;
  437. for (i = LO_CHAN; i <= HI_CHAN; i++)
  438. {
  439. tne = L_add(tne, ch_noise[i]);
  440. tce = L_add(tce, ch_enrg[i]);
  441. }
  442. /* Calculate log spectral deviation */
  443. for (i = LO_CHAN; i <= HI_CHAN; i++)
  444. {
  445. Ltmp = ch_enrg[i];
  446. if (Ltmp == 0)
  447. Ltmp = 1;
  448. Ltmp1 = fnLog10(Ltmp);
  449. Ltmp2 = L_add(Ltmp1, LOG_OFFSET - 161614248); /* -round32(log10(2^8)*2^26) */
  450. ch_enrg_db[i] = mult(TEN_S5_10, extract_h(Ltmp2));
  451. }
  452. if (first == TRUE)
  453. for (i = LO_CHAN; i <= HI_CHAN; i++)
  454. ch_enrg_long_db[i] = ch_enrg_db[i];
  455. ch_enrg_dev = 0;
  456. for (i = LO_CHAN; i <= HI_CHAN; i++)
  457. {
  458. tmp = abs_s(sub(ch_enrg_long_db[i], ch_enrg_db[i]));
  459. ch_enrg_dev = add(ch_enrg_dev, tmp);
  460. }
  461. /*
  462. * Calculate long term integration constant as a function of total channel energy (tce)
  463. * (i.e., high tce (-40 dB) -> slow integration (alpha = 0.99),
  464. * low tce (-60 dB) -> fast integration (alpha = 0.50)
  465. */
  466. Ltmp1 = fnLog10(tce);
  467. Ltmp2 = L_add(Ltmp1, LOG_OFFSET - 161614248); /* -round32(log10(2^8)*2^26) */
  468. tmp = mult(TEN_S5_10, extract_h(Ltmp2));
  469. tmp2 = sub(HIGH_TCE_DB, tmp); /* HIGH_TCE_DB and tmp scaled as 10,5 */
  470. tmp2 = shl(tmp2, 5); /* move scale to 5,10 get more fraction */
  471. tmp1 = mult(ALPHA_RAN_DIV_TCE_RAN, tmp2);
  472. alpha = sub(HIGH_ALPHA_S5_10, tmp1);
  473. if (alpha > HIGH_ALPHA_S5_10)
  474. alpha = HIGH_ALPHA;
  475. else if (alpha < LOW_ALPHA_S5_10)
  476. alpha = LOW_ALPHA;
  477. else
  478. alpha = shl(alpha, 5); /* rescale from 5,10 to 0,15 alpha is a fraction */
  479. /* Calc long term log spectral energy */
  480. tmp = sub(SW_MAX, alpha);
  481. for (i = LO_CHAN; i <= HI_CHAN; i++)
  482. {
  483. Ltmp1 = L_mult(tmp, ch_enrg_db[i]);
  484. Ltmp2 = L_mult(alpha, ch_enrg_long_db[i]);
  485. ch_enrg_long_db[i] = extract_h(L_add(Ltmp1, Ltmp2));
  486. }
  487. /* Set or reset the update flag */
  488. update_flag = FALSE;
  489. if (vm_sum <= UPDATE_THLD)
  490. {
  491. update_flag = TRUE;
  492. update_cnt = 0;
  493. }
  494. else if (tce > NOISE_FLOOR_CHAN && ch_enrg_dev < DEV_THLD)
  495. {
  496. update_cnt++;
  497. if (update_cnt >= UPDATE_CNT_THLD)
  498. update_flag = TRUE;
  499. }
  500. if (update_cnt == last_update_cnt)
  501. hyster_cnt++;
  502. else
  503. hyster_cnt = 0;
  504. last_update_cnt = update_cnt;
  505. if (hyster_cnt > HYSTER_CNT_THLD)
  506. update_cnt = 0;
  507. /* Set or reset modify flag */
  508. index_cnt = 0;
  509. for (i = MID_CHAN; i <= HI_CHAN; i++)
  510. if (ch_snr[i] >= INDEX_THLD)
  511. index_cnt++;
  512. modify_flag = (index_cnt < INDEX_CNT_THLD) ? TRUE : FALSE;
  513. /* Modify the SNR indices */
  514. if (modify_flag == TRUE)
  515. {
  516. for (i = LO_CHAN; i <= HI_CHAN; i++)
  517. if ((vm_sum <= METRIC_THLD) || (ch_snr[i] <= SETBACK_THLD))
  518. ch_snr[i] = 1;
  519. }
  520. /* Compute the channel gains */
  521. Ltmp1 = fnLog10(tne);
  522. Ltmp1 = L_add(Ltmp1, LOG_OFFSET - 161614248); /* -round32(log10(2^8)*2^26) */
  523. Ltmp1 = L_negate(Ltmp1);
  524. gain = L_mpy_ls(Ltmp1, TEN_S5_10);
  525. if (gain < MIN_GAIN)
  526. gain = MIN_GAIN;
  527. for (i = LO_CHAN; i <= HI_CHAN; i++)
  528. {
  529. if (ch_snr[i] <= SNR_THLD)
  530. ch_snr[i] = SNR_THLD;
  531. tmp = sub(ch_snr[i], SNR_THLD);
  532. Ltmp1 = L_mult(tmp, GAIN_SLOPE);
  533. Ltmp2 = L_shl(Ltmp1, 5); /* rescaled to 10,5 */
  534. Ltmp = L_add(Ltmp2, gain); /* gain scaled as 10,5 */
  535. if (Ltmp > 0)
  536. Ltmp = 0;
  537. Ltmp1 = L_mpy_ls(Ltmp, ONE_OVER_20);
  538. Ltmp1 = L_shl(Ltmp1, 5); /* rescale Ltmp1 to 5,26 */
  539. if (Ltmp1 == 0)
  540. Ltmp1 = -1;
  541. Ltmp2 = fnExp10(Ltmp1);
  542. ftmp2 = extract_h(Ltmp2);
  543. j1 = ch_tbl[i][0], j2 = ch_tbl[i][1];
  544. for (j = j1; j <= j2; j++)
  545. {
  546. ch_gain[j] = ftmp2;
  547. }
  548. }
  549. /* Update the channel noise estimates */
  550. if (update_flag == TRUE)
  551. {
  552. for (i = LO_CHAN; i <= HI_CHAN; i++)
  553. {
  554. norm_shift = norm_l(ch_noise[i]);
  555. Ltmp = L_shl(ch_noise[i], norm_shift);
  556. Ltmp1 = L_mult(extract_h(Ltmp), ONE_MINUS_CNE_SM_FAC);
  557. Ltmp1 = L_shr(Ltmp1, norm_shift);
  558. norm_shift = norm_l(ch_enrg[i]);
  559. Ltmp = L_shl(ch_enrg[i], norm_shift);
  560. Ltmp2 = L_mult(extract_h(Ltmp), CNE_SM_FAC);
  561. Ltmp2 = L_shr(Ltmp2, norm_shift);
  562. ch_noise[i] = L_add(Ltmp1, Ltmp2);
  563. if (ch_noise[i] < MIN_NOISE_ENRG)
  564. ch_noise[i] = MIN_NOISE_ENRG;
  565. }
  566. }
  567. /* Filter the input data in the frequency domain and perform IFFT */
  568. for (i = 0; i < FFT_LEN / 2; i++)
  569. {
  570. data_buffer[2 * i] = mult(data_buffer[2 * i], ch_gain[i]);
  571. data_buffer[2 * i + 1] = mult(data_buffer[2 * i + 1], ch_gain[i]);
  572. }
  573. /* Block normalize data_buffer */
  574. norm_shift = block_norm(data_buffer, FFT_LEN, IFFT_HEADROOM);
  575. /* Inverse FFT */
  576. r_fft(data_buffer, -1);
  577. /* Block denormalize data_buffer */
  578. /* block_denorm(data_buffer, FFT_LEN, normb_shift + norm_shift); */
  579. block_denorm(data_buffer, FFT_LEN, normb_shift + norm_shift + 1);
  580. /* Overlap add the filtered data from previous block.
  581. * Save data from this block for the next. */
  582. for (i = 0; i < FFT_LEN - FRM_LEN; i++)
  583. data_buffer[i] = add(data_buffer[i], overlap[i]);
  584. for (i = FRM_LEN; i < FFT_LEN; i++)
  585. overlap[i - FRM_LEN] = data_buffer[i];
  586. /* Deemphasize the filtered speech and write it out to farray */
  587. tmp = mult(DE_EMP_FAC, de_emp_mem);
  588. *farray_ptr = add(data_buffer[0], tmp);
  589. for (i = 1; i < FRM_LEN; i++)
  590. {
  591. tmp = mult_r(DE_EMP_FAC, *(farray_ptr + i - 1));
  592. *(farray_ptr + i) = add(data_buffer[i], tmp);
  593. }
  594. de_emp_mem = *(farray_ptr + FRM_LEN - 1);
  595. first = FALSE;
  596. } /* end noise_suprs () */