az_lsp.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. /*
  2. ********************************************************************************
  3. *
  4. * GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001
  5. * R99 Version 3.3.0
  6. * REL-4 Version 4.1.0
  7. *
  8. ********************************************************************************
  9. *
  10. * File : az_lsp.c
  11. * Purpose : Compute the LSPs from the LP coefficients
  12. *
  13. ********************************************************************************
  14. */
  15. /*
  16. ********************************************************************************
  17. * MODULE INCLUDE FILE AND VERSION ID
  18. ********************************************************************************
  19. */
  20. #include "az_lsp.h"
  21. const char az_lsp_id[] = "@(#)$Id $" az_lsp_h;
  22. /*
  23. ********************************************************************************
  24. * INCLUDE FILES
  25. ********************************************************************************
  26. */
  27. #include "typedef.h"
  28. #include "basic_op.h"
  29. #include "oper_32b.h"
  30. #include "count.h"
  31. #include "cnst.h"
  32. /*
  33. ********************************************************************************
  34. * LOCAL VARIABLES AND TABLES
  35. ********************************************************************************
  36. */
  37. #include "grid.tab"
  38. #define NC M/2 /* M = LPC order, NC = M/2 */
  39. /*
  40. ********************************************************************************
  41. * LOCAL PROGRAM CODE
  42. ********************************************************************************
  43. */
  44. /*
  45. **************************************************************************
  46. *
  47. * Function : Chebps
  48. * Purpose : Evaluates the Chebyshev polynomial series
  49. * Description : - The polynomial order is n = m/2 = 5
  50. * - The polynomial F(z) (F1(z) or F2(z)) is given by
  51. * F(w) = 2 exp(-j5w) C(x)
  52. * where
  53. * C(x) = T_n(x) + f(1)T_n-1(x) + ... +f(n-1)T_1(x) + f(n)/2
  54. * and T_m(x) = cos(mw) is the mth order Chebyshev
  55. * polynomial ( x=cos(w) )
  56. * Returns : C(x) for the input x.
  57. *
  58. **************************************************************************
  59. */
  60. static Word16 Chebps (Word16 x,
  61. Word16 f[], /* (n) */
  62. Word16 n)
  63. {
  64. Word16 i, cheb;
  65. Word16 b0_h, b0_l, b1_h, b1_l, b2_h, b2_l;
  66. Word32 t0;
  67. b2_h = 256; move16 (); /* b2 = 1.0 */
  68. b2_l = 0; move16 ();
  69. t0 = L_mult_ex (x, 512); /* 2*x */
  70. t0 = L_mac_ex (t0, f[1], 8192); /* + f[1] */
  71. L_Extract (t0, &b1_h, &b1_l); /* b1 = 2*x + f[1] */
  72. for (i = 2; i < n; i++)
  73. {
  74. t0 = Mpy_32_16 (b1_h, b1_l, x); /* t0 = 2.0*x*b1 */
  75. t0 = L_shl_ex (t0, 1);
  76. t0 = L_mac_ex (t0, b2_h, (Word16) 0x8000); /* t0 = 2.0*x*b1 - b2 */
  77. t0 = L_msu_ex (t0, b2_l, 1);
  78. t0 = L_mac_ex (t0, f[i], 8192); /* t0 = 2.0*x*b1 - b2 + f[i] */
  79. L_Extract (t0, &b0_h, &b0_l); /* b0 = 2.0*x*b1 - b2 + f[i]*/
  80. b2_l = b1_l; move16 (); /* b2 = b1; */
  81. b2_h = b1_h; move16 ();
  82. b1_l = b0_l; move16 (); /* b1 = b0; */
  83. b1_h = b0_h; move16 ();
  84. }
  85. t0 = Mpy_32_16 (b1_h, b1_l, x); /* t0 = x*b1; */
  86. t0 = L_mac_ex (t0, b2_h, (Word16) 0x8000); /* t0 = x*b1 - b2 */
  87. t0 = L_msu_ex (t0, b2_l, 1);
  88. t0 = L_mac_ex (t0, f[i], 4096); /* t0 = x*b1 - b2 + f[i]/2 */
  89. t0 = L_shl_ex (t0, 6);
  90. cheb = extract_h_ex (t0);
  91. return (cheb);
  92. }
  93. /*
  94. ********************************************************************************
  95. * PUBLIC PROGRAM CODE
  96. ********************************************************************************
  97. */
  98. /*
  99. **************************************************************************
  100. *
  101. * Function : Az_lsp
  102. * Purpose : Compute the LSPs from the LP coefficients
  103. *
  104. **************************************************************************
  105. */
  106. void Az_lsp (
  107. Word16 a[], /* (i) : predictor coefficients (MP1) */
  108. Word16 lsp[], /* (o) : line spectral pairs (M) */
  109. Word16 old_lsp[] /* (i) : old lsp[] (in case not found 10 roots) (M) */
  110. )
  111. {
  112. Word16 i, j, nf, ip;
  113. Word16 xlow, ylow, xhigh, yhigh, xmid, ymid, xint;
  114. Word16 x, y, sign, exp;
  115. Word16 *coef;
  116. Word16 f1[M / 2 + 1], f2[M / 2 + 1];
  117. Word32 t0;
  118. /*-------------------------------------------------------------*
  119. * find the sum and diff. pol. F1(z) and F2(z) *
  120. * F1(z) <--- F1(z)/(1+z**-1) & F2(z) <--- F2(z)/(1-z**-1) *
  121. * *
  122. * f1[0] = 1.0; *
  123. * f2[0] = 1.0; *
  124. * *
  125. * for (i = 0; i< NC; i++) *
  126. * { *
  127. * f1[i+1] = a[i+1] + a[M-i] - f1[i] ; *
  128. * f2[i+1] = a[i+1] - a[M-i] + f2[i] ; *
  129. * } *
  130. *-------------------------------------------------------------*/
  131. f1[0] = 1024; move16 (); /* f1[0] = 1.0 */
  132. f2[0] = 1024; move16 (); /* f2[0] = 1.0 */
  133. for (i = 0; i < NC; i++)
  134. {
  135. t0 = L_mult_ex (a[i + 1], 8192); /* x = (a[i+1] + a[M-i]) >> 2 */
  136. t0 = L_mac_ex (t0, a[M - i], 8192);
  137. x = extract_h_ex (t0);
  138. /* f1[i+1] = a[i+1] + a[M-i] - f1[i] */
  139. f1[i + 1] = sub_ex (x, f1[i]);move16 ();
  140. t0 = L_mult_ex (a[i + 1], 8192); /* x = (a[i+1] - a[M-i]) >> 2 */
  141. t0 = L_msu_ex (t0, a[M - i], 8192);
  142. x = extract_h_ex (t0);
  143. /* f2[i+1] = a[i+1] - a[M-i] + f2[i] */
  144. f2[i + 1] = add_ex (x, f2[i]);move16 ();
  145. }
  146. /*-------------------------------------------------------------*
  147. * find the LSPs using the Chebychev pol. evaluation *
  148. *-------------------------------------------------------------*/
  149. nf = 0; move16 (); /* number of found frequencies */
  150. ip = 0; move16 (); /* indicator for f1 or f2 */
  151. coef = f1; move16 ();
  152. xlow = grid[0]; move16 ();
  153. ylow = Chebps (xlow, coef, NC);move16 ();
  154. j = 0;
  155. test (); test ();
  156. /* while ( (nf < M) && (j < grid_points) ) */
  157. while ((sub_ex (nf, M) < 0) && (sub_ex (j, grid_points) < 0))
  158. {
  159. j++;
  160. xhigh = xlow; move16 ();
  161. yhigh = ylow; move16 ();
  162. xlow = grid[j]; move16 ();
  163. ylow = Chebps (xlow, coef, NC);
  164. move16 ();
  165. test ();
  166. if (L_mult_ex (ylow, yhigh) <= (Word32) 0L)
  167. {
  168. /* divide 4 times the interval */
  169. for (i = 0; i < 4; i++)
  170. {
  171. /* xmid = (xlow + xhigh)/2 */
  172. xmid = add_ex (shr_ex (xlow, 1), shr_ex (xhigh, 1));
  173. ymid = Chebps (xmid, coef, NC);
  174. move16 ();
  175. test ();
  176. if (L_mult_ex (ylow, ymid) <= (Word32) 0L)
  177. {
  178. yhigh = ymid; move16 ();
  179. xhigh = xmid; move16 ();
  180. }
  181. else
  182. {
  183. ylow = ymid; move16 ();
  184. xlow = xmid; move16 ();
  185. }
  186. }
  187. /*-------------------------------------------------------------*
  188. * Linear interpolation *
  189. * xint = xlow - ylow*(xhigh-xlow)/(yhigh-ylow); *
  190. *-------------------------------------------------------------*/
  191. x = sub_ex (xhigh, xlow);
  192. y = sub_ex (yhigh, ylow);
  193. test ();
  194. if (y == 0)
  195. {
  196. xint = xlow; move16 ();
  197. }
  198. else
  199. {
  200. sign = y; move16 ();
  201. y = abs_s_ex (y);
  202. exp = norm_s_ex (y);
  203. y = shl_ex (y, exp);
  204. y = div_s ((Word16) 16383, y);
  205. t0 = L_mult_ex (x, y);
  206. t0 = L_shr_ex (t0, sub_ex (20, exp));
  207. y = extract_l_ex (t0); /* y= (xhigh-xlow)/(yhigh-ylow) */
  208. test ();
  209. if (sign < 0)
  210. y = negate_ex (y);
  211. t0 = L_mult_ex (ylow, y);
  212. t0 = L_shr_ex (t0, 11);
  213. xint = sub_ex (xlow, extract_l_ex (t0)); /* xint = xlow - ylow*y */
  214. }
  215. lsp[nf] = xint; move16 ();
  216. xlow = xint; move16 ();
  217. nf++;
  218. test ();
  219. if (ip == 0)
  220. {
  221. ip = 1; move16 ();
  222. coef = f2; move16 ();
  223. }
  224. else
  225. {
  226. ip = 0; move16 ();
  227. coef = f1; move16 ();
  228. }
  229. ylow = Chebps (xlow, coef, NC);
  230. move16 ();
  231. }
  232. test (); test ();
  233. }
  234. /* Check if M roots found */
  235. test ();
  236. if (sub_ex (nf, M) < 0)
  237. {
  238. for (i = 0; i < M; i++)
  239. {
  240. lsp[i] = old_lsp[i]; move16 ();
  241. }
  242. }
  243. return;
  244. }