Ignore:
Timestamp:
Jul 26, 2006 5:04:54 PM (18 years ago)
Author:
bennylp
Message:
  • Bring speex codec up to date with their SVN trunk
  • Speex codec should work in FIXED_POINT mode when PJ_HAS_FLOATING_POINT is set to zero.
  • ulaw2linear will return zero if zero is given (this would make the VAD works better, and it also fixed click noise when call is established/hangup).
File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia-codec/speex/ltp_bfin.h

    r278 r628  
    3535 
    3636#define OVERRIDE_INNER_PROD 
    37 static spx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len) 
     37spx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len) 
    3838{ 
    3939   spx_word32_t sum=0; 
     
    6464 
    6565#define OVERRIDE_PITCH_XCORR 
    66 static void pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack) 
     66void pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack) 
    6767{ 
    6868   corr += nb_pitch - 1; 
     
    110110 
    111111#define OVERRIDE_COMPUTE_PITCH_ERROR 
    112 static inline spx_word32_t compute_pitch_error(spx_word32_t *C, spx_word16_t *g, spx_word16_t pitch_control) 
     112static inline spx_word32_t compute_pitch_error(spx_word16_t *C, spx_word16_t *g, spx_word16_t pitch_control) 
    113113{ 
    114114   spx_word32_t sum; 
    115115   __asm__ __volatile__ 
    116116         ( 
    117          "A1 = A0 = 0;\n\t" 
    118           
    119          "R0 = [%1++];\n\t" 
     117         "A0 = 0;\n\t" 
     118          
     119         "R0 = W[%1++];\n\t" 
    120120         "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" 
    123122          
    124123         "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" 
    127125          
    128126         "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" 
    131128          
    132129         "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" 
    135131 
    136132         "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" 
    139134          
    140135         "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" 
    143137          
    144138         "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" 
    147140 
    148141         "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" 
    151143          
    152144         "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          
    158147         "%0 = A0;\n\t" 
    159148   : "=&D" (sum), "=a" (C) 
     
    164153} 
    165154 
     155#define OVERRIDE_OPEN_LOOP_NBEST_PITCH 
     156#ifdef OVERRIDE_OPEN_LOOP_NBEST_PITCH 
     157void 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 
     307static 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.