Esempio n. 1
0
File: ltp.c Progetto: Affix/fgcom
void open_loop_nbest_pitch(spx_sig_t *sw, int start, int end, int len, int *pitch, spx_word16_t *gain, int N, char *stack)
{
    int i,j,k;
    VARDECL(spx_word32_t *best_score);
    spx_word32_t e0;
    VARDECL(spx_word32_t *corr);
    VARDECL(spx_word32_t *energy);
    VARDECL(spx_word32_t *score);
#ifdef FIXED_POINT
    VARDECL(spx_word16_t *swn2);
#endif
    spx_word16_t *swn;

    ALLOC(best_score, N, spx_word32_t);
    ALLOC(corr, end-start+1, spx_word32_t);
    ALLOC(energy, end-start+2, spx_word32_t);
    ALLOC(score, end-start+1, spx_word32_t);

#ifdef FIXED_POINT
    ALLOC(swn2, end+len, spx_word16_t);
    normalize16(sw-end, swn2, 16384, end+len);
    swn = swn2 + end;
#else
    swn = sw;
#endif

    for (i=0; i<N; i++)
    {
        best_score[i]=-1;
        pitch[i]=start;
    }


    energy[0]=inner_prod(swn-start, swn-start, len);
    e0=inner_prod(swn, swn, len);
    for (i=start; i<=end; i++)
    {
        /* Update energy for next pitch*/
        energy[i-start+1] = SUB32(ADD32(energy[i-start],SHR32(MULT16_16(swn[-i-1],swn[-i-1]),6)), SHR32(MULT16_16(swn[-i+len-1],swn[-i+len-1]),6));
    }

    pitch_xcorr(swn, swn-end, corr, len, end-start+1, stack);

#ifdef FIXED_POINT
    {
        VARDECL(spx_word16_t *corr16);
        VARDECL(spx_word16_t *ener16);
        ALLOC(corr16, end-start+1, spx_word16_t);
        ALLOC(ener16, end-start+1, spx_word16_t);
        normalize16(corr, corr16, 16384, end-start+1);
        normalize16(energy, ener16, 16384, end-start+1);

        for (i=start; i<=end; i++)
        {
            spx_word16_t g;
            spx_word32_t tmp;
            tmp = corr16[i-start];
            if (tmp>0)
            {
                if (SHR16(corr16[i-start],4)>ener16[i-start])
                    tmp = SHL32(EXTEND32(ener16[i-start]),14);
                else if (-SHR16(corr16[i-start],4)>ener16[i-start])
                    tmp = -SHL32(EXTEND32(ener16[i-start]),14);
                else
                    tmp = SHL32(tmp,10);
                g = DIV32_16(tmp, 8+ener16[i-start]);
                score[i-start] = MULT16_16(corr16[i-start],g);
            } else
            {
                score[i-start] = 1;
            }
        }
    }
#else
    for (i=start; i<=end; i++)
    {
        float g = corr[i-start]/(1+energy[i-start]);
        if (g>16)
            g = 16;
        else if (g<-16)
            g = -16;
        score[i-start] = g*corr[i-start];
    }
#endif

    /* Extract best scores */
    for (i=start; i<=end; i++)
    {
        if (score[i-start]>best_score[N-1])
        {
            for (j=0; j<N; j++)
            {
                if (score[i-start] > best_score[j])
                {
                    for (k=N-1; k>j; k--)
                    {
                        best_score[k]=best_score[k-1];
                        pitch[k]=pitch[k-1];
                    }
                    best_score[j]=score[i-start];
                    pitch[j]=i;
                    break;
                }
            }
        }
    }

    /* Compute open-loop gain */
    if (gain)
    {
        for (j=0; j<N; j++)
        {
            spx_word16_t g;
            i=pitch[j];
            g = DIV32(corr[i-start], 10+SHR32(MULT16_16(spx_sqrt(e0),spx_sqrt(energy[i-start])),6));
            /* FIXME: g = max(g,corr/energy) */
            if (g<0)
                g = 0;
            gain[j]=g;
        }
    }
}
Esempio n. 2
0
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) {
    int i, j, k;
    VARDECL(spx_word32_t * best_score);
    VARDECL(spx_word32_t * best_ener);
    spx_word32_t e0;
    VARDECL(spx_word32_t * corr);
#ifdef FIXED_POINT
    /* In fixed-point, we need only one (temporary) array of 32-bit values and two (corr16, ener16)
       arrays for (normalized) 16-bit values */
    VARDECL(spx_word16_t * corr16);
    VARDECL(spx_word16_t * ener16);
    spx_word32_t* energy;
    int cshift = 0, eshift = 0;
    int scaledown = 0;
    ALLOC(corr16, end - start + 1, spx_word16_t);
    ALLOC(ener16, end - start + 1, spx_word16_t);
    ALLOC(corr, end - start + 1, spx_word32_t);
    energy = corr;
#else
    /* In floating-point, we need to float arrays and no normalized copies */
    VARDECL(spx_word32_t * energy);
    spx_word16_t* corr16;
    spx_word16_t* ener16;
    ALLOC(energy, end - start + 2, spx_word32_t);
    ALLOC(corr, end - start + 1, spx_word32_t);
    corr16 = corr;
    ener16 = energy;
#endif

    ALLOC(best_score, N, spx_word32_t);
    ALLOC(best_ener, N, spx_word32_t);
    for (i = 0; i < N; i++) {
        best_score[i] = -1;
        best_ener[i] = 0;
        pitch[i] = start;
    }

#ifdef FIXED_POINT
    for (i = -end; i < len; i++) {
        if (ABS16(sw[i]) > 16383) {
            scaledown = 1;
            break;
        }
    }
    /* If the weighted input is close to saturation, then we scale it down */
    if (scaledown) {
        for (i = -end; i < len; i++) {
            sw[i] = SHR16(sw[i], 1);
        }
    }
#endif
    energy[0] = inner_prod(sw - start, sw - start, len);
    e0 = inner_prod(sw, sw, len);
    for (i = start; i < end; i++) {
        /* Update energy for next pitch*/
        energy[i - start + 1] = SUB32(ADD32(energy[i - start], SHR32(MULT16_16(sw[-i - 1], sw[-i - 1]), 6)), SHR32(MULT16_16(sw[-i + len - 1], sw[-i + len - 1]), 6));
        if (energy[i - start + 1] < 0)
            energy[i - start + 1] = 0;
    }

#ifdef FIXED_POINT
    eshift = normalize16(energy, ener16, 32766, end - start + 1);
#endif

    /* In fixed-point, this actually overrites the energy array (aliased to corr) */
    pitch_xcorr(sw, sw - end, corr, len, end - start + 1, stack);

#ifdef FIXED_POINT
    /* Normalize to 180 so we can square it and it still fits in 16 bits */
    cshift = normalize16(corr, corr16, 180, end - start + 1);
    /* If we scaled weighted input down, we need to scale it up again (OK, so we've just lost the LSB, who cares?) */
    if (scaledown) {
        for (i = -end; i < len; i++) {
            sw[i] = SHL16(sw[i], 1);
        }
    }
#endif

    /* Search for the best pitch prediction gain */
    for (i = start; i <= end; i++) {
        spx_word16_t tmp = MULT16_16_16(corr16[i - start], corr16[i - start]);
        /* Instead of dividing the tmp by the energy, we multiply on the other side */
        if (MULT16_16(tmp, best_ener[N - 1]) > MULT16_16(best_score[N - 1], ADD16(1, ener16[i - start]))) {
            /* We can safely put it last and then check */
            best_score[N - 1] = tmp;
            best_ener[N - 1] = ener16[i - start] + 1;
            pitch[N - 1] = i;
            /* Check if it comes in front of others */
            for (j = 0; j < N - 1; j++) {
                if (MULT16_16(tmp, best_ener[j]) > MULT16_16(best_score[j], ADD16(1, ener16[i - start]))) {
                    for (k = N - 1; k > j; k--) {
                        best_score[k] = best_score[k - 1];
                        best_ener[k] = best_ener[k - 1];
                        pitch[k] = pitch[k - 1];
                    }
                    best_score[j] = tmp;
                    best_ener[j] = ener16[i - start] + 1;
                    pitch[j] = i;
                    break;
                }
            }
        }
    }

    /* Compute open-loop gain if necessary */
    if (gain) {
        for (j = 0; j < N; j++) {
            spx_word16_t g;
            i = pitch[j];
            g = DIV32(SHL32(EXTEND32(corr16[i - start]), cshift), 10 + SHR32(MULT16_16(spx_sqrt(e0), spx_sqrt(SHL32(EXTEND32(ener16[i - start]), eshift))), 6));
            /* FIXME: g = max(g,corr/energy) */
            if (g < 0)
                g = 0;
            gain[j] = g;
        }
    }


}
Esempio n. 3
0
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)
{
   int i,j,k;
   VARDECL(spx_word32_t *best_score);
   VARDECL(spx_word32_t *best_ener);
   spx_word32_t e0;
   VARDECL(spx_word32_t *corr);
   VARDECL(spx_word32_t *energy);

   ALLOC(best_score, N, spx_word32_t);
   ALLOC(best_ener, N, spx_word32_t);
   ALLOC(corr, end-start+1, spx_word32_t);
   ALLOC(energy, end-start+2, spx_word32_t);

   for (i=0;i<N;i++)
   {
        best_score[i]=-1;
        best_ener[i]=0;
        pitch[i]=start;
   }

   energy[0]=inner_prod(sw-start, sw-start, len);
   e0=inner_prod(sw, sw, len);
   for (i=start;i<end;i++)
   {
      /* Update energy for next pitch*/
      energy[i-start+1] = SUB32(ADD32(energy[i-start],SHR32(MULT16_16(sw[-i-1],sw[-i-1]),6)), SHR32(MULT16_16(sw[-i+len-1],sw[-i+len-1]),6));
      if (energy[i-start+1] < 0)
         energy[i-start+1] = 0;
   }

   pitch_xcorr(sw, sw-end, corr, len, end-start+1, stack);

   /* FIXME: Fixed-point and floating-point code should be merged */
#ifdef FIXED_POINT
   {
      VARDECL(spx_word16_t *corr16);
      VARDECL(spx_word16_t *ener16);
      ALLOC(corr16, end-start+1, spx_word16_t);
      ALLOC(ener16, end-start+1, spx_word16_t);
      /* Normalize to 180 so we can square it and it still fits in 16 bits */
      normalize16(corr, corr16, 180, end-start+1);
      normalize16(energy, ener16, 180, end-start+1);

      for (i=start;i<=end;i++)
      {
         spx_word16_t tmp = MULT16_16_16(corr16[i-start],corr16[i-start]);
         /* Instead of dividing the tmp by the energy, we multiply on the other side */
         if (MULT16_16(tmp,best_ener[N-1])>MULT16_16(best_score[N-1],ADD16(1,ener16[i-start])))
         {
            /* We can safely put it last and then check */
            best_score[N-1]=tmp;
            best_ener[N-1]=ener16[i-start]+1;
            pitch[N-1]=i;
            /* Check if it comes in front of others */
            for (j=0;j<N-1;j++)
            {
               if (MULT16_16(tmp,best_ener[j])>MULT16_16(best_score[j],ADD16(1,ener16[i-start])))
               {
                  for (k=N-1;k>j;k--)
                  {
                     best_score[k]=best_score[k-1];
                     best_ener[k]=best_ener[k-1];
                     pitch[k]=pitch[k-1];
                  }
                  best_score[j]=tmp;
                  best_ener[j]=ener16[i-start]+1;
                  pitch[j]=i;
                  break;
               }
            }
         }
      }
   }
#else
   for (i=start;i<=end;i++)
   {
      float tmp = corr[i-start]*corr[i-start];
      if (tmp*best_ener[N-1]>best_score[N-1]*(1+energy[i-start]))
      {
         for (j=0;j<N;j++)
         {
            if (tmp*best_ener[j]>best_score[j]*(1+energy[i-start]))
            {
               for (k=N-1;k>j;k--)
               {
                  best_score[k]=best_score[k-1];
                  best_ener[k]=best_ener[k-1];
                  pitch[k]=pitch[k-1];
               }
               best_score[j]=tmp;
               best_ener[j]=energy[i-start]+1;
               pitch[j]=i;
               break;
            }
         }
      }
   }
#endif

   /* Compute open-loop gain */
   if (gain)
   {
       for (j=0;j<N;j++)
       {
          spx_word16_t g;
          i=pitch[j];
          g = DIV32(corr[i-start], 10+SHR32(MULT16_16(spx_sqrt(e0),spx_sqrt(energy[i-start])),6));
          /* FIXME: g = max(g,corr/energy) */
                   if (g<0)
                   g = 0;
             gain[j]=g;
       }
   }
}