- Timestamp:
- Jul 26, 2006 5:04:54 PM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia-codec/speex/ltp_bfin.h
r278 r628 35 35 36 36 #define OVERRIDE_INNER_PROD 37 s tatic spx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len)37 spx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len) 38 38 { 39 39 spx_word32_t sum=0; … … 64 64 65 65 #define OVERRIDE_PITCH_XCORR 66 staticvoid pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack)66 void pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack) 67 67 { 68 68 corr += nb_pitch - 1; … … 110 110 111 111 #define OVERRIDE_COMPUTE_PITCH_ERROR 112 static inline spx_word32_t compute_pitch_error(spx_word 32_t *C, spx_word16_t *g, spx_word16_t pitch_control)112 static inline spx_word32_t compute_pitch_error(spx_word16_t *C, spx_word16_t *g, spx_word16_t pitch_control) 113 113 { 114 114 spx_word32_t sum; 115 115 __asm__ __volatile__ 116 116 ( 117 "A 1 = A0 = 0;\n\t"118 119 "R0 = [%1++];\n\t"117 "A0 = 0;\n\t" 118 119 "R0 = W[%1++];\n\t" 120 120 "R1.L = %2.L*%5.L (IS);\n\t" 121 "R0 <<= 1;\n\t" 122 "A1 += R1.L*R0.L (M), A0 += R1.L*R0.H (IS) || R0 = [%1++];\n\t" 121 "A0 += R1.L*R0.L (IS) || R0 = W[%1++];\n\t" 123 122 124 123 "R1.L = %3.L*%5.L (IS);\n\t" 125 "R0 <<= 1;\n\t" 126 "A1 += R1.L*R0.L (M), A0 += R1.L*R0.H (IS) || R0 = [%1++];\n\t" 124 "A0 += R1.L*R0.L (IS) || R0 = W[%1++];\n\t" 127 125 128 126 "R1.L = %4.L*%5.L (IS);\n\t" 129 "R0 <<= 1;\n\t" 130 "A1 += R1.L*R0.L (M), A0 += R1.L*R0.H (IS) || R0 = [%1++];\n\t" 127 "A0 += R1.L*R0.L (IS) || R0 = W[%1++];\n\t" 131 128 132 129 "R1.L = %2.L*%3.L (IS);\n\t" 133 "R0 <<= 1;\n\t" 134 "A1 -= R1.L*R0.L (M), A0 -= R1.L*R0.H (IS) || R0 = [%1++];\n\t" 130 "A0 -= R1.L*R0.L (IS) || R0 = W[%1++];\n\t" 135 131 136 132 "R1.L = %4.L*%3.L (IS);\n\t" 137 "R0 <<= 1;\n\t" 138 "A1 -= R1.L*R0.L (M), A0 -= R1.L*R0.H (IS) || R0 = [%1++];\n\t" 133 "A0 -= R1.L*R0.L (IS) || R0 = W[%1++];\n\t" 139 134 140 135 "R1.L = %4.L*%2.L (IS);\n\t" 141 "R0 <<= 1;\n\t" 142 "A1 -= R1.L*R0.L (M), A0 -= R1.L*R0.H (IS) || R0 = [%1++];\n\t" 136 "A0 -= R1.L*R0.L (IS) || R0 = W[%1++];\n\t" 143 137 144 138 "R1.L = %2.L*%2.L (IS);\n\t" 145 "R0 <<= 1;\n\t" 146 "A1 -= R1.L*R0.L (M), A0 -= R1.L*R0.H (IS) || R0 = [%1++];\n\t" 139 "A0 -= R1.L*R0.L (IS) || R0 = W[%1++];\n\t" 147 140 148 141 "R1.L = %3.L*%3.L (IS);\n\t" 149 "R0 <<= 1;\n\t" 150 "A1 -= R1.L*R0.L (M), A0 -= R1.L*R0.H (IS) || R0 = [%1++];\n\t" 142 "A0 -= R1.L*R0.L (IS) || R0 = W[%1++];\n\t" 151 143 152 144 "R1.L = %4.L*%4.L (IS);\n\t" 153 "R0 <<= 1;\n\t" 154 "A1 -= R1.L*R0.L (M), A0 -= R1.L*R0.H (IS);\n\t" 155 156 "A1 = A1 >>> 16;\n\t" 157 "A0 += A1;\n\t" 145 "A0 -= R1.L*R0.L (IS);\n\t" 146 158 147 "%0 = A0;\n\t" 159 148 : "=&D" (sum), "=a" (C) … … 164 153 } 165 154 155 #define OVERRIDE_OPEN_LOOP_NBEST_PITCH 156 #ifdef OVERRIDE_OPEN_LOOP_NBEST_PITCH 157 void open_loop_nbest_pitch(spx_word16_t *sw, int start, int end, int len, int *pitch, spx_word16_t *gain, int N, char *stack) 158 { 159 int i,j,k; 160 VARDECL(spx_word32_t *best_score); 161 VARDECL(spx_word32_t *best_ener); 162 spx_word32_t e0; 163 VARDECL(spx_word32_t *corr); 164 VARDECL(spx_word32_t *energy); 165 166 ALLOC(best_score, N, spx_word32_t); 167 ALLOC(best_ener, N, spx_word32_t); 168 ALLOC(corr, end-start+1, spx_word32_t); 169 ALLOC(energy, end-start+2, spx_word32_t); 170 171 for (i=0;i<N;i++) 172 { 173 best_score[i]=-1; 174 best_ener[i]=0; 175 pitch[i]=start; 176 } 177 178 energy[0]=inner_prod(sw-start, sw-start, len); 179 e0=inner_prod(sw, sw, len); 180 181 /* energy update -------------------------------------*/ 182 183 __asm__ __volatile__ 184 ( 185 " P0 = %0;\n\t" 186 " I1 = %1;\n\t" 187 " L1 = 0;\n\t" 188 " I2 = %2;\n\t" 189 " L2 = 0;\n\t" 190 " R2 = [P0++];\n\t" 191 " R3 = 0;\n\t" 192 " LSETUP (eu1, eu2) LC1 = %3;\n\t" 193 "eu1: R1.L = W [I1--] || R0.L = W [I2--] ;\n\t" 194 " R1 = R1.L * R1.L (IS);\n\t" 195 " R0 = R0.L * R0.L (IS);\n\t" 196 " R1 >>>= 6;\n\t" 197 " R1 = R1 + R2;\n\t" 198 " R0 >>>= 6;\n\t" 199 " R1 = R1 - R0;\n\t" 200 " R2 = MAX(R1,R3);\n\t" 201 "eu2: [P0++] = R2;\n\t" 202 : : "d" (energy), "d" (&sw[-start-1]), "d" (&sw[-start+len-1]), 203 "a" (end-start) 204 : "P0", "I1", "I2", "R0", "R1", "R2", "R3" 205 #if (__GNUC__ == 4) 206 , "LC1" 207 #endif 208 ); 209 210 pitch_xcorr(sw, sw-end, corr, len, end-start+1, stack); 211 212 /* FIXME: Fixed-point and floating-point code should be merged */ 213 { 214 VARDECL(spx_word16_t *corr16); 215 VARDECL(spx_word16_t *ener16); 216 ALLOC(corr16, end-start+1, spx_word16_t); 217 ALLOC(ener16, end-start+1, spx_word16_t); 218 /* Normalize to 180 so we can square it and it still fits in 16 bits */ 219 normalize16(corr, corr16, 180, end-start+1); 220 normalize16(energy, ener16, 180, end-start+1); 221 222 if (N == 1) { 223 /* optimised asm to handle N==1 case */ 224 __asm__ __volatile__ 225 ( 226 " I0 = %1;\n\t" /* I0: corr16[] */ 227 " L0 = 0;\n\t" 228 " I1 = %2;\n\t" /* I1: energy */ 229 " L1 = 0;\n\t" 230 " R2 = -1;\n\t" /* R2: best score */ 231 " R3 = 0;\n\t" /* R3: best energy */ 232 " P0 = %4;\n\t" /* P0: best pitch */ 233 " P1 = %4;\n\t" /* P1: counter */ 234 " LSETUP (sl1, sl2) LC1 = %3;\n\t" 235 "sl1: R0.L = W [I0++] || R1.L = W [I1++];\n\t" 236 " R0 = R0.L * R0.L (IS);\n\t" 237 " R1 += 1;\n\t" 238 " R4 = R0.L * R3.L;\n\t" 239 " R5 = R2.L * R1.L;\n\t" 240 " cc = R5 < R4;\n\t" 241 " if cc R2 = R0;\n\t" 242 " if cc R3 = R1;\n\t" 243 " if cc P0 = P1;\n\t" 244 "sl2: P1 += 1;\n\t" 245 " %0 = P0;\n\t" 246 : "=&d" (pitch[0]) 247 : "a" (corr16), "a" (ener16), "a" (end+1-start), "d" (start) 248 : "P0", "P1", "I0", "I1", "R0", "R1", "R2", "R3", "R4", "R5" 249 #if (__GNUC__ == 4) 250 , "LC1" 251 #endif 252 ); 253 254 } 255 else { 256 for (i=start;i<=end;i++) 257 { 258 spx_word16_t tmp = MULT16_16_16(corr16[i-start],corr16[i-start]); 259 /* Instead of dividing the tmp by the energy, we multiply on the other side */ 260 if (MULT16_16(tmp,best_ener[N-1])>MULT16_16(best_score[N-1],ADD16(1,ener16[i-start]))) 261 { 262 /* We can safely put it last and then check */ 263 best_score[N-1]=tmp; 264 best_ener[N-1]=ener16[i-start]+1; 265 pitch[N-1]=i; 266 /* Check if it comes in front of others */ 267 for (j=0;j<N-1;j++) 268 { 269 if (MULT16_16(tmp,best_ener[j])>MULT16_16(best_score[j],ADD16(1,ener16[i-start]))) 270 { 271 for (k=N-1;k>j;k--) 272 { 273 best_score[k]=best_score[k-1]; 274 best_ener[k]=best_ener[k-1]; 275 pitch[k]=pitch[k-1]; 276 } 277 best_score[j]=tmp; 278 best_ener[j]=ener16[i-start]+1; 279 pitch[j]=i; 280 break; 281 } 282 } 283 } 284 } 285 } 286 } 287 288 /* Compute open-loop gain */ 289 if (gain) 290 { 291 for (j=0;j<N;j++) 292 { 293 spx_word16_t g; 294 i=pitch[j]; 295 g = DIV32(corr[i-start], 10+SHR32(MULT16_16(spx_sqrt(e0),spx_sqrt(energy[i-start])),6)); 296 /* FIXME: g = max(g,corr/energy) */ 297 if (g<0) 298 g = 0; 299 gain[j]=g; 300 } 301 } 302 } 303 #endif 304 305 #define OVERRIDE_PITCH_GAIN_SEARCH_3TAP_VQ 306 #ifdef OVERRIDE_PITCH_GAIN_SEARCH_3TAP_VQ 307 static int pitch_gain_search_3tap_vq( 308 const signed char *gain_cdbk, 309 int gain_cdbk_size, 310 spx_word16_t *C16, 311 spx_word16_t max_gain 312 ) 313 { 314 const signed char *ptr=gain_cdbk; 315 int best_cdbk=0; 316 spx_word32_t best_sum=-VERY_LARGE32; 317 spx_word32_t sum=0; 318 spx_word16_t g[3]; 319 spx_word16_t pitch_control=64; 320 spx_word16_t gain_sum; 321 int i; 322 323 /* fast asm version of VQ codebook search */ 324 325 __asm__ __volatile__ 326 ( 327 328 " P0 = %2;\n\t" /* P0: ptr to gain_cdbk */ 329 " L1 = 0;\n\t" /* no circ addr for L1 */ 330 " %0 = 0;\n\t" /* %0: best_sum */ 331 " %1 = 0;\n\t" /* %1: best_cbdk */ 332 " P1 = 0;\n\t" /* P1: loop counter */ 333 " R5 = 64;\n\t" /* R5: pitch_control */ 334 335 " LSETUP (pgs1, pgs2) LC1 = %4;\n\t" 336 "pgs1: R2 = B [P0++] (X);\n\t" /* R2: g[0] */ 337 " R3 = B [P0++] (X);\n\t" /* R3: g[1] */ 338 " R4 = B [P0++] (X);\n\t" /* R4: g[2] */ 339 " R2 += 32;\n\t" 340 " R3 += 32;\n\t" 341 " R4 += 32;\n\t" 342 343 " R0 = B [P0++] (X);\n\t" 344 " B0 = R0;\n\t" /* BO: gain_sum */ 345 346 /* compute_pitch_error() -------------------------------*/ 347 348 " I1 = %3;\n\t" /* I1: ptr to C */ 349 " A0 = 0;\n\t" 350 351 " R0.L = W[I1++];\n\t" 352 " R1.L = R2.L*R5.L (IS);\n\t" 353 " A0 += R1.L*R0.L (IS) || R0.L = W[I1++];\n\t" 354 355 " R1.L = R3.L*R5.L (IS);\n\t" 356 " A0 += R1.L*R0.L (IS) || R0.L = W[I1++];\n\t" 357 358 " R1.L = R4.L*R5.L (IS);\n\t" 359 " A0 += R1.L*R0.L (IS) || R0.L = W[I1++];\n\t" 360 361 " R1.L = R2.L*R3.L (IS);\n\t" 362 " A0 -= R1.L*R0.L (IS) || R0.L = W[I1++];\n\t" 363 364 " R1.L = R4.L*R3.L (IS);\n\t" 365 " A0 -= R1.L*R0.L (IS) || R0.L = W[I1++];\n\t" 366 367 " R1.L = R4.L*R2.L (IS);\n\t" 368 " A0 -= R1.L*R0.L (IS) || R0.L = W[I1++];\n\t" 369 370 " R1.L = R2.L*R2.L (IS);\n\t" 371 " A0 -= R1.L*R0.L (IS) || R0.L = W[I1++];\n\t" 372 373 " R1.L = R3.L*R3.L (IS);\n\t" 374 " A0 -= R1.L*R0.L (IS) || R0.L = W[I1++];\n\t" 375 376 " R1.L = R4.L*R4.L (IS);\n\t" 377 " R0 = (A0 -= R1.L*R0.L) (IS);\n\t" 378 379 /* 380 Re-arrange the if-then to code efficiently on the Blackfin: 381 382 if (sum>best_sum && gain_sum<=max_gain) ------ (1) 383 384 if (sum>best_sum && !(gain_sum>max_gain)) ------ (2) 385 386 if (max_gain<=gain_sum) { ------ (3) 387 sum = -VERY_LARGE32; 388 } 389 if (best_sum<=sum) 390 391 The blackin cc instructions are all of the form: 392 393 cc = x < y (or cc = x <= y) 394 */ 395 " R1 = B0\n\t" 396 " R2 = %5\n\t" 397 " R3 = %6\n\t" 398 " cc = R2 <= R1;\n\t" 399 " if cc R0 = R3;\n\t" 400 " cc = %0 <= R0;\n\t" 401 " if cc %0 = R0;\n\t" 402 " if cc %1 = P1;\n\t" 403 404 "pgs2: P1 += 1;\n\t" 405 406 : "=&d" (best_sum), "=&d" (best_cdbk) 407 : "a" (gain_cdbk), "a" (C16), "a" (gain_cdbk_size), "a" (max_gain), 408 "b" (-VERY_LARGE32) 409 : "R0", "R1", "R2", "R3", "R4", "R5", "P0", 410 "P1", "I1", "L1", "A0", "B0" 411 #if (__GNUC__ == 4) 412 , "LC1" 413 #endif 414 ); 415 416 return best_cdbk; 417 } 418 #endif 419
Note: See TracChangeset
for help on using the changeset viewer.