q_plsf_5.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  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 : q_plsf_5.c
  11. * Purpose : Quantization of 2 sets of LSF parameters using 1st
  12. * order MA prediction and split by 5 matrix
  13. * quantization (split-MQ)
  14. *
  15. ********************************************************************************
  16. */
  17. /*
  18. ********************************************************************************
  19. * MODULE INCLUDE FILE AND VERSION ID
  20. ********************************************************************************
  21. */
  22. #include "q_plsf.h"
  23. const char q_plsf_5_id[] = "@(#)$Id $" q_plsf_h;
  24. /*
  25. ********************************************************************************
  26. * INCLUDE FILES
  27. ********************************************************************************
  28. */
  29. #include <stdlib.h>
  30. #include <stdio.h>
  31. #include "typedef.h"
  32. #include "basic_op.h"
  33. #include "count.h"
  34. #include "lsp_lsf.h"
  35. #include "reorder.h"
  36. #include "lsfwt.h"
  37. /*
  38. ********************************************************************************
  39. * LOCAL VARIABLES AND TABLES
  40. ********************************************************************************
  41. */
  42. #include "q_plsf_5.tab" /* Codebooks of LSF prediction residual */
  43. /*
  44. ********************************************************************************
  45. * LOCAL PROGRAM CODE
  46. ********************************************************************************
  47. */
  48. /* Quantization of a 4 dimensional subvector */
  49. static Word16 Vq_subvec (/* o : quantization index, Q0 */
  50. Word16 *lsf_r1, /* i : 1st LSF residual vector, Q15 */
  51. Word16 *lsf_r2, /* i : 2nd LSF residual vector, Q15 */
  52. const Word16 *dico, /* i : quantization codebook, Q15 */
  53. Word16 *wf1, /* i : 1st LSF weighting factors Q13 */
  54. Word16 *wf2, /* i : 2nd LSF weighting factors Q13 */
  55. Word16 dico_size /* i : size of quantization codebook, Q0 */
  56. )
  57. {
  58. Word16 index = 0; /* initialization only needed to keep gcc silent */
  59. Word16 i, temp;
  60. const Word16 *p_dico;
  61. Word32 dist_min, dist;
  62. dist_min = MAX_32; move32 ();
  63. p_dico = dico; move16 ();
  64. for (i = 0; i < dico_size; i++)
  65. {
  66. temp = sub_ex (lsf_r1[0], *p_dico++);
  67. temp = mult_ex (wf1[0], temp);
  68. dist = L_mult_ex (temp, temp);
  69. temp = sub_ex (lsf_r1[1], *p_dico++);
  70. temp = mult_ex (wf1[1], temp);
  71. dist = L_mac_ex (dist, temp, temp);
  72. temp = sub_ex (lsf_r2[0], *p_dico++);
  73. temp = mult_ex (wf2[0], temp);
  74. dist = L_mac_ex (dist, temp, temp);
  75. temp = sub_ex (lsf_r2[1], *p_dico++);
  76. temp = mult_ex (wf2[1], temp);
  77. dist = L_mac_ex (dist, temp, temp);
  78. test ();
  79. if (L_sub_ex (dist, dist_min) < (Word32) 0)
  80. {
  81. dist_min = dist; move32 ();
  82. index = i; move16 ();
  83. }
  84. }
  85. /* Reading the selected vector */
  86. p_dico = &dico[shl_ex (index, 2)]; move16 ();
  87. lsf_r1[0] = *p_dico++; move16 ();
  88. lsf_r1[1] = *p_dico++; move16 ();
  89. lsf_r2[0] = *p_dico++; move16 ();
  90. lsf_r2[1] = *p_dico++; move16 ();
  91. return index;
  92. }
  93. /* Quantization of a 4 dimensional subvector with a signed codebook */
  94. static Word16 Vq_subvec_s ( /* o : quantization index Q0 */
  95. Word16 *lsf_r1, /* i : 1st LSF residual vector Q15 */
  96. Word16 *lsf_r2, /* i : and LSF residual vector Q15 */
  97. const Word16 *dico, /* i : quantization codebook Q15 */
  98. Word16 *wf1, /* i : 1st LSF weighting factors Q13 */
  99. Word16 *wf2, /* i : 2nd LSF weighting factors Q13 */
  100. Word16 dico_size) /* i : size of quantization codebook Q0 */
  101. {
  102. Word16 index = 0; /* initialization only needed to keep gcc silent */
  103. Word16 sign = 0; /* initialization only needed to keep gcc silent */
  104. Word16 i, temp;
  105. const Word16 *p_dico;
  106. Word32 dist_min, dist;
  107. dist_min = MAX_32; move32 ();
  108. p_dico = dico; move16 ();
  109. for (i = 0; i < dico_size; i++)
  110. {
  111. /* test positive */
  112. temp = sub_ex (lsf_r1[0], *p_dico++);
  113. temp = mult_ex (wf1[0], temp);
  114. dist = L_mult_ex (temp, temp);
  115. temp = sub_ex (lsf_r1[1], *p_dico++);
  116. temp = mult_ex (wf1[1], temp);
  117. dist = L_mac_ex (dist, temp, temp);
  118. temp = sub_ex (lsf_r2[0], *p_dico++);
  119. temp = mult_ex (wf2[0], temp);
  120. dist = L_mac_ex (dist, temp, temp);
  121. temp = sub_ex (lsf_r2[1], *p_dico++);
  122. temp = mult_ex (wf2[1], temp);
  123. dist = L_mac_ex (dist, temp, temp);
  124. test ();
  125. if (L_sub_ex (dist, dist_min) < (Word32) 0)
  126. {
  127. dist_min = dist; move32 ();
  128. index = i; move16 ();
  129. sign = 0; move16 ();
  130. }
  131. /* test negative */
  132. p_dico -= 4; move16 ();
  133. temp = add_ex (lsf_r1[0], *p_dico++);
  134. temp = mult_ex (wf1[0], temp);
  135. dist = L_mult_ex (temp, temp);
  136. temp = add_ex (lsf_r1[1], *p_dico++);
  137. temp = mult_ex (wf1[1], temp);
  138. dist = L_mac_ex (dist, temp, temp);
  139. temp = add_ex (lsf_r2[0], *p_dico++);
  140. temp = mult_ex (wf2[0], temp);
  141. dist = L_mac_ex (dist, temp, temp);
  142. temp = add_ex (lsf_r2[1], *p_dico++);
  143. temp = mult_ex (wf2[1], temp);
  144. dist = L_mac_ex (dist, temp, temp);
  145. test ();
  146. if (L_sub_ex (dist, dist_min) < (Word32) 0)
  147. {
  148. dist_min = dist; move32 ();
  149. index = i; move16 ();
  150. sign = 1; move16 ();
  151. }
  152. }
  153. /* Reading the selected vector */
  154. p_dico = &dico[shl_ex (index, 2)]; move16 ();
  155. test ();
  156. if (sign == 0)
  157. {
  158. lsf_r1[0] = *p_dico++; move16 ();
  159. lsf_r1[1] = *p_dico++; move16 ();
  160. lsf_r2[0] = *p_dico++; move16 ();
  161. lsf_r2[1] = *p_dico++; move16 ();
  162. }
  163. else
  164. {
  165. lsf_r1[0] = negate_ex (*p_dico++); move16 ();
  166. lsf_r1[1] = negate_ex (*p_dico++); move16 ();
  167. lsf_r2[0] = negate_ex (*p_dico++); move16 ();
  168. lsf_r2[1] = negate_ex (*p_dico++); move16 ();
  169. }
  170. index = shl_ex (index, 1);
  171. index = add_ex (index, sign);
  172. return index;
  173. }
  174. /*
  175. ********************************************************************************
  176. * PUBLIC PROGRAM CODE
  177. ********************************************************************************
  178. */
  179. /*************************************************************************
  180. * FUNCTION: Q_plsf_5()
  181. *
  182. * PURPOSE: Quantization of 2 sets of LSF parameters using 1st order MA
  183. * prediction and split by 5 matrix quantization (split-MQ)
  184. *
  185. * DESCRIPTION:
  186. *
  187. * p[i] = pred_factor*past_rq[i]; i=0,...,m-1
  188. * r1[i]= lsf1[i] - p[i]; i=0,...,m-1
  189. * r2[i]= lsf2[i] - p[i]; i=0,...,m-1
  190. * where:
  191. * lsf1[i] 1st mean-removed LSF vector.
  192. * lsf2[i] 2nd mean-removed LSF vector.
  193. * r1[i] 1st residual prediction vector.
  194. * r2[i] 2nd residual prediction vector.
  195. * past_r2q[i] Past quantized residual (2nd vector).
  196. *
  197. * The residual vectors r1[i] and r2[i] are jointly quantized using
  198. * split-MQ with 5 codebooks. Each 4th dimension submatrix contains 2
  199. * elements from each residual vector. The 5 submatrices are as follows:
  200. * {r1[0], r1[1], r2[0], r2[1]}; {r1[2], r1[3], r2[2], r2[3]};
  201. * {r1[4], r1[5], r2[4], r2[5]}; {r1[6], r1[7], r2[6], r2[7]};
  202. * {r1[8], r1[9], r2[8], r2[9]};
  203. *
  204. *************************************************************************/
  205. void Q_plsf_5 (
  206. Q_plsfState *st,
  207. Word16 *lsp1, /* i : 1st LSP vector, Q15 */
  208. Word16 *lsp2, /* i : 2nd LSP vector, Q15 */
  209. Word16 *lsp1_q, /* o : quantized 1st LSP vector, Q15 */
  210. Word16 *lsp2_q, /* o : quantized 2nd LSP vector, Q15 */
  211. Word16 *indice /* o : quantization indices of 5 matrices, Q0 */
  212. )
  213. {
  214. Word16 i;
  215. Word16 lsf1[M], lsf2[M], wf1[M], wf2[M], lsf_p[M], lsf_r1[M], lsf_r2[M];
  216. Word16 lsf1_q[M], lsf2_q[M];
  217. /* convert LSFs to normalize frequency domain 0..16384 */
  218. Lsp_lsf (lsp1, lsf1, M);
  219. Lsp_lsf (lsp2, lsf2, M);
  220. /* Compute LSF weighting factors (Q13) */
  221. Lsf_wt (lsf1, wf1);
  222. Lsf_wt (lsf2, wf2);
  223. /* Compute predicted LSF and prediction error */
  224. for (i = 0; i < M; i++)
  225. {
  226. lsf_p[i] = add_ex (mean_lsf[i], mult_ex (st->past_rq[i], LSP_PRED_FAC_MR122));
  227. move16 ();
  228. lsf_r1[i] = sub_ex (lsf1[i], lsf_p[i]); move16 ();
  229. lsf_r2[i] = sub_ex (lsf2[i], lsf_p[i]); move16 ();
  230. }
  231. /*---- Split-MQ of prediction error ----*/
  232. indice[0] = Vq_subvec (&lsf_r1[0], &lsf_r2[0], dico1_lsf,
  233. &wf1[0], &wf2[0], DICO1_SIZE);
  234. move16 ();
  235. indice[1] = Vq_subvec (&lsf_r1[2], &lsf_r2[2], dico2_lsf,
  236. &wf1[2], &wf2[2], DICO2_SIZE);
  237. move16 ();
  238. indice[2] = Vq_subvec_s (&lsf_r1[4], &lsf_r2[4], dico3_lsf,
  239. &wf1[4], &wf2[4], DICO3_SIZE);
  240. move16 ();
  241. indice[3] = Vq_subvec (&lsf_r1[6], &lsf_r2[6], dico4_lsf,
  242. &wf1[6], &wf2[6], DICO4_SIZE);
  243. move16 ();
  244. indice[4] = Vq_subvec (&lsf_r1[8], &lsf_r2[8], dico5_lsf,
  245. &wf1[8], &wf2[8], DICO5_SIZE);
  246. move16 ();
  247. /* Compute quantized LSFs and update the past quantized residual */
  248. for (i = 0; i < M; i++)
  249. {
  250. lsf1_q[i] = add_ex (lsf_r1[i], lsf_p[i]); move16 ();
  251. lsf2_q[i] = add_ex (lsf_r2[i], lsf_p[i]); move16 ();
  252. st->past_rq[i] = lsf_r2[i]; move16 ();
  253. }
  254. /* verification that LSFs has minimum distance of LSF_GAP */
  255. Reorder_lsf (lsf1_q, LSF_GAP, M);
  256. Reorder_lsf (lsf2_q, LSF_GAP, M);
  257. /* convert LSFs to the cosine domain */
  258. Lsf_lsp (lsf1_q, lsp1_q, M);
  259. Lsf_lsp (lsf2_q, lsp2_q, M);
  260. }