bgnscd.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. /*************************************************************************
  2. *
  3. * GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001
  4. * R99 Version 3.3.0
  5. * REL-4 Version 4.1.0
  6. *
  7. ********************************************************************************
  8. *
  9. * File : bgnscd.c
  10. * Purpose : Background noise source charateristic detector (SCD)
  11. *
  12. ********************************************************************************
  13. */
  14. /*
  15. ********************************************************************************
  16. * MODULE INCLUDE FILE AND VERSION ID
  17. ********************************************************************************
  18. */
  19. #include "bgnscd.h"
  20. const char bgnscd_id[] = "@(#)$Id $" bgnscd_h;
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include "typedef.h"
  24. #include "basic_op.h"
  25. #include "count.h"
  26. #include "cnst.h"
  27. #include "copy.h"
  28. #include "set_zero.h"
  29. #include "gmed_n.h"
  30. #include "sqrt_l.h"
  31. /*
  32. ********************************************************************************
  33. * LOCAL VARIABLES AND TABLES
  34. ********************************************************************************
  35. */
  36. /*-----------------------------------------------------------------*
  37. * Decoder constant parameters (defined in "cnst.h") *
  38. *-----------------------------------------------------------------*
  39. * L_FRAME : Frame size. *
  40. * L_SUBFR : Sub-frame size. *
  41. *-----------------------------------------------------------------*/
  42. /*
  43. ********************************************************************************
  44. * PUBLIC PROGRAM CODE
  45. ********************************************************************************
  46. */
  47. /*
  48. **************************************************************************
  49. *
  50. * Function : Bgn_scd_init
  51. * Purpose : Allocates and initializes state memory
  52. *
  53. **************************************************************************
  54. */
  55. Word16 Bgn_scd_init (Bgn_scdState **state)
  56. {
  57. Bgn_scdState* s;
  58. if (state == (Bgn_scdState **) NULL){
  59. wfprintf(stderr, "Bgn_scd_init: invalid parameter\n");
  60. return -1;
  61. }
  62. *state = NULL;
  63. /* allocate memory */
  64. if ((s= (Bgn_scdState *) wmalloc(sizeof(Bgn_scdState))) == NULL){
  65. wfprintf(stderr, "Bgn_scd_init: can not malloc state structure\n");
  66. return -1;
  67. }
  68. Bgn_scd_reset(s);
  69. *state = s;
  70. return 0;
  71. }
  72. /*
  73. **************************************************************************
  74. *
  75. * Function : Bgn_scd_reset
  76. * Purpose : Resets state memory
  77. *
  78. **************************************************************************
  79. */
  80. Word16 Bgn_scd_reset (Bgn_scdState *state)
  81. {
  82. if (state == (Bgn_scdState *) NULL){
  83. wfprintf(stderr, "Bgn_scd_reset: invalid parameter\n");
  84. return -1;
  85. }
  86. /* Static vectors to zero */
  87. Set_zero (state->frameEnergyHist, L_ENERGYHIST);
  88. /* Initialize hangover handling */
  89. state->bgHangover = 0;
  90. return 0;
  91. }
  92. /*
  93. **************************************************************************
  94. *
  95. * Function : Bgn_scd_exit
  96. * Purpose : The memory used for state memory is freed
  97. *
  98. **************************************************************************
  99. */
  100. void Bgn_scd_exit (Bgn_scdState **state)
  101. {
  102. if (state == NULL || *state == NULL)
  103. return;
  104. /* deallocate memory */
  105. wfree(*state);
  106. *state = NULL;
  107. return;
  108. }
  109. /*
  110. **************************************************************************
  111. *
  112. * Function : Bgn_scd
  113. * Purpose : Charaterice synthesis speech and detect background noise
  114. * Returns : background noise decision; 0 = no bgn, 1 = bgn
  115. *
  116. **************************************************************************
  117. */
  118. Word16 Bgn_scd (Bgn_scdState *st, /* i : State variables for bgn SCD */
  119. Word16 ltpGainHist[], /* i : LTP gain history */
  120. Word16 speech[], /* o : synthesis speech frame */
  121. Word16 *voicedHangover /* o : # of frames after last
  122. voiced frame */
  123. )
  124. {
  125. Word16 i;
  126. Word16 prevVoiced, inbgNoise;
  127. Word16 temp;
  128. Word16 ltpLimit, frameEnergyMin;
  129. Word16 currEnergy, noiseFloor, maxEnergy, maxEnergyLastPart;
  130. Word32 s;
  131. /* Update the inBackgroundNoise flag (valid for use in next frame if BFI) */
  132. /* it now works as a energy detector floating on top */
  133. /* not as good as a VAD. */
  134. currEnergy = 0; move16 ();
  135. s = (Word32) 0; move32 ();
  136. for (i = 0; i < L_FRAME; i++)
  137. {
  138. s = L_mac_ex (s, speech[i], speech[i]);
  139. }
  140. s = L_shl_ex(s, 2);
  141. currEnergy = extract_h_ex (s);
  142. frameEnergyMin = 32767; move16 ();
  143. for (i = 0; i < L_ENERGYHIST; i++)
  144. {
  145. test ();
  146. if (sub_ex(st->frameEnergyHist[i], frameEnergyMin) < 0)
  147. frameEnergyMin = st->frameEnergyHist[i]; move16 ();
  148. }
  149. noiseFloor = shl_ex (frameEnergyMin, 4); /* Frame Energy Margin of 16 */
  150. maxEnergy = st->frameEnergyHist[0]; move16 ();
  151. for (i = 1; i < L_ENERGYHIST-4; i++)
  152. {
  153. test ();
  154. if ( sub_ex (maxEnergy, st->frameEnergyHist[i]) < 0)
  155. {
  156. maxEnergy = st->frameEnergyHist[i]; move16 ();
  157. }
  158. }
  159. maxEnergyLastPart = st->frameEnergyHist[2*L_ENERGYHIST/3]; move16 ();
  160. for (i = 2*L_ENERGYHIST/3+1; i < L_ENERGYHIST; i++)
  161. {
  162. test ();
  163. if ( sub_ex (maxEnergyLastPart, st->frameEnergyHist[i] ) < 0)
  164. {
  165. maxEnergyLastPart = st->frameEnergyHist[i]; move16 ();
  166. }
  167. }
  168. inbgNoise = 0; /* false */ move16 ();
  169. /* Do not consider silence as noise */
  170. /* Do not consider continuous high volume as noise */
  171. /* Or if the current noise level is very low */
  172. /* Mark as noise if under current noise limit */
  173. /* OR if the maximum energy is below the upper limit */
  174. test (); test (); test (); test (); test ();
  175. if ( (sub_ex(maxEnergy, LOWERNOISELIMIT) > 0) &&
  176. (sub_ex(currEnergy, FRAMEENERGYLIMIT) < 0) &&
  177. (sub_ex(currEnergy, LOWERNOISELIMIT) > 0) &&
  178. ( (sub_ex(currEnergy, noiseFloor) < 0) ||
  179. (sub_ex(maxEnergyLastPart, UPPERNOISELIMIT) < 0)))
  180. {
  181. test ();
  182. if (sub_ex(add_ex(st->bgHangover, 1), 30) > 0)
  183. {
  184. st->bgHangover = 30; move16 ();
  185. } else
  186. {
  187. st->bgHangover = add_ex(st->bgHangover, 1);
  188. }
  189. }
  190. else
  191. {
  192. st->bgHangover = 0; move16 ();
  193. }
  194. /* make final decision about frame state , act somewhat cautiosly */
  195. test ();
  196. if (sub_ex(st->bgHangover,1) > 0)
  197. inbgNoise = 1; /* true */ move16 ();
  198. for (i = 0; i < L_ENERGYHIST-1; i++)
  199. {
  200. st->frameEnergyHist[i] = st->frameEnergyHist[i+1]; move16 ();
  201. }
  202. st->frameEnergyHist[L_ENERGYHIST-1] = currEnergy; move16 ();
  203. /* prepare for voicing decision; tighten the threshold after some
  204. time in noise */
  205. ltpLimit = 13926; /* 0.85 Q14 */ move16 ();
  206. test ();
  207. if (sub_ex(st->bgHangover, 8) > 0)
  208. {
  209. ltpLimit = 15565; /* 0.95 Q14 */ move16 ();
  210. }
  211. test ();
  212. if (sub_ex(st->bgHangover, 15) > 0)
  213. {
  214. ltpLimit = 16383; /* 1.00 Q14 */ move16 ();
  215. }
  216. /* weak sort of voicing indication. */
  217. prevVoiced = 0; /* false */ move16 ();
  218. test ();
  219. if (sub_ex(gmed_n(&ltpGainHist[4], 5), ltpLimit) > 0)
  220. {
  221. prevVoiced = 1; /* true */ move16 ();
  222. }
  223. test ();
  224. if (sub_ex(st->bgHangover, 20) > 0) {
  225. if (sub_ex(gmed_n(ltpGainHist, 9), ltpLimit) > 0)
  226. {
  227. prevVoiced = 1; /* true */ move16 ();
  228. }
  229. else
  230. {
  231. prevVoiced = 0; /* false */ move16 ();
  232. }
  233. }
  234. test ();
  235. if (prevVoiced)
  236. {
  237. *voicedHangover = 0; move16 ();
  238. }
  239. else
  240. {
  241. temp = add_ex(*voicedHangover, 1);
  242. test ();
  243. if (sub_ex(temp, 10) > 0)
  244. {
  245. *voicedHangover = 10; move16 ();
  246. }
  247. else
  248. {
  249. *voicedHangover = temp; move16 ();
  250. }
  251. }
  252. return inbgNoise;
  253. }