FreeCalypso > hg > gsm-codec-lib
comparison libtwamr/q_plsf_5.c @ 373:128ec87489b6
libtwamr: integrate q_plsf_5.c
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Mon, 06 May 2024 04:03:21 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 372:9cca139a20a8 | 373:128ec87489b6 |
|---|---|
| 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 ******************************************************************************** | |
| 20 * MODULE INCLUDE FILE AND VERSION ID | |
| 21 ******************************************************************************** | |
| 22 */ | |
| 23 #include "namespace.h" | |
| 24 #include "q_plsf.h" | |
| 25 | |
| 26 /* | |
| 27 ******************************************************************************** | |
| 28 * INCLUDE FILES | |
| 29 ******************************************************************************** | |
| 30 */ | |
| 31 #include "typedef.h" | |
| 32 #include "basic_op.h" | |
| 33 #include "no_count.h" | |
| 34 #include "lsp_lsf.h" | |
| 35 #include "reorder.h" | |
| 36 #include "lsfwt.h" | |
| 37 #include "q_plsf5_tab.h" | |
| 38 | |
| 39 /* | |
| 40 ******************************************************************************** | |
| 41 * LOCAL PROGRAM CODE | |
| 42 ******************************************************************************** | |
| 43 */ | |
| 44 /* Quantization of a 4 dimensional subvector */ | |
| 45 | |
| 46 static Word16 Vq_subvec (/* o : quantization index, Q0 */ | |
| 47 Word16 *lsf_r1, /* i : 1st LSF residual vector, Q15 */ | |
| 48 Word16 *lsf_r2, /* i : 2nd LSF residual vector, Q15 */ | |
| 49 const Word16 *dico, /* i : quantization codebook, Q15 */ | |
| 50 Word16 *wf1, /* i : 1st LSF weighting factors Q13 */ | |
| 51 Word16 *wf2, /* i : 2nd LSF weighting factors Q13 */ | |
| 52 Word16 dico_size /* i : size of quantization codebook, Q0 */ | |
| 53 ) | |
| 54 { | |
| 55 Word16 index = 0; /* initialization only needed to keep gcc silent */ | |
| 56 Word16 i, temp; | |
| 57 const Word16 *p_dico; | |
| 58 Word32 dist_min, dist; | |
| 59 | |
| 60 dist_min = MAX_32; move32 (); | |
| 61 p_dico = dico; move16 (); | |
| 62 | |
| 63 for (i = 0; i < dico_size; i++) | |
| 64 { | |
| 65 temp = sub (lsf_r1[0], *p_dico++); | |
| 66 temp = mult (wf1[0], temp); | |
| 67 dist = L_mult (temp, temp); | |
| 68 | |
| 69 temp = sub (lsf_r1[1], *p_dico++); | |
| 70 temp = mult (wf1[1], temp); | |
| 71 dist = L_mac (dist, temp, temp); | |
| 72 | |
| 73 temp = sub (lsf_r2[0], *p_dico++); | |
| 74 temp = mult (wf2[0], temp); | |
| 75 dist = L_mac (dist, temp, temp); | |
| 76 | |
| 77 temp = sub (lsf_r2[1], *p_dico++); | |
| 78 temp = mult (wf2[1], temp); | |
| 79 dist = L_mac (dist, temp, temp); | |
| 80 | |
| 81 test (); | |
| 82 if (L_sub (dist, dist_min) < (Word32) 0) | |
| 83 { | |
| 84 dist_min = dist; move32 (); | |
| 85 index = i; move16 (); | |
| 86 } | |
| 87 } | |
| 88 | |
| 89 /* Reading the selected vector */ | |
| 90 | |
| 91 p_dico = &dico[shl (index, 2)]; move16 (); | |
| 92 lsf_r1[0] = *p_dico++; move16 (); | |
| 93 lsf_r1[1] = *p_dico++; move16 (); | |
| 94 lsf_r2[0] = *p_dico++; move16 (); | |
| 95 lsf_r2[1] = *p_dico++; move16 (); | |
| 96 | |
| 97 return index; | |
| 98 } | |
| 99 | |
| 100 /* Quantization of a 4 dimensional subvector with a signed codebook */ | |
| 101 | |
| 102 static Word16 Vq_subvec_s ( /* o : quantization index Q0 */ | |
| 103 Word16 *lsf_r1, /* i : 1st LSF residual vector Q15 */ | |
| 104 Word16 *lsf_r2, /* i : and LSF residual vector Q15 */ | |
| 105 const Word16 *dico, /* i : quantization codebook Q15 */ | |
| 106 Word16 *wf1, /* i : 1st LSF weighting factors Q13 */ | |
| 107 Word16 *wf2, /* i : 2nd LSF weighting factors Q13 */ | |
| 108 Word16 dico_size) /* i : size of quantization codebook Q0 */ | |
| 109 { | |
| 110 Word16 index = 0; /* initialization only needed to keep gcc silent */ | |
| 111 Word16 sign = 0; /* initialization only needed to keep gcc silent */ | |
| 112 Word16 i, temp; | |
| 113 const Word16 *p_dico; | |
| 114 Word32 dist_min, dist; | |
| 115 | |
| 116 dist_min = MAX_32; move32 (); | |
| 117 p_dico = dico; move16 (); | |
| 118 | |
| 119 for (i = 0; i < dico_size; i++) | |
| 120 { | |
| 121 /* test positive */ | |
| 122 | |
| 123 temp = sub (lsf_r1[0], *p_dico++); | |
| 124 temp = mult (wf1[0], temp); | |
| 125 dist = L_mult (temp, temp); | |
| 126 | |
| 127 temp = sub (lsf_r1[1], *p_dico++); | |
| 128 temp = mult (wf1[1], temp); | |
| 129 dist = L_mac (dist, temp, temp); | |
| 130 | |
| 131 temp = sub (lsf_r2[0], *p_dico++); | |
| 132 temp = mult (wf2[0], temp); | |
| 133 dist = L_mac (dist, temp, temp); | |
| 134 | |
| 135 temp = sub (lsf_r2[1], *p_dico++); | |
| 136 temp = mult (wf2[1], temp); | |
| 137 dist = L_mac (dist, temp, temp); | |
| 138 | |
| 139 test (); | |
| 140 if (L_sub (dist, dist_min) < (Word32) 0) | |
| 141 { | |
| 142 dist_min = dist; move32 (); | |
| 143 index = i; move16 (); | |
| 144 sign = 0; move16 (); | |
| 145 } | |
| 146 /* test negative */ | |
| 147 | |
| 148 p_dico -= 4; move16 (); | |
| 149 temp = add (lsf_r1[0], *p_dico++); | |
| 150 temp = mult (wf1[0], temp); | |
| 151 dist = L_mult (temp, temp); | |
| 152 | |
| 153 temp = add (lsf_r1[1], *p_dico++); | |
| 154 temp = mult (wf1[1], temp); | |
| 155 dist = L_mac (dist, temp, temp); | |
| 156 | |
| 157 temp = add (lsf_r2[0], *p_dico++); | |
| 158 temp = mult (wf2[0], temp); | |
| 159 dist = L_mac (dist, temp, temp); | |
| 160 | |
| 161 temp = add (lsf_r2[1], *p_dico++); | |
| 162 temp = mult (wf2[1], temp); | |
| 163 dist = L_mac (dist, temp, temp); | |
| 164 | |
| 165 test (); | |
| 166 if (L_sub (dist, dist_min) < (Word32) 0) | |
| 167 { | |
| 168 dist_min = dist; move32 (); | |
| 169 index = i; move16 (); | |
| 170 sign = 1; move16 (); | |
| 171 } | |
| 172 } | |
| 173 | |
| 174 /* Reading the selected vector */ | |
| 175 | |
| 176 p_dico = &dico[shl (index, 2)]; move16 (); | |
| 177 test (); | |
| 178 if (sign == 0) | |
| 179 { | |
| 180 lsf_r1[0] = *p_dico++; move16 (); | |
| 181 lsf_r1[1] = *p_dico++; move16 (); | |
| 182 lsf_r2[0] = *p_dico++; move16 (); | |
| 183 lsf_r2[1] = *p_dico++; move16 (); | |
| 184 } | |
| 185 else | |
| 186 { | |
| 187 lsf_r1[0] = negate (*p_dico++); move16 (); | |
| 188 lsf_r1[1] = negate (*p_dico++); move16 (); | |
| 189 lsf_r2[0] = negate (*p_dico++); move16 (); | |
| 190 lsf_r2[1] = negate (*p_dico++); move16 (); | |
| 191 } | |
| 192 | |
| 193 index = shl (index, 1); | |
| 194 index = add (index, sign); | |
| 195 | |
| 196 return index; | |
| 197 } | |
| 198 | |
| 199 /* | |
| 200 ******************************************************************************** | |
| 201 * PUBLIC PROGRAM CODE | |
| 202 ******************************************************************************** | |
| 203 */ | |
| 204 | |
| 205 /************************************************************************* | |
| 206 * FUNCTION: Q_plsf_5() | |
| 207 * | |
| 208 * PURPOSE: Quantization of 2 sets of LSF parameters using 1st order MA | |
| 209 * prediction and split by 5 matrix quantization (split-MQ) | |
| 210 * | |
| 211 * DESCRIPTION: | |
| 212 * | |
| 213 * p[i] = pred_factor*past_rq[i]; i=0,...,m-1 | |
| 214 * r1[i]= lsf1[i] - p[i]; i=0,...,m-1 | |
| 215 * r2[i]= lsf2[i] - p[i]; i=0,...,m-1 | |
| 216 * where: | |
| 217 * lsf1[i] 1st mean-removed LSF vector. | |
| 218 * lsf2[i] 2nd mean-removed LSF vector. | |
| 219 * r1[i] 1st residual prediction vector. | |
| 220 * r2[i] 2nd residual prediction vector. | |
| 221 * past_r2q[i] Past quantized residual (2nd vector). | |
| 222 * | |
| 223 * The residual vectors r1[i] and r2[i] are jointly quantized using | |
| 224 * split-MQ with 5 codebooks. Each 4th dimension submatrix contains 2 | |
| 225 * elements from each residual vector. The 5 submatrices are as follows: | |
| 226 * {r1[0], r1[1], r2[0], r2[1]}; {r1[2], r1[3], r2[2], r2[3]}; | |
| 227 * {r1[4], r1[5], r2[4], r2[5]}; {r1[6], r1[7], r2[6], r2[7]}; | |
| 228 * {r1[8], r1[9], r2[8], r2[9]}; | |
| 229 * | |
| 230 *************************************************************************/ | |
| 231 void Q_plsf_5 ( | |
| 232 Q_plsfState *st, | |
| 233 Word16 *lsp1, /* i : 1st LSP vector, Q15 */ | |
| 234 Word16 *lsp2, /* i : 2nd LSP vector, Q15 */ | |
| 235 Word16 *lsp1_q, /* o : quantized 1st LSP vector, Q15 */ | |
| 236 Word16 *lsp2_q, /* o : quantized 2nd LSP vector, Q15 */ | |
| 237 Word16 *indice /* o : quantization indices of 5 matrices, Q0 */ | |
| 238 ) | |
| 239 { | |
| 240 Word16 i; | |
| 241 Word16 lsf1[M], lsf2[M], wf1[M], wf2[M], lsf_p[M], lsf_r1[M], lsf_r2[M]; | |
| 242 Word16 lsf1_q[M], lsf2_q[M]; | |
| 243 | |
| 244 /* convert LSFs to normalize frequency domain 0..16384 */ | |
| 245 | |
| 246 Lsp_lsf (lsp1, lsf1, M); | |
| 247 Lsp_lsf (lsp2, lsf2, M); | |
| 248 | |
| 249 /* Compute LSF weighting factors (Q13) */ | |
| 250 | |
| 251 Lsf_wt (lsf1, wf1); | |
| 252 Lsf_wt (lsf2, wf2); | |
| 253 | |
| 254 /* Compute predicted LSF and prediction error */ | |
| 255 | |
| 256 for (i = 0; i < M; i++) | |
| 257 { | |
| 258 lsf_p[i] = add (mean_lsf[i], mult (st->past_rq[i], LSP_PRED_FAC_MR122)); | |
| 259 move16 (); | |
| 260 lsf_r1[i] = sub (lsf1[i], lsf_p[i]); move16 (); | |
| 261 lsf_r2[i] = sub (lsf2[i], lsf_p[i]); move16 (); | |
| 262 } | |
| 263 | |
| 264 /*---- Split-MQ of prediction error ----*/ | |
| 265 | |
| 266 indice[0] = Vq_subvec (&lsf_r1[0], &lsf_r2[0], dico1_lsf, | |
| 267 &wf1[0], &wf2[0], DICO1_SIZE); | |
| 268 move16 (); | |
| 269 | |
| 270 indice[1] = Vq_subvec (&lsf_r1[2], &lsf_r2[2], dico2_lsf, | |
| 271 &wf1[2], &wf2[2], DICO2_SIZE); | |
| 272 move16 (); | |
| 273 | |
| 274 indice[2] = Vq_subvec_s (&lsf_r1[4], &lsf_r2[4], dico3_lsf, | |
| 275 &wf1[4], &wf2[4], DICO3_SIZE); | |
| 276 move16 (); | |
| 277 | |
| 278 indice[3] = Vq_subvec (&lsf_r1[6], &lsf_r2[6], dico4_lsf, | |
| 279 &wf1[6], &wf2[6], DICO4_SIZE); | |
| 280 move16 (); | |
| 281 | |
| 282 indice[4] = Vq_subvec (&lsf_r1[8], &lsf_r2[8], dico5_lsf, | |
| 283 &wf1[8], &wf2[8], DICO5_SIZE); | |
| 284 move16 (); | |
| 285 | |
| 286 /* Compute quantized LSFs and update the past quantized residual */ | |
| 287 for (i = 0; i < M; i++) | |
| 288 { | |
| 289 lsf1_q[i] = add (lsf_r1[i], lsf_p[i]); move16 (); | |
| 290 lsf2_q[i] = add (lsf_r2[i], lsf_p[i]); move16 (); | |
| 291 st->past_rq[i] = lsf_r2[i]; move16 (); | |
| 292 } | |
| 293 | |
| 294 /* verification that LSFs has minimum distance of LSF_GAP */ | |
| 295 | |
| 296 Reorder_lsf (lsf1_q, LSF_GAP, M); | |
| 297 Reorder_lsf (lsf2_q, LSF_GAP, M); | |
| 298 | |
| 299 /* convert LSFs to the cosine domain */ | |
| 300 | |
| 301 Lsf_lsp (lsf1_q, lsp1_q, M); | |
| 302 Lsf_lsp (lsf2_q, lsp2_q, M); | |
| 303 } |
