PageRenderTime 53ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/intlibs/gsm_amr/amr_nb/enc/src/autocorr.cpp

https://github.com/jaumem/MoSync
C++ | 459 lines | 106 code | 48 blank | 305 comment | 15 complexity | 5024282898691a8f6e81d8b93ca9f2c0 MD5 | raw file
  1. /* ------------------------------------------------------------------
  2. * Copyright (C) 2008 PacketVideo
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
  13. * express or implied.
  14. * See the License for the specific language governing permissions
  15. * and limitations under the License.
  16. * -------------------------------------------------------------------
  17. */
  18. /****************************************************************************************
  19. Portions of this file are derived from the following 3GPP standard:
  20. 3GPP TS 26.073
  21. ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
  22. Available from http://www.3gpp.org
  23. (C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
  24. Permission to distribute, modify and use this file under the standard license
  25. terms listed above has been obtained from the copyright holder.
  26. ****************************************************************************************/
  27. /*
  28. ------------------------------------------------------------------------------
  29. Pathname: ./audio/gsm-amr/c/src/autocorr.c
  30. Date: 05/15/2000
  31. ------------------------------------------------------------------------------
  32. REVISION HISTORY
  33. Description: Put into template...starting optimization.
  34. Description: Removed call to mult_r routine.
  35. Description: Modified Input/Output Definitions section to comply with the
  36. current template. Fixed tabs.
  37. Description: Updated Input/Output definitions by making them more
  38. descriptive.
  39. Description: Synchronized file with UMTS version 3.2.0. Updated coding
  40. template.
  41. Description: Made the following changes per comments from Phase 2/3 review:
  42. 1. Added full pathname of file.
  43. 2. Fixed typecasting issue with TI compiler.
  44. 3. Modified FOR loops to count down.
  45. 4. Added comment to the code.
  46. Description: Removed extern to global paramter (Flag Overflow) and replaced
  47. by passing in a pointer to Overflow. Also, made several small changes to
  48. bring code more in line with PV Standards.
  49. Description:
  50. 1. Added pointer to avoid adding offsets in every pass
  51. 2. Break last loop in two nested loop to speed up processing
  52. 3. Removed extra check for overflow by doing scaling right
  53. after overflow is detected.
  54. 4. Eliminated calls to basic operations (like extract) not
  55. needed because of the nature of the number (all bounded)
  56. Description:
  57. 1. Fixed for:
  58. overflow check was looking for positive number before a left
  59. shift. When numbers were big enough, positive numbers after
  60. shifted became negative, causing a 1/0 division).
  61. Fixed so now it checks for numbers lesser than 0x40000000
  62. before the left shift
  63. Description:
  64. 1.Modified check for saturation to match bit exact test.
  65. Also, when saturation is reached, a faster loop is used
  66. (with no energy accumulation) to speed up processing
  67. Description:
  68. 1.Added pointer initialization to for loop when saturation
  69. is found. This because some compiler ( like Vcpp in release
  70. mode) when optimizing code, may remove pointer information
  71. once the loop is broken.
  72. Description: Added casting to eliminate warnings
  73. Description: Replaced "int" and/or "char" with OSCL defined types.
  74. Description: Using inlines from fxp_arithmetic.h.
  75. Description: Replacing fxp_arithmetic.h with basic_op.h.
  76. Description:
  77. ----------------------------------------------------------------------------*/
  78. /*----------------------------------------------------------------------------
  79. ; INCLUDES
  80. ----------------------------------------------------------------------------*/
  81. #include "autocorr.h"
  82. #include "typedef.h"
  83. #include "basic_op.h"
  84. #include "oper_32b.h"
  85. #include "cnst.h"
  86. /*----------------------------------------------------------------------------
  87. ; MACROS
  88. ; Define module specific macros here
  89. ----------------------------------------------------------------------------*/
  90. /*----------------------------------------------------------------------------
  91. ; DEFINES
  92. ; Include all pre-processor statements here. Include conditional
  93. ; compile variables also.
  94. ----------------------------------------------------------------------------*/
  95. /*----------------------------------------------------------------------------
  96. ; LOCAL FUNCTION DEFINITIONS
  97. ; Function Prototype declaration
  98. ----------------------------------------------------------------------------*/
  99. /*----------------------------------------------------------------------------
  100. ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
  101. ; Variable declaration - defined here and used outside this module
  102. ----------------------------------------------------------------------------*/
  103. /*----------------------------------------------------------------------------
  104. ; EXTERNAL FUNCTION REFERENCES
  105. ; Declare functions defined elsewhere and referenced in this module
  106. ----------------------------------------------------------------------------*/
  107. /*----------------------------------------------------------------------------
  108. ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
  109. ; Declare variables used in this module but defined elsewhere
  110. ----------------------------------------------------------------------------*/
  111. /*
  112. ------------------------------------------------------------------------------
  113. FUNCTION NAME: Autocorr
  114. ----------------------------------------------------------------------------
  115. INPUT AND OUTPUT DEFINITIONS
  116. Inputs:
  117. x = buffer of input signals of type Word16
  118. m = LPC order of type Word16
  119. wind = buffer of window signals of type Word16
  120. r_h = buffer containing the high word of the autocorrelation values
  121. of type Word16
  122. r_l = buffer containing the low word of the autocorrelation values
  123. of type Word16
  124. pOverflow = pointer to variable of type Flag *, which indicates if
  125. overflow occurs.
  126. Outputs:
  127. r_h buffer contains the high word of the new autocorrelation values
  128. r_l buffer contains the low word of the new autocorrelation values
  129. pOverflow -> 1 if overflow occurs.
  130. Returns:
  131. norm = normalized autocorrelation at lag zero of type Word16
  132. Global Variables Used:
  133. None
  134. Local Variables Needed:
  135. None
  136. ------------------------------------------------------------------------------
  137. FUNCTION DESCRIPTION
  138. This function windows the input signal with the provided window
  139. then calculates the autocorrelation values for lags of 0,1,...m,
  140. where m is the passed in LPC order.
  141. ------------------------------------------------------------------------------
  142. REQUIREMENTS
  143. None.
  144. ------------------------------------------------------------------------------
  145. REFERENCES
  146. autocorr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
  147. ------------------------------------------------------------------------------
  148. PSEUDO-CODE
  149. Word16 Autocorr (
  150. Word16 x[], // (i) : Input signal (L_WINDOW)
  151. Word16 m, // (i) : LPC order
  152. Word16 r_h[], // (o) : Autocorrelations (msb)
  153. Word16 r_l[], // (o) : Autocorrelations (lsb)
  154. const Word16 wind[] // (i) : window for LPC analysis (L_WINDOW)
  155. )
  156. {
  157. Word16 i, j, norm;
  158. Word16 y[L_WINDOW];
  159. Word32 sum;
  160. Word16 overfl, overfl_shft;
  161. // Windowing of signal
  162. for (i = 0; i < L_WINDOW; i++)
  163. {
  164. y[i] = mult_r (x[i], wind[i]);
  165. }
  166. // Compute r[0] and test for overflow
  167. overfl_shft = 0;
  168. do
  169. {
  170. overfl = 0;
  171. sum = 0L;
  172. for (i = 0; i < L_WINDOW; i++)
  173. {
  174. sum = L_mac (sum, y[i], y[i]);
  175. }
  176. // If overflow divide y[] by 4
  177. if (L_sub (sum, MAX_32) == 0L)
  178. {
  179. overfl_shft = add (overfl_shft, 4);
  180. overfl = 1; // Set the overflow flag
  181. for (i = 0; i < L_WINDOW; i++)
  182. {
  183. y[i] = shr (y[i], 2);
  184. }
  185. }
  186. }
  187. while (overfl != 0);
  188. sum = L_add (sum, 1L); // Avoid the case of all zeros
  189. // Normalization of r[0]
  190. norm = norm_l (sum);
  191. sum = L_shl (sum, norm);
  192. L_Extract (sum, &r_h[0], &r_l[0]); // Put in DPF format (see oper_32b)
  193. // r[1] to r[m]
  194. for (i = 1; i <= m; i++)
  195. {
  196. sum = 0;
  197. for (j = 0; j < L_WINDOW - i; j++)
  198. {
  199. sum = L_mac (sum, y[j], y[j + i]);
  200. }
  201. sum = L_shl (sum, norm);
  202. L_Extract (sum, &r_h[i], &r_l[i]);
  203. }
  204. norm = sub (norm, overfl_shft);
  205. return norm;
  206. }
  207. ------------------------------------------------------------------------------
  208. RESOURCES USED [optional]
  209. When the code is written for a specific target processor the
  210. the resources used should be documented below.
  211. HEAP MEMORY USED: x bytes
  212. STACK MEMORY USED: x bytes
  213. CLOCK CYCLES: (cycle count equation for this function) + (variable
  214. used to represent cycle count for each subroutine
  215. called)
  216. where: (cycle count variable) = cycle count for [subroutine
  217. name]
  218. ------------------------------------------------------------------------------
  219. CAUTION [optional]
  220. [State any special notes, constraints or cautions for users of this function]
  221. ------------------------------------------------------------------------------
  222. */
  223. Word16 Autocorr(
  224. Word16 x[], /* (i) : Input signal (L_WINDOW) */
  225. Word16 m, /* (i) : LPC order */
  226. Word16 r_h[], /* (o) : Autocorrelations (msb) */
  227. Word16 r_l[], /* (o) : Autocorrelations (lsb) */
  228. const Word16 wind[], /* (i) : window for LPC analysis (L_WINDOW) */
  229. Flag *pOverflow /* (o) : indicates overflow */
  230. )
  231. {
  232. register Word16 i;
  233. register Word16 j;
  234. register Word16 norm;
  235. Word16 y[L_WINDOW];
  236. Word32 sum;
  237. Word16 overfl_shft;
  238. /* Added for optimization */
  239. Word16 temp;
  240. Word16 *p_x;
  241. Word16 *p_y;
  242. Word16 *p_y_1;
  243. Word16 *p_y_ref;
  244. Word16 *p_rh;
  245. Word16 *p_rl;
  246. const Word16 *p_wind;
  247. p_y = y;
  248. p_x = x;
  249. p_wind = wind;
  250. /*
  251. * Windowing of the signal
  252. */
  253. OSCL_UNUSED_ARG(pOverflow);
  254. sum = 0L;
  255. j = 0;
  256. for (i = L_WINDOW; i != 0; i--)
  257. {
  258. temp = (amrnb_fxp_mac_16_by_16bb((Word32) * (p_x++), (Word32) * (p_wind++), 0x04000)) >> 15;
  259. *(p_y++) = temp;
  260. sum += ((Word32)temp * temp) << 1;
  261. if (sum < 0)
  262. {
  263. /*
  264. * if oveflow exist, then stop accumulation
  265. */
  266. j = 1;
  267. break;
  268. }
  269. }
  270. /*
  271. * if oveflow existed, complete windowing operation
  272. * without computing energy
  273. */
  274. if (j)
  275. {
  276. p_y = &y[L_WINDOW-i];
  277. p_x = &x[L_WINDOW-i];
  278. p_wind = &wind[L_WINDOW-i];
  279. for (; i != 0; i--)
  280. {
  281. temp = (amrnb_fxp_mac_16_by_16bb((Word32) * (p_x++), (Word32) * (p_wind++), 0x04000)) >> 15;
  282. *(p_y++) = temp;
  283. }
  284. }
  285. /*
  286. * Compute r[0] and test for overflow
  287. */
  288. overfl_shft = 0;
  289. /*
  290. * scale down by 1/4 only when needed
  291. */
  292. while (j == 1)
  293. {
  294. /* If overflow divide y[] by 4 */
  295. /* FYI: For better resolution, we could */
  296. /* divide y[] by 2 */
  297. overfl_shft += 4;
  298. p_y = &y[0];
  299. sum = 0L;
  300. for (i = (L_WINDOW >> 1); i != 0 ; i--)
  301. {
  302. temp = *p_y >> 2;
  303. *(p_y++) = temp;
  304. sum += ((Word32)temp * temp) << 1;
  305. temp = *p_y >> 2;
  306. *(p_y++) = temp;
  307. sum += ((Word32)temp * temp) << 1;
  308. }
  309. if (sum > 0)
  310. {
  311. j = 0;
  312. }
  313. }
  314. sum += 1L; /* Avoid the case of all zeros */
  315. /* Normalization of r[0] */
  316. norm = norm_l(sum);
  317. sum <<= norm;
  318. /* Put in DPF format (see oper_32b) */
  319. r_h[0] = (Word16)(sum >> 16);
  320. r_l[0] = (Word16)((sum >> 1) - ((Word32)(r_h[0]) << 15));
  321. /* r[1] to r[m] */
  322. p_y_ref = &y[L_WINDOW - 1 ];
  323. p_rh = &r_h[m];
  324. p_rl = &r_l[m];
  325. for (i = m; i > 0; i--)
  326. {
  327. sum = 0;
  328. p_y = &y[L_WINDOW - i - 1];
  329. p_y_1 = p_y_ref;
  330. for (j = (L_WINDOW - i - 1) >> 1; j != 0; j--)
  331. {
  332. sum = amrnb_fxp_mac_16_by_16bb((Word32) * (p_y--), (Word32) * (p_y_1--), sum);
  333. sum = amrnb_fxp_mac_16_by_16bb((Word32) * (p_y--), (Word32) * (p_y_1--), sum);
  334. }
  335. sum = amrnb_fxp_mac_16_by_16bb((Word32) * (p_y--), (Word32) * (p_y_1--), sum);
  336. if (((L_WINDOW - i - 1) & 1))
  337. {
  338. sum = amrnb_fxp_mac_16_by_16bb((Word32) * (p_y--), (Word32) * (p_y_1--), sum);
  339. }
  340. sum <<= (norm + 1);
  341. *(p_rh) = (Word16)(sum >> 16);
  342. *(p_rl--) = (Word16)((sum >> 1) - ((Word32) * (p_rh--) << 15));
  343. }
  344. norm -= overfl_shft;
  345. return (norm);
  346. } /* Autocorr */