q_plsf_3.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  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_3.c
  11. * Purpose : Quantization of LSF parameters with 1st order MA
  12. * prediction and split by 3 vector quantization
  13. * (split-VQ)
  14. *
  15. *****************************************************************************
  16. */
  17. /*
  18. *****************************************************************************
  19. * MODULE INCLUDE FILE AND VERSION ID
  20. *****************************************************************************
  21. */
  22. #include "q_plsf.h"
  23. const char q_plsf_3_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. #include "copy.h"
  38. /*
  39. *****************************************************************************
  40. * LOCAL VARIABLES AND TABLES
  41. *****************************************************************************
  42. */
  43. #include "q_plsf_3.tab" /* Codebooks of LSF prediction residual */
  44. #define PAST_RQ_INIT_SIZE 8
  45. /*
  46. *****************************************************************************
  47. * LOCAL PROGRAM CODE
  48. *****************************************************************************
  49. */
  50. /* Quantization of a 4 dimensional subvector */
  51. static Word16
  52. Vq_subvec4( /* o: quantization index, Q0 */
  53. Word16 * lsf_r1, /* i: 1st LSF residual vector, Q15 */
  54. Word16 * dico, /* i: quantization codebook, Q15 */
  55. Word16 * wf1, /* i: 1st LSF weighting factors, Q13 */
  56. Word16 dico_size) /* i: size of quantization codebook, Q0 */
  57. {
  58. Word16 i, index = 0;
  59. Word16 *p_dico, temp;
  60. Word32 dist_min, dist;
  61. dist_min = MAX_32; move32 ();
  62. p_dico = dico; move16 ();
  63. for (i = 0; i < dico_size; i++)
  64. {
  65. temp = sub_ex (lsf_r1[0], *p_dico++);
  66. temp = mult_ex (wf1[0], temp);
  67. dist = L_mult_ex (temp, temp);
  68. temp = sub_ex (lsf_r1[1], *p_dico++);
  69. temp = mult_ex (wf1[1], temp);
  70. dist = L_mac_ex (dist, temp, temp);
  71. temp = sub_ex (lsf_r1[2], *p_dico++);
  72. temp = mult_ex (wf1[2], temp);
  73. dist = L_mac_ex (dist, temp, temp);
  74. temp = sub_ex (lsf_r1[3], *p_dico++);
  75. temp = mult_ex (wf1[3], temp);
  76. dist = L_mac_ex (dist, temp, temp);
  77. test ();
  78. if (L_sub_ex (dist, dist_min) < (Word32) 0)
  79. {
  80. dist_min = dist; move32 ();
  81. index = i; move16 ();
  82. }
  83. }
  84. /* Reading the selected vector */
  85. p_dico = &dico[shl_ex (index, 2)]; move16 ();
  86. lsf_r1[0] = *p_dico++; move16 ();
  87. lsf_r1[1] = *p_dico++; move16 ();
  88. lsf_r1[2] = *p_dico++; move16 ();
  89. lsf_r1[3] = *p_dico++; move16 ();
  90. return index;
  91. }
  92. /* Quantization of a 3 dimensional subvector */
  93. static Word16
  94. Vq_subvec3( /* o: quantization index, Q0 */
  95. Word16 * lsf_r1, /* i: 1st LSF residual vector, Q15 */
  96. Word16 * dico, /* i: quantization codebook, Q15 */
  97. Word16 * wf1, /* i: 1st LSF weighting factors, Q13 */
  98. Word16 dico_size, /* i: size of quantization codebook, Q0 */
  99. Flag use_half) /* i: use every second entry in codebook */
  100. {
  101. Word16 i, index = 0;
  102. Word16 *p_dico, temp;
  103. Word32 dist_min, dist;
  104. dist_min = MAX_32; move32 ();
  105. p_dico = dico; move16 ();
  106. test ();
  107. if (use_half == 0) {
  108. for (i = 0; i < dico_size; i++)
  109. {
  110. temp = sub_ex(lsf_r1[0], *p_dico++);
  111. temp = mult_ex(wf1[0], temp);
  112. dist = L_mult_ex(temp, temp);
  113. temp = sub_ex(lsf_r1[1], *p_dico++);
  114. temp = mult_ex(wf1[1], temp);
  115. dist = L_mac_ex(dist, temp, temp);
  116. temp = sub_ex(lsf_r1[2], *p_dico++);
  117. temp = mult_ex(wf1[2], temp);
  118. dist = L_mac_ex(dist, temp, temp);
  119. test ();
  120. if (L_sub_ex(dist, dist_min) < (Word32) 0) {
  121. dist_min = dist; move32 ();
  122. index = i; move16 ();
  123. }
  124. }
  125. p_dico = &dico[add_ex(index, add_ex(index, index))]; move16 ();
  126. }
  127. else
  128. {
  129. for (i = 0; i < dico_size; i++)
  130. {
  131. temp = sub_ex(lsf_r1[0], *p_dico++);
  132. temp = mult_ex(wf1[0], temp);
  133. dist = L_mult_ex(temp, temp);
  134. temp = sub_ex(lsf_r1[1], *p_dico++);
  135. temp = mult_ex(wf1[1], temp);
  136. dist = L_mac_ex(dist, temp, temp);
  137. temp = sub_ex(lsf_r1[2], *p_dico++);
  138. temp = mult_ex(wf1[2], temp);
  139. dist = L_mac_ex(dist, temp, temp);
  140. test ();
  141. if (L_sub_ex(dist, dist_min) < (Word32) 0)
  142. {
  143. dist_min = dist; move32 ();
  144. index = i; move16 ();
  145. }
  146. p_dico = p_dico + 3; add_ex(0,0);
  147. }
  148. p_dico = &dico[shl_ex(add_ex(index, add_ex(index, index)),1)]; move16 ();
  149. }
  150. /* Reading the selected vector */
  151. lsf_r1[0] = *p_dico++; move16 ();
  152. lsf_r1[1] = *p_dico++; move16 ();
  153. lsf_r1[2] = *p_dico++; move16 ();
  154. return index;
  155. }
  156. /*
  157. *****************************************************************************
  158. * PUBLIC PROGRAM CODE
  159. *****************************************************************************
  160. */
  161. /***********************************************************************
  162. *
  163. * routine: Q_plsf_3()
  164. *
  165. * Quantization of LSF parameters with 1st order MA prediction and
  166. * split by 3 vector quantization (split-VQ)
  167. *
  168. ***********************************************************************/
  169. void Q_plsf_3(
  170. Q_plsfState *st, /* i/o: state struct */
  171. enum Mode mode, /* i : coder mode */
  172. Word16 *lsp1, /* i : 1st LSP vector Q15 */
  173. Word16 *lsp1_q, /* o : quantized 1st LSP vector Q15 */
  174. Word16 *indice, /* o : quantization indices of 3 vectors Q0 */
  175. Word16 *pred_init_i /* o : init index for MA prediction in DTX mode */
  176. )
  177. {
  178. Word16 i, j;
  179. Word16 lsf1[M], wf1[M], lsf_p[M], lsf_r1[M];
  180. Word16 lsf1_q[M];
  181. Word32 L_pred_init_err;
  182. Word32 L_min_pred_init_err;
  183. Word16 temp_r1[M];
  184. Word16 temp_p[M];
  185. /* convert LSFs to normalize frequency domain 0..16384 */
  186. Lsp_lsf(lsp1, lsf1, M);
  187. /* compute LSF weighting factors (Q13) */
  188. Lsf_wt(lsf1, wf1);
  189. /* Compute predicted LSF and prediction error */
  190. if (test(), sub_ex(mode, MRDTX) != 0)
  191. {
  192. for (i = 0; i < M; i++)
  193. {
  194. lsf_p[i] = add_ex(mean_lsf[i],
  195. mult_ex(st->past_rq[i],
  196. pred_fac[i])); move16 ();
  197. lsf_r1[i] = sub_ex(lsf1[i], lsf_p[i]); move16 ();
  198. }
  199. }
  200. else
  201. {
  202. /* DTX mode, search the init vector that yields */
  203. /* lowest prediction resuidual energy */
  204. *pred_init_i = 0; move16 ();
  205. L_min_pred_init_err = 0x7fffffff; /* 2^31 - 1 */ move32 ();
  206. for (j = 0; j < PAST_RQ_INIT_SIZE; j++)
  207. {
  208. L_pred_init_err = 0; move32 ();
  209. for (i = 0; i < M; i++)
  210. {
  211. temp_p[i] = add_ex(mean_lsf[i], past_rq_init[j*M+i]);
  212. temp_r1[i] = sub_ex(lsf1[i],temp_p[i]);
  213. L_pred_init_err = L_mac_ex(L_pred_init_err, temp_r1[i], temp_r1[i]);
  214. } /* next i */
  215. test ();
  216. if (L_sub_ex(L_pred_init_err, L_min_pred_init_err) < (Word32) 0)
  217. {
  218. L_min_pred_init_err = L_pred_init_err; move32 ();
  219. Copy(temp_r1, lsf_r1, M);
  220. Copy(temp_p, lsf_p, M);
  221. /* Set zerom */
  222. Copy(&past_rq_init[j*M], st->past_rq, M);
  223. *pred_init_i = j; move16 ();
  224. } /* endif */
  225. } /* next j */
  226. } /* endif MRDTX */
  227. /*---- Split-VQ of prediction error ----*/
  228. if (sub_ex (mode, MR475) == 0 || sub_ex (mode, MR515) == 0)
  229. { /* MR475, MR515 */
  230. test (); test ();
  231. indice[0] = Vq_subvec3(&lsf_r1[0], dico1_lsf, &wf1[0], DICO1_SIZE, 0);
  232. move16 ();
  233. indice[1] = Vq_subvec3(&lsf_r1[3], dico2_lsf, &wf1[3], DICO2_SIZE/2, 1);
  234. move16 ();
  235. indice[2] = Vq_subvec4(&lsf_r1[6], mr515_3_lsf, &wf1[6], MR515_3_SIZE);
  236. move16 ();
  237. }
  238. else if (sub_ex (mode, MR795) == 0)
  239. { /* MR795 */
  240. test (); test (); test ();
  241. indice[0] = Vq_subvec3(&lsf_r1[0], mr795_1_lsf, &wf1[0], MR795_1_SIZE, 0);
  242. move16 ();
  243. indice[1] = Vq_subvec3(&lsf_r1[3], dico2_lsf, &wf1[3], DICO2_SIZE, 0);
  244. move16 ();
  245. indice[2] = Vq_subvec4(&lsf_r1[6], dico3_lsf, &wf1[6], DICO3_SIZE);
  246. move16 ();
  247. }
  248. else
  249. { /* MR59, MR67, MR74, MR102 , MRDTX */
  250. test (); test (); test ();
  251. indice[0] = Vq_subvec3(&lsf_r1[0], dico1_lsf, &wf1[0], DICO1_SIZE, 0);
  252. move16 ();
  253. indice[1] = Vq_subvec3(&lsf_r1[3], dico2_lsf, &wf1[3], DICO2_SIZE, 0);
  254. move16 ();
  255. indice[2] = Vq_subvec4(&lsf_r1[6], dico3_lsf, &wf1[6], DICO3_SIZE);
  256. move16 ();
  257. }
  258. /* Compute quantized LSFs and update the past quantized residual */
  259. for (i = 0; i < M; i++)
  260. {
  261. lsf1_q[i] = add_ex(lsf_r1[i], lsf_p[i]); move16 ();
  262. st->past_rq[i] = lsf_r1[i]; move16 ();
  263. }
  264. /* verification that LSFs has mimimum distance of LSF_GAP Hz */
  265. Reorder_lsf(lsf1_q, LSF_GAP, M);
  266. /* convert LSFs to the cosine domain */
  267. Lsf_lsp(lsf1_q, lsp1_q, M);
  268. }