FreeCalypso > hg > efr-experiments
comparison src/c1035pf.c @ 0:56410792419a
src: original EFR source from ETSI
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Wed, 03 Apr 2024 05:31:37 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:56410792419a |
|---|---|
| 1 #include "typedef.h" | |
| 2 #include "basic_op.h" | |
| 3 #include "sig_proc.h" | |
| 4 #include "count.h" | |
| 5 | |
| 6 #define L_CODE 40 | |
| 7 #define NB_TRACK 5 | |
| 8 #define NB_PULSE 10 | |
| 9 #define STEP 5 | |
| 10 | |
| 11 /* local functions */ | |
| 12 | |
| 13 void cor_h_x ( | |
| 14 Word16 h[], /* (i) : impulse response of weighted synthesis filter */ | |
| 15 Word16 x[], /* (i) : target */ | |
| 16 Word16 dn[] /* (o) : correlation between target and h[] */ | |
| 17 ); | |
| 18 | |
| 19 void set_sign ( | |
| 20 Word16 dn[], /* (i/o) : correlation between target and h[] */ | |
| 21 Word16 cn[], /* (i) : residual after long term prediction */ | |
| 22 Word16 sign[], /* (o) : sign of d[n] */ | |
| 23 Word16 pos_max[], /* (o) : position of maximum of dn[] */ | |
| 24 Word16 ipos[] /* (o) : starting position for each pulse */ | |
| 25 ); | |
| 26 | |
| 27 void cor_h ( | |
| 28 Word16 h[], /* (i) : impulse response of weighted synthesis | |
| 29 filter */ | |
| 30 Word16 sign[], /* (i) : sign of d[n] */ | |
| 31 Word16 rr[][L_CODE] /* (o) : matrix of autocorrelation */ | |
| 32 ); | |
| 33 void search_10i40 ( | |
| 34 Word16 dn[], /* (i) : correlation between target and h[] */ | |
| 35 Word16 rr[][L_CODE], /* (i) : matrix of autocorrelation */ | |
| 36 Word16 ipos[], /* (i) : starting position for each pulse */ | |
| 37 Word16 pos_max[], /* (i) : position of maximum of dn[] */ | |
| 38 Word16 codvec[] /* (o) : algebraic codebook vector */ | |
| 39 ); | |
| 40 void build_code ( | |
| 41 Word16 codvec[], /* (i) : algebraic codebook vector */ | |
| 42 Word16 sign[], /* (i) : sign of dn[] */ | |
| 43 Word16 cod[], /* (o) : algebraic (fixed) codebook excitation */ | |
| 44 Word16 h[], /* (i) : impulse response of weighted synthesis filter*/ | |
| 45 Word16 y[], /* (o) : filtered fixed codebook excitation */ | |
| 46 Word16 indx[] /* (o) : index of 10 pulses (position+sign+ampl)*10 */ | |
| 47 ); | |
| 48 | |
| 49 void q_p ( | |
| 50 Word16 *ind, /* Pulse position */ | |
| 51 Word16 n /* Pulse number */ | |
| 52 ); | |
| 53 | |
| 54 /************************************************************************* | |
| 55 * | |
| 56 * FUNCTION: code_10i40_35bits() | |
| 57 * | |
| 58 * PURPOSE: Searches a 35 bit algebraic codebook containing 10 pulses | |
| 59 * in a frame of 40 samples. | |
| 60 * | |
| 61 * DESCRIPTION: | |
| 62 * The code contains 10 nonzero pulses: i0...i9. | |
| 63 * All pulses can have two possible amplitudes: +1 or -1. | |
| 64 * The 40 positions in a subframe are divided into 5 tracks of | |
| 65 * interleaved positions. Each track contains two pulses. | |
| 66 * The pulses can have the following possible positions: | |
| 67 * | |
| 68 * i0, i5 : 0, 5, 10, 15, 20, 25, 30, 35. | |
| 69 * i1, i6 : 1, 6, 11, 16, 21, 26, 31, 36. | |
| 70 * i2, i7 : 2, 7, 12, 17, 22, 27, 32, 37. | |
| 71 * i3, i8 : 3, 8, 13, 18, 23, 28, 33, 38. | |
| 72 * i4, i9 : 4, 9, 14, 19, 24, 29, 34, 39. | |
| 73 * | |
| 74 * Each pair of pulses require 1 bit for their signs and 6 bits for their | |
| 75 * positions (3 bits + 3 bits). This results in a 35 bit codebook. | |
| 76 * The function determines the optimal pulse signs and positions, builds | |
| 77 * the codevector, and computes the filtered codevector. | |
| 78 * | |
| 79 *************************************************************************/ | |
| 80 | |
| 81 void code_10i40_35bits ( | |
| 82 Word16 x[], /* (i) : target vector */ | |
| 83 Word16 cn[], /* (i) : residual after long term prediction */ | |
| 84 Word16 h[], /* (i) : impulse response of weighted synthesis filter | |
| 85 h[-L_subfr..-1] must be set to zero */ | |
| 86 Word16 cod[], /* (o) : algebraic (fixed) codebook excitation */ | |
| 87 Word16 y[], /* (o) : filtered fixed codebook excitation */ | |
| 88 Word16 indx[] /* (o) : index of 10 pulses (sign + position) */ | |
| 89 ) | |
| 90 { | |
| 91 Word16 ipos[NB_PULSE], pos_max[NB_TRACK], codvec[NB_PULSE]; | |
| 92 Word16 dn[L_CODE], sign[L_CODE]; | |
| 93 Word16 rr[L_CODE][L_CODE], i; | |
| 94 | |
| 95 cor_h_x (h, x, dn); | |
| 96 set_sign (dn, cn, sign, pos_max, ipos); | |
| 97 cor_h (h, sign, rr); | |
| 98 search_10i40 (dn, rr, ipos, pos_max, codvec); | |
| 99 build_code (codvec, sign, cod, h, y, indx); | |
| 100 for (i = 0; i < 10; i++) | |
| 101 { | |
| 102 q_p (&indx[i], i); | |
| 103 } | |
| 104 return; | |
| 105 } | |
| 106 | |
| 107 /************************************************************************* | |
| 108 * | |
| 109 * FUNCTION: cor_h_x() | |
| 110 * | |
| 111 * PURPOSE: Computes correlation between target signal "x[]" and | |
| 112 * impulse response"h[]". | |
| 113 * | |
| 114 * DESCRIPTION: | |
| 115 * The correlation is given by: | |
| 116 * d[n] = sum_{i=n}^{L-1} x[i] h[i-n] n=0,...,L-1 | |
| 117 * | |
| 118 * d[n] is normalized such that the sum of 5 maxima of d[n] corresponding | |
| 119 * to each position track does not saturate. | |
| 120 * | |
| 121 *************************************************************************/ | |
| 122 void cor_h_x ( | |
| 123 Word16 h[], /* (i) : impulse response of weighted synthesis filter */ | |
| 124 Word16 x[], /* (i) : target */ | |
| 125 Word16 dn[] /* (o) : correlation between target and h[] */ | |
| 126 ) | |
| 127 { | |
| 128 Word16 i, j, k; | |
| 129 Word32 s, y32[L_CODE], max, tot; | |
| 130 | |
| 131 /* first keep the result on 32 bits and find absolute maximum */ | |
| 132 | |
| 133 tot = 5; move32 (); | |
| 134 | |
| 135 for (k = 0; k < NB_TRACK; k++) | |
| 136 { | |
| 137 max = 0; move32 (); | |
| 138 for (i = k; i < L_CODE; i += STEP) | |
| 139 { | |
| 140 s = 0; move32 (); | |
| 141 for (j = i; j < L_CODE; j++) | |
| 142 s = L_mac (s, x[j], h[j - i]); | |
| 143 | |
| 144 y32[i] = s; move32 (); | |
| 145 | |
| 146 s = L_abs (s); | |
| 147 test (); | |
| 148 if (L_sub (s, max) > (Word32) 0L) | |
| 149 max = s; move32 (); | |
| 150 } | |
| 151 tot = L_add (tot, L_shr (max, 1)); | |
| 152 } | |
| 153 | |
| 154 j = sub (norm_l (tot), 2); /* multiply tot by 4 */ | |
| 155 | |
| 156 for (i = 0; i < L_CODE; i++) | |
| 157 { | |
| 158 dn[i] = round (L_shl (y32[i], j)); move16 (); | |
| 159 } | |
| 160 } | |
| 161 | |
| 162 /************************************************************************* | |
| 163 * | |
| 164 * FUNCTION set_sign() | |
| 165 * | |
| 166 * PURPOSE: Builds sign[] vector according to "dn[]" and "cn[]", and modifies | |
| 167 * dn[] to include the sign information (dn[i]=sign[i]*dn[i]). | |
| 168 * Also finds the position of maximum of correlation in each track | |
| 169 * and the starting position for each pulse. | |
| 170 * | |
| 171 *************************************************************************/ | |
| 172 | |
| 173 void set_sign ( | |
| 174 Word16 dn[], /* (i/o): correlation between target and h[] */ | |
| 175 Word16 cn[], /* (i) : residual after long term prediction */ | |
| 176 Word16 sign[], /* (o) : sign of d[n] */ | |
| 177 Word16 pos_max[], /* (o) : position of maximum correlation */ | |
| 178 Word16 ipos[] /* (o) : starting position for each pulse */ | |
| 179 ) | |
| 180 { | |
| 181 Word16 i, j; | |
| 182 Word16 val, cor, k_cn, k_dn, max, max_of_all, pos; | |
| 183 Word16 en[L_CODE]; /* correlation vector */ | |
| 184 Word32 s; | |
| 185 | |
| 186 /* calculate energy for normalization of cn[] and dn[] */ | |
| 187 | |
| 188 s = 256; move32 (); | |
| 189 for (i = 0; i < L_CODE; i++) | |
| 190 { | |
| 191 s = L_mac (s, cn[i], cn[i]); | |
| 192 } | |
| 193 s = Inv_sqrt (s); move32 (); | |
| 194 k_cn = extract_h (L_shl (s, 5)); | |
| 195 | |
| 196 s = 256; move32 (); | |
| 197 for (i = 0; i < L_CODE; i++) | |
| 198 { | |
| 199 s = L_mac (s, dn[i], dn[i]); | |
| 200 } | |
| 201 s = Inv_sqrt (s); move32 (); | |
| 202 k_dn = extract_h (L_shl (s, 5)); | |
| 203 | |
| 204 for (i = 0; i < L_CODE; i++) | |
| 205 { | |
| 206 val = dn[i]; move16 (); | |
| 207 cor = round (L_shl (L_mac (L_mult (k_cn, cn[i]), k_dn, val), 10)); | |
| 208 | |
| 209 test (); | |
| 210 if (cor >= 0) | |
| 211 { | |
| 212 sign[i] = 32767; move16 (); /* sign = +1 */ | |
| 213 } | |
| 214 else | |
| 215 { | |
| 216 sign[i] = -32767; move16 (); /* sign = -1 */ | |
| 217 cor = negate (cor); | |
| 218 val = negate (val); | |
| 219 } | |
| 220 /* modify dn[] according to the fixed sign */ | |
| 221 dn[i] = val; move16 (); | |
| 222 en[i] = cor; move16 (); | |
| 223 } | |
| 224 | |
| 225 max_of_all = -1; move16 (); | |
| 226 for (i = 0; i < NB_TRACK; i++) | |
| 227 { | |
| 228 max = -1; move16 (); | |
| 229 | |
| 230 for (j = i; j < L_CODE; j += STEP) | |
| 231 { | |
| 232 cor = en[j]; move16 (); | |
| 233 val = sub (cor, max); | |
| 234 test (); | |
| 235 if (val > 0) | |
| 236 { | |
| 237 max = cor; move16 (); | |
| 238 pos = j; move16 (); | |
| 239 } | |
| 240 } | |
| 241 /* store maximum correlation position */ | |
| 242 pos_max[i] = pos; move16 (); | |
| 243 val = sub (max, max_of_all); | |
| 244 test (); | |
| 245 if (val > 0) | |
| 246 { | |
| 247 max_of_all = max; move16 (); | |
| 248 /* starting position for i0 */ | |
| 249 ipos[0] = i; move16 (); | |
| 250 } | |
| 251 } | |
| 252 | |
| 253 /*----------------------------------------------------------------* | |
| 254 * Set starting position of each pulse. * | |
| 255 *----------------------------------------------------------------*/ | |
| 256 | |
| 257 pos = ipos[0]; move16 (); | |
| 258 ipos[5] = pos; move16 (); | |
| 259 | |
| 260 for (i = 1; i < NB_TRACK; i++) | |
| 261 { | |
| 262 pos = add (pos, 1); | |
| 263 if (sub (pos, NB_TRACK) >= 0) | |
| 264 { | |
| 265 pos = 0; move16 (); | |
| 266 } | |
| 267 ipos[i] = pos; move16 (); | |
| 268 ipos[i + 5] = pos; move16 (); | |
| 269 } | |
| 270 } | |
| 271 | |
| 272 void q_p ( | |
| 273 Word16 *ind, /* Pulse position */ | |
| 274 Word16 n /* Pulse number */ | |
| 275 ) | |
| 276 { | |
| 277 static const Word16 gray[8] = {0, 1, 3, 2, 6, 4, 5, 7}; | |
| 278 Word16 tmp; | |
| 279 | |
| 280 tmp = *ind; move16 (); | |
| 281 | |
| 282 test (); | |
| 283 if (sub (n, 5) < 0) | |
| 284 { | |
| 285 tmp = (tmp & 0x8) | gray[tmp & 0x7]; logic16 (); logic16 (); | |
| 286 logic16 (); | |
| 287 } | |
| 288 else | |
| 289 { | |
| 290 tmp = gray[tmp & 0x7]; logic16 (); move16 (); | |
| 291 } | |
| 292 | |
| 293 *ind = tmp; move16 (); | |
| 294 } | |
| 295 | |
| 296 /************************************************************************* | |
| 297 * | |
| 298 * FUNCTION: cor_h() | |
| 299 * | |
| 300 * PURPOSE: Computes correlations of h[] needed for the codebook search; | |
| 301 * and includes the sign information into the correlations. | |
| 302 * | |
| 303 * DESCRIPTION: The correlations are given by | |
| 304 * rr[i][j] = sum_{n=i}^{L-1} h[n-i] h[n-j]; i>=j; i,j=0,...,L-1 | |
| 305 * | |
| 306 * and the sign information is included by | |
| 307 * rr[i][j] = rr[i][j]*sign[i]*sign[j] | |
| 308 * | |
| 309 *************************************************************************/ | |
| 310 | |
| 311 void cor_h ( | |
| 312 Word16 h[], /* (i) : impulse response of weighted synthesis | |
| 313 filter */ | |
| 314 Word16 sign[], /* (i) : sign of d[n] */ | |
| 315 Word16 rr[][L_CODE] /* (o) : matrix of autocorrelation */ | |
| 316 ) | |
| 317 { | |
| 318 Word16 i, j, k, dec, h2[L_CODE]; | |
| 319 Word32 s; | |
| 320 | |
| 321 /* Scaling for maximum precision */ | |
| 322 | |
| 323 s = 2; move32 (); | |
| 324 for (i = 0; i < L_CODE; i++) | |
| 325 s = L_mac (s, h[i], h[i]); | |
| 326 | |
| 327 j = sub (extract_h (s), 32767); | |
| 328 test (); | |
| 329 if (j == 0) | |
| 330 { | |
| 331 for (i = 0; i < L_CODE; i++) | |
| 332 { | |
| 333 h2[i] = shr (h[i], 1); move16 (); | |
| 334 } | |
| 335 } | |
| 336 else | |
| 337 { | |
| 338 s = L_shr (s, 1); | |
| 339 k = extract_h (L_shl (Inv_sqrt (s), 7)); | |
| 340 k = mult (k, 32440); /* k = 0.99*k */ | |
| 341 | |
| 342 for (i = 0; i < L_CODE; i++) | |
| 343 { | |
| 344 h2[i] = round (L_shl (L_mult (h[i], k), 9)); | |
| 345 move16 (); | |
| 346 } | |
| 347 } | |
| 348 | |
| 349 /* build matrix rr[] */ | |
| 350 s = 0; move32 (); | |
| 351 i = L_CODE - 1; | |
| 352 for (k = 0; k < L_CODE; k++, i--) | |
| 353 { | |
| 354 s = L_mac (s, h2[k], h2[k]); | |
| 355 rr[i][i] = round (s); move16 (); | |
| 356 } | |
| 357 | |
| 358 for (dec = 1; dec < L_CODE; dec++) | |
| 359 { | |
| 360 s = 0; move32 (); | |
| 361 j = L_CODE - 1; | |
| 362 i = sub (j, dec); | |
| 363 for (k = 0; k < (L_CODE - dec); k++, i--, j--) | |
| 364 { | |
| 365 s = L_mac (s, h2[k], h2[k + dec]); | |
| 366 rr[j][i] = mult (round (s), mult (sign[i], sign[j])); | |
| 367 move16 (); | |
| 368 rr[i][j] = rr[j][i]; move16 (); | |
| 369 } | |
| 370 } | |
| 371 } | |
| 372 | |
| 373 /************************************************************************* | |
| 374 * | |
| 375 * FUNCTION search_10i40() | |
| 376 * | |
| 377 * PURPOSE: Search the best codevector; determine positions of the 10 pulses | |
| 378 * in the 40-sample frame. | |
| 379 * | |
| 380 *************************************************************************/ | |
| 381 | |
| 382 #define _1_2 (Word16)(32768L/2) | |
| 383 #define _1_4 (Word16)(32768L/4) | |
| 384 #define _1_8 (Word16)(32768L/8) | |
| 385 #define _1_16 (Word16)(32768L/16) | |
| 386 #define _1_32 (Word16)(32768L/32) | |
| 387 #define _1_64 (Word16)(32768L/64) | |
| 388 #define _1_128 (Word16)(32768L/128) | |
| 389 | |
| 390 void search_10i40 ( | |
| 391 Word16 dn[], /* (i) : correlation between target and h[] */ | |
| 392 Word16 rr[][L_CODE], /* (i) : matrix of autocorrelation */ | |
| 393 Word16 ipos[], /* (i) : starting position for each pulse */ | |
| 394 Word16 pos_max[], /* (i) : position of maximum of dn[] */ | |
| 395 Word16 codvec[] /* (o) : algebraic codebook vector */ | |
| 396 ) | |
| 397 { | |
| 398 Word16 i0, i1, i2, i3, i4, i5, i6, i7, i8, i9; | |
| 399 Word16 i, j, k, pos, ia, ib; | |
| 400 Word16 psk, ps, ps0, ps1, ps2, sq, sq2; | |
| 401 Word16 alpk, alp, alp_16; | |
| 402 Word16 rrv[L_CODE]; | |
| 403 Word32 s, alp0, alp1, alp2; | |
| 404 | |
| 405 /* fix i0 on maximum of correlation position */ | |
| 406 | |
| 407 i0 = pos_max[ipos[0]]; move16 (); | |
| 408 | |
| 409 /*------------------------------------------------------------------* | |
| 410 * i1 loop: * | |
| 411 *------------------------------------------------------------------*/ | |
| 412 | |
| 413 /* Default value */ | |
| 414 psk = -1; move16 (); | |
| 415 alpk = 1; move16 (); | |
| 416 for (i = 0; i < NB_PULSE; i++) | |
| 417 { | |
| 418 codvec[i] = i; move16 (); | |
| 419 } | |
| 420 | |
| 421 for (i = 1; i < NB_TRACK; i++) | |
| 422 { | |
| 423 i1 = pos_max[ipos[1]]; move16 (); | |
| 424 ps0 = add (dn[i0], dn[i1]); | |
| 425 alp0 = L_mult (rr[i0][i0], _1_16); | |
| 426 alp0 = L_mac (alp0, rr[i1][i1], _1_16); | |
| 427 alp0 = L_mac (alp0, rr[i0][i1], _1_8); | |
| 428 | |
| 429 /*----------------------------------------------------------------* | |
| 430 * i2 and i3 loop: * | |
| 431 *----------------------------------------------------------------*/ | |
| 432 | |
| 433 /* initialize 4 indices for next loop. */ | |
| 434 move16 (); /* initialize "rr[i3][i3]" pointer */ | |
| 435 move16 (); /* initialize "rr[i0][i3]" pointer */ | |
| 436 move16 (); /* initialize "rr[i1][i3]" pointer */ | |
| 437 move16 (); /* initialize "rrv[i3]" pointer */ | |
| 438 | |
| 439 for (i3 = ipos[3]; i3 < L_CODE; i3 += STEP) | |
| 440 { | |
| 441 s = L_mult (rr[i3][i3], _1_8); /* index incr= STEP+L_CODE */ | |
| 442 s = L_mac (s, rr[i0][i3], _1_4); /* index increment = STEP */ | |
| 443 s = L_mac (s, rr[i1][i3], _1_4); /* index increment = STEP */ | |
| 444 rrv[i3] = round (s); move16 (); | |
| 445 } | |
| 446 | |
| 447 /* Default value */ | |
| 448 sq = -1; move16 (); | |
| 449 alp = 1; move16 (); | |
| 450 ps = 0; move16 (); | |
| 451 ia = ipos[2]; move16 (); | |
| 452 ib = ipos[3]; move16 (); | |
| 453 | |
| 454 /* initialize 4 indices for i2 loop. */ | |
| 455 move16 (); /* initialize "dn[i2]" pointer */ | |
| 456 move16 (); /* initialize "rr[i2][i2]" pointer */ | |
| 457 move16 (); /* initialize "rr[i0][i2]" pointer */ | |
| 458 move16 (); /* initialize "rr[i1][i2]" pointer */ | |
| 459 | |
| 460 for (i2 = ipos[2]; i2 < L_CODE; i2 += STEP) | |
| 461 { | |
| 462 /* index increment = STEP */ | |
| 463 ps1 = add (ps0, dn[i2]); | |
| 464 | |
| 465 /* index incr= STEP+L_CODE */ | |
| 466 alp1 = L_mac (alp0, rr[i2][i2], _1_16); | |
| 467 /* index increment = STEP */ | |
| 468 alp1 = L_mac (alp1, rr[i0][i2], _1_8); | |
| 469 /* index increment = STEP */ | |
| 470 alp1 = L_mac (alp1, rr[i1][i2], _1_8); | |
| 471 | |
| 472 /* initialize 3 indices for i3 inner loop */ | |
| 473 move16 (); /* initialize "dn[i3]" pointer */ | |
| 474 move16 (); /* initialize "rrv[i3]" pointer */ | |
| 475 move16 (); /* initialize "rr[i2][i3]" pointer */ | |
| 476 | |
| 477 for (i3 = ipos[3]; i3 < L_CODE; i3 += STEP) | |
| 478 { | |
| 479 /* index increment = STEP */ | |
| 480 ps2 = add (ps1, dn[i3]); | |
| 481 | |
| 482 /* index increment = STEP */ | |
| 483 alp2 = L_mac (alp1, rrv[i3], _1_2); | |
| 484 /* index increment = STEP */ | |
| 485 alp2 = L_mac (alp2, rr[i2][i3], _1_8); | |
| 486 | |
| 487 sq2 = mult (ps2, ps2); | |
| 488 | |
| 489 alp_16 = round (alp2); | |
| 490 | |
| 491 s = L_msu (L_mult (alp, sq2), sq, alp_16); | |
| 492 | |
| 493 test (); | |
| 494 if (s > 0) | |
| 495 { | |
| 496 sq = sq2; move16 (); | |
| 497 ps = ps2; move16 (); | |
| 498 alp = alp_16; move16 (); | |
| 499 ia = i2; move16 (); | |
| 500 ib = i3; move16 (); | |
| 501 } | |
| 502 } | |
| 503 } | |
| 504 i2 = ia; move16 (); | |
| 505 i3 = ib; move16 (); | |
| 506 | |
| 507 /*----------------------------------------------------------------* | |
| 508 * i4 and i5 loop: * | |
| 509 *----------------------------------------------------------------*/ | |
| 510 | |
| 511 ps0 = ps; move16 (); | |
| 512 alp0 = L_mult (alp, _1_2); | |
| 513 | |
| 514 /* initialize 6 indices for next loop (see i2-i3 loop) */ | |
| 515 move16 (); move16 (); move16 (); move16 (); move16 (); move16 (); | |
| 516 | |
| 517 for (i5 = ipos[5]; i5 < L_CODE; i5 += STEP) | |
| 518 { | |
| 519 s = L_mult (rr[i5][i5], _1_8); | |
| 520 s = L_mac (s, rr[i0][i5], _1_4); | |
| 521 s = L_mac (s, rr[i1][i5], _1_4); | |
| 522 s = L_mac (s, rr[i2][i5], _1_4); | |
| 523 s = L_mac (s, rr[i3][i5], _1_4); | |
| 524 rrv[i5] = round (s); move16 (); | |
| 525 } | |
| 526 | |
| 527 /* Default value */ | |
| 528 sq = -1; move16 (); | |
| 529 alp = 1; move16 (); | |
| 530 ps = 0; move16 (); | |
| 531 ia = ipos[4]; move16 (); | |
| 532 ib = ipos[5]; move16 (); | |
| 533 | |
| 534 /* initialize 6 indices for i4 loop (see i2-i3 loop) */ | |
| 535 move16 (); move16 (); move16 (); move16 (); move16 (); move16 (); | |
| 536 | |
| 537 for (i4 = ipos[4]; i4 < L_CODE; i4 += STEP) | |
| 538 { | |
| 539 ps1 = add (ps0, dn[i4]); | |
| 540 | |
| 541 alp1 = L_mac (alp0, rr[i4][i4], _1_32); | |
| 542 alp1 = L_mac (alp1, rr[i0][i4], _1_16); | |
| 543 alp1 = L_mac (alp1, rr[i1][i4], _1_16); | |
| 544 alp1 = L_mac (alp1, rr[i2][i4], _1_16); | |
| 545 alp1 = L_mac (alp1, rr[i3][i4], _1_16); | |
| 546 | |
| 547 /* initialize 3 indices for i5 inner loop (see i2-i3 loop) */ | |
| 548 move16 (); move16 (); move16 (); | |
| 549 | |
| 550 for (i5 = ipos[5]; i5 < L_CODE; i5 += STEP) | |
| 551 { | |
| 552 ps2 = add (ps1, dn[i5]); | |
| 553 | |
| 554 alp2 = L_mac (alp1, rrv[i5], _1_4); | |
| 555 alp2 = L_mac (alp2, rr[i4][i5], _1_16); | |
| 556 | |
| 557 sq2 = mult (ps2, ps2); | |
| 558 | |
| 559 alp_16 = round (alp2); | |
| 560 | |
| 561 s = L_msu (L_mult (alp, sq2), sq, alp_16); | |
| 562 | |
| 563 test (); | |
| 564 if (s > 0) | |
| 565 { | |
| 566 sq = sq2; move16 (); | |
| 567 ps = ps2; move16 (); | |
| 568 alp = alp_16; move16 (); | |
| 569 ia = i4; move16 (); | |
| 570 ib = i5; move16 (); | |
| 571 } | |
| 572 } | |
| 573 } | |
| 574 i4 = ia; move16 (); | |
| 575 i5 = ib; move16 (); | |
| 576 | |
| 577 /*----------------------------------------------------------------* | |
| 578 * i6 and i7 loop: * | |
| 579 *----------------------------------------------------------------*/ | |
| 580 | |
| 581 ps0 = ps; move16 (); | |
| 582 alp0 = L_mult (alp, _1_2); | |
| 583 | |
| 584 /* initialize 8 indices for next loop (see i2-i3 loop) */ | |
| 585 move16 (); move16 (); move16 (); move16 (); | |
| 586 move16 (); move16 (); move16 (); move16 (); | |
| 587 | |
| 588 for (i7 = ipos[7]; i7 < L_CODE; i7 += STEP) | |
| 589 { | |
| 590 s = L_mult (rr[i7][i7], _1_16); | |
| 591 s = L_mac (s, rr[i0][i7], _1_8); | |
| 592 s = L_mac (s, rr[i1][i7], _1_8); | |
| 593 s = L_mac (s, rr[i2][i7], _1_8); | |
| 594 s = L_mac (s, rr[i3][i7], _1_8); | |
| 595 s = L_mac (s, rr[i4][i7], _1_8); | |
| 596 s = L_mac (s, rr[i5][i7], _1_8); | |
| 597 rrv[i7] = round (s); move16 (); | |
| 598 } | |
| 599 | |
| 600 /* Default value */ | |
| 601 sq = -1; move16 (); | |
| 602 alp = 1; move16 (); | |
| 603 ps = 0; move16 (); | |
| 604 ia = ipos[6]; move16 (); | |
| 605 ib = ipos[7]; move16 (); | |
| 606 | |
| 607 /* initialize 8 indices for i6 loop (see i2-i3 loop) */ | |
| 608 move16 (); move16 (); move16 (); move16 (); | |
| 609 move16 (); move16 (); move16 (); move16 (); | |
| 610 | |
| 611 for (i6 = ipos[6]; i6 < L_CODE; i6 += STEP) | |
| 612 { | |
| 613 ps1 = add (ps0, dn[i6]); | |
| 614 | |
| 615 alp1 = L_mac (alp0, rr[i6][i6], _1_64); | |
| 616 alp1 = L_mac (alp1, rr[i0][i6], _1_32); | |
| 617 alp1 = L_mac (alp1, rr[i1][i6], _1_32); | |
| 618 alp1 = L_mac (alp1, rr[i2][i6], _1_32); | |
| 619 alp1 = L_mac (alp1, rr[i3][i6], _1_32); | |
| 620 alp1 = L_mac (alp1, rr[i4][i6], _1_32); | |
| 621 alp1 = L_mac (alp1, rr[i5][i6], _1_32); | |
| 622 | |
| 623 /* initialize 3 indices for i7 inner loop (see i2-i3 loop) */ | |
| 624 move16 (); move16 (); move16 (); | |
| 625 | |
| 626 for (i7 = ipos[7]; i7 < L_CODE; i7 += STEP) | |
| 627 { | |
| 628 ps2 = add (ps1, dn[i7]); | |
| 629 | |
| 630 alp2 = L_mac (alp1, rrv[i7], _1_4); | |
| 631 alp2 = L_mac (alp2, rr[i6][i7], _1_32); | |
| 632 | |
| 633 sq2 = mult (ps2, ps2); | |
| 634 | |
| 635 alp_16 = round (alp2); | |
| 636 | |
| 637 s = L_msu (L_mult (alp, sq2), sq, alp_16); | |
| 638 | |
| 639 test (); | |
| 640 if (s > 0) | |
| 641 { | |
| 642 sq = sq2; move16 (); | |
| 643 ps = ps2; move16 (); | |
| 644 alp = alp_16; move16 (); | |
| 645 ia = i6; move16 (); | |
| 646 ib = i7; move16 (); | |
| 647 } | |
| 648 } | |
| 649 } | |
| 650 i6 = ia; move16 (); | |
| 651 i7 = ib; move16 (); | |
| 652 | |
| 653 /*----------------------------------------------------------------* | |
| 654 * i8 and i9 loop: * | |
| 655 *----------------------------------------------------------------*/ | |
| 656 | |
| 657 ps0 = ps; move16 (); | |
| 658 alp0 = L_mult (alp, _1_2); | |
| 659 | |
| 660 /* initialize 10 indices for next loop (see i2-i3 loop) */ | |
| 661 move16 (); move16 (); move16 (); move16 (); move16 (); | |
| 662 move16 (); move16 (); move16 (); move16 (); move16 (); | |
| 663 | |
| 664 for (i9 = ipos[9]; i9 < L_CODE; i9 += STEP) | |
| 665 { | |
| 666 s = L_mult (rr[i9][i9], _1_16); | |
| 667 s = L_mac (s, rr[i0][i9], _1_8); | |
| 668 s = L_mac (s, rr[i1][i9], _1_8); | |
| 669 s = L_mac (s, rr[i2][i9], _1_8); | |
| 670 s = L_mac (s, rr[i3][i9], _1_8); | |
| 671 s = L_mac (s, rr[i4][i9], _1_8); | |
| 672 s = L_mac (s, rr[i5][i9], _1_8); | |
| 673 s = L_mac (s, rr[i6][i9], _1_8); | |
| 674 s = L_mac (s, rr[i7][i9], _1_8); | |
| 675 rrv[i9] = round (s); move16 (); | |
| 676 } | |
| 677 | |
| 678 /* Default value */ | |
| 679 sq = -1; move16 (); | |
| 680 alp = 1; move16 (); | |
| 681 ps = 0; move16 (); | |
| 682 ia = ipos[8]; move16 (); | |
| 683 ib = ipos[9]; move16 (); | |
| 684 | |
| 685 /* initialize 10 indices for i8 loop (see i2-i3 loop) */ | |
| 686 move16 (); move16 (); move16 (); move16 (); move16 (); | |
| 687 move16 (); move16 (); move16 (); move16 (); move16 (); | |
| 688 | |
| 689 for (i8 = ipos[8]; i8 < L_CODE; i8 += STEP) | |
| 690 { | |
| 691 ps1 = add (ps0, dn[i8]); | |
| 692 | |
| 693 alp1 = L_mac (alp0, rr[i8][i8], _1_128); | |
| 694 alp1 = L_mac (alp1, rr[i0][i8], _1_64); | |
| 695 alp1 = L_mac (alp1, rr[i1][i8], _1_64); | |
| 696 alp1 = L_mac (alp1, rr[i2][i8], _1_64); | |
| 697 alp1 = L_mac (alp1, rr[i3][i8], _1_64); | |
| 698 alp1 = L_mac (alp1, rr[i4][i8], _1_64); | |
| 699 alp1 = L_mac (alp1, rr[i5][i8], _1_64); | |
| 700 alp1 = L_mac (alp1, rr[i6][i8], _1_64); | |
| 701 alp1 = L_mac (alp1, rr[i7][i8], _1_64); | |
| 702 | |
| 703 /* initialize 3 indices for i9 inner loop (see i2-i3 loop) */ | |
| 704 move16 (); move16 (); move16 (); | |
| 705 | |
| 706 for (i9 = ipos[9]; i9 < L_CODE; i9 += STEP) | |
| 707 { | |
| 708 ps2 = add (ps1, dn[i9]); | |
| 709 | |
| 710 alp2 = L_mac (alp1, rrv[i9], _1_8); | |
| 711 alp2 = L_mac (alp2, rr[i8][i9], _1_64); | |
| 712 | |
| 713 sq2 = mult (ps2, ps2); | |
| 714 | |
| 715 alp_16 = round (alp2); | |
| 716 | |
| 717 s = L_msu (L_mult (alp, sq2), sq, alp_16); | |
| 718 | |
| 719 test (); | |
| 720 if (s > 0) | |
| 721 { | |
| 722 sq = sq2; move16 (); | |
| 723 ps = ps2; move16 (); | |
| 724 alp = alp_16; move16 (); | |
| 725 ia = i8; move16 (); | |
| 726 ib = i9; move16 (); | |
| 727 } | |
| 728 } | |
| 729 } | |
| 730 | |
| 731 /*----------------------------------------------------------------* | |
| 732 * memorise codevector if this one is better than the last one. * | |
| 733 *----------------------------------------------------------------*/ | |
| 734 | |
| 735 s = L_msu (L_mult (alpk, sq), psk, alp); | |
| 736 | |
| 737 test (); | |
| 738 if (s > 0) | |
| 739 { | |
| 740 psk = sq; move16 (); | |
| 741 alpk = alp; move16 (); | |
| 742 codvec[0] = i0; move16 (); | |
| 743 codvec[1] = i1; move16 (); | |
| 744 codvec[2] = i2; move16 (); | |
| 745 codvec[3] = i3; move16 (); | |
| 746 codvec[4] = i4; move16 (); | |
| 747 codvec[5] = i5; move16 (); | |
| 748 codvec[6] = i6; move16 (); | |
| 749 codvec[7] = i7; move16 (); | |
| 750 codvec[8] = ia; move16 (); | |
| 751 codvec[9] = ib; move16 (); | |
| 752 } | |
| 753 /*----------------------------------------------------------------* | |
| 754 * Cyclic permutation of i1,i2,i3,i4,i5,i6,i7,i8 and i9. * | |
| 755 *----------------------------------------------------------------*/ | |
| 756 | |
| 757 pos = ipos[1]; move16 (); | |
| 758 for (j = 1, k = 2; k < NB_PULSE; j++, k++) | |
| 759 { | |
| 760 ipos[j] = ipos[k]; move16 (); | |
| 761 } | |
| 762 ipos[NB_PULSE - 1] = pos; move16 (); | |
| 763 } | |
| 764 } | |
| 765 | |
| 766 /************************************************************************* | |
| 767 * | |
| 768 * FUNCTION: build_code() | |
| 769 * | |
| 770 * PURPOSE: Builds the codeword, the filtered codeword and index of the | |
| 771 * codevector, based on the signs and positions of 10 pulses. | |
| 772 * | |
| 773 *************************************************************************/ | |
| 774 | |
| 775 void build_code ( | |
| 776 Word16 codvec[], /* (i) : position of pulses */ | |
| 777 Word16 sign[], /* (i) : sign of d[n] */ | |
| 778 Word16 cod[], /* (o) : innovative code vector */ | |
| 779 Word16 h[], /* (i) : impulse response of weighted synthesis filter*/ | |
| 780 Word16 y[], /* (o) : filtered innovative code */ | |
| 781 Word16 indx[] /* (o) : index of 10 pulses (sign+position) */ | |
| 782 ) | |
| 783 { | |
| 784 Word16 i, j, k, track, index, _sign[NB_PULSE]; | |
| 785 Word16 *p0, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9; | |
| 786 Word32 s; | |
| 787 | |
| 788 for (i = 0; i < L_CODE; i++) | |
| 789 { | |
| 790 cod[i] = 0; move16 (); | |
| 791 } | |
| 792 for (i = 0; i < NB_TRACK; i++) | |
| 793 { | |
| 794 indx[i] = -1; move16 (); | |
| 795 } | |
| 796 | |
| 797 for (k = 0; k < NB_PULSE; k++) | |
| 798 { | |
| 799 /* read pulse position */ | |
| 800 i = codvec[k]; move16 (); | |
| 801 /* read sign */ | |
| 802 j = sign[i]; move16 (); | |
| 803 | |
| 804 index = mult (i, 6554); /* index = pos/5 */ | |
| 805 /* track = pos%5 */ | |
| 806 track = sub (i, extract_l (L_shr (L_mult (index, 5), 1))); | |
| 807 test (); | |
| 808 if (j > 0) | |
| 809 { | |
| 810 cod[i] = add (cod[i], 4096); | |
| 811 _sign[k] = 8192; move16 (); | |
| 812 | |
| 813 } | |
| 814 else | |
| 815 { | |
| 816 cod[i] = sub (cod[i], 4096); | |
| 817 _sign[k] = -8192; move16 (); | |
| 818 index = add (index, 8); | |
| 819 } | |
| 820 | |
| 821 test (); | |
| 822 if (indx[track] < 0) | |
| 823 { | |
| 824 indx[track] = index; move16 (); | |
| 825 } | |
| 826 else | |
| 827 { | |
| 828 test (); logic16 (); logic16 (); | |
| 829 if (((index ^ indx[track]) & 8) == 0) | |
| 830 { | |
| 831 /* sign of 1st pulse == sign of 2nd pulse */ | |
| 832 | |
| 833 test (); | |
| 834 if (sub (indx[track], index) <= 0) | |
| 835 { | |
| 836 indx[track + 5] = index; move16 (); | |
| 837 } | |
| 838 else | |
| 839 { | |
| 840 indx[track + 5] = indx[track]; | |
| 841 move16 (); | |
| 842 indx[track] = index; move16 (); | |
| 843 } | |
| 844 } | |
| 845 else | |
| 846 { | |
| 847 /* sign of 1st pulse != sign of 2nd pulse */ | |
| 848 | |
| 849 test (); logic16 (); logic16 (); | |
| 850 if (sub ((indx[track] & 7), (index & 7)) <= 0) | |
| 851 { | |
| 852 indx[track + 5] = indx[track]; | |
| 853 move16 (); | |
| 854 indx[track] = index; move16 (); | |
| 855 } | |
| 856 else | |
| 857 { | |
| 858 indx[track + 5] = index; move16 (); | |
| 859 } | |
| 860 } | |
| 861 } | |
| 862 } | |
| 863 | |
| 864 p0 = h - codvec[0]; move16 (); | |
| 865 p1 = h - codvec[1]; move16 (); | |
| 866 p2 = h - codvec[2]; move16 (); | |
| 867 p3 = h - codvec[3]; move16 (); | |
| 868 p4 = h - codvec[4]; move16 (); | |
| 869 p5 = h - codvec[5]; move16 (); | |
| 870 p6 = h - codvec[6]; move16 (); | |
| 871 p7 = h - codvec[7]; move16 (); | |
| 872 p8 = h - codvec[8]; move16 (); | |
| 873 p9 = h - codvec[9]; move16 (); | |
| 874 | |
| 875 for (i = 0; i < L_CODE; i++) | |
| 876 { | |
| 877 s = 0; move32 (); | |
| 878 s = L_mac (s, *p0++, _sign[0]); | |
| 879 s = L_mac (s, *p1++, _sign[1]); | |
| 880 s = L_mac (s, *p2++, _sign[2]); | |
| 881 s = L_mac (s, *p3++, _sign[3]); | |
| 882 s = L_mac (s, *p4++, _sign[4]); | |
| 883 s = L_mac (s, *p5++, _sign[5]); | |
| 884 s = L_mac (s, *p6++, _sign[6]); | |
| 885 s = L_mac (s, *p7++, _sign[7]); | |
| 886 s = L_mac (s, *p8++, _sign[8]); | |
| 887 s = L_mac (s, *p9++, _sign[9]); | |
| 888 y[i] = round (s); move16 (); | |
| 889 } | |
| 890 } | |
| 891 |
