fixed-point: conversion of the open-loop pitch analysis
authorjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Wed, 8 Oct 2003 04:53:18 +0000 (04:53 +0000)
committerjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Wed, 8 Oct 2003 04:53:18 +0000 (04:53 +0000)
git-svn-id: http://svn.xiph.org/trunk/speex@5430 0101bb08-14d6-0310-b084-bc0e0c8e3800

libspeex/filters.c
libspeex/ltp.c
libspeex/smallft.c

index 28b9f1c..e6348cf 100644 (file)
@@ -60,13 +60,13 @@ spx_word16_t compute_rms(spx_sig_t *x, int len)
    {
       spx_sig_t tmp = x[i];
       if (tmp<0)
    {
       spx_sig_t tmp = x[i];
       if (tmp<0)
-         tmp = -1;
+         tmp = -tmp;
       if (tmp > max_val)
          max_val = tmp;
    }
 
    sig_shift=0;
       if (tmp > max_val)
          max_val = tmp;
    }
 
    sig_shift=0;
-   while (max_val>2048)
+   while (max_val>16383)
    {
       sig_shift++;
       max_val >>= 1;
    {
       sig_shift++;
       max_val >>= 1;
@@ -84,11 +84,11 @@ spx_word16_t compute_rms(spx_sig_t *x, int len)
       sum2 += MULT16_16(tmp,tmp);
       tmp = SHR(x[i+3],sig_shift);
       sum2 += MULT16_16(tmp,tmp);
       sum2 += MULT16_16(tmp,tmp);
       tmp = SHR(x[i+3],sig_shift);
       sum2 += MULT16_16(tmp,tmp);
-      sum += sum2;
+      sum += SHR(sum2,6);
    }
    
    /*FIXME: remove division*/
    }
    
    /*FIXME: remove division*/
-   return (1<<sig_shift)*sqrt(1+sum/len)/SIG_SCALING;
+   return (1<<(sig_shift+3))*sqrt(1+sum/len)/SIG_SCALING;
 }
 
 #define MUL_16_32_R15(a,bh,bl) ((a)*(bh) + ((a)*(bl)>>15))
 }
 
 #define MUL_16_32_R15(a,bh,bl) ((a)*(bh) + ((a)*(bl)>>15))
index 6b53048..951c74a 100644 (file)
 
 #include <stdio.h>
 
 
 #include <stdio.h>
 
+#ifdef FIXED_POINT
+
+static spx_word32_t inner_prod2(spx_word16_t *x, spx_word16_t *y, int len)
+{
+   int i;
+   spx_word32_t sum=0;
+   for (i=0;i<len;i+=4)
+   {
+      spx_word32_t part=0;
+      part += MULT16_16(x[i],y[i]);
+      part += MULT16_16(x[i+1],y[i+1]);
+      part += MULT16_16(x[i+2],y[i+2]);
+      part += MULT16_16(x[i+3],y[i+3]);
+      sum += SHR(part,6);
+   }
+   return sum;
+}
+
+
+static float inner_prod(spx_sig_t *x, spx_sig_t *y, int len)
+{
+   int i;
+   float sum1=0,sum2=0,sum3=0,sum4=0;
+   for (i=0;i<len;)
+   {
+      sum1 += x[i]*y[i];
+      sum2 += x[i+1]*y[i+1];
+      sum3 += x[i+2]*y[i+2];
+      sum4 += x[i+3]*y[i+3];
+      i+=4;
+   }
+   return sum1+sum2+sum3+sum4;
+}
+
+void open_loop_nbest_pitch(spx_sig_t *sw, int start, int end, int len, int *pitch, float *gain, int N, char *stack)
+{
+   int i,j,k;
+   /*float corr=0;*/
+   /*float energy;*/
+   float *best_score;
+   float e0;
+   spx_word32_t *corr, *energy;
+   float *score;
+
+   spx_word16_t *swn;
+   spx_sig_t max_sw=1;
+   int sw_shift=0;
+
+   best_score = PUSH(stack,N, float);
+   corr = PUSH(stack,end-start+1, spx_word32_t);
+   energy = PUSH(stack,end-start+2, spx_word32_t);
+   score = PUSH(stack,end-start+1, float);
+
+   swn = PUSH(stack, end+len, spx_word16_t);
+   for (i=-end;i<len;i++)
+   {
+      spx_sig_t tmp = sw[i];
+      if (tmp<0)
+         tmp = -tmp;
+      if (tmp > max_sw)
+         max_sw = tmp;
+   }
+   while (max_sw>16384)
+   {
+      sw_shift++;
+      max_sw>>=1;
+   }
+   for (i=0;i<end+len;i++)
+      swn[i] = SHR(sw[i-end],sw_shift);
+   
+   swn += end;
+
+
+   for (i=0;i<N;i++)
+   {
+        best_score[i]=-1;
+        gain[i]=0;
+   }
+
+
+   energy[0]=inner_prod2(swn-start, swn-start, len);
+   e0=inner_prod2(swn, swn, len);
+   for (i=start;i<=end;i++)
+   {
+      /* Update energy for next pitch*/
+      energy[i-start+1] = energy[i-start] + SHR(MULT16_16(swn[-i-1],swn[-i-1]) - MULT16_16(swn[-i+len-1],swn[-i+len-1]),6);
+   }
+   for (i=start;i<=end;i++)
+   {
+      corr[i-start]=0;
+      score[i-start]=0;
+   }
+
+   for (i=start;i<=end;i++)
+   {
+      /* Compute correlation*/
+      corr[i-start]=inner_prod2(swn, swn-i, len);
+      score[i-start]=1.*corr[i-start]*corr[i-start]/(energy[i-start]+1.);
+   }
+   for (i=start;i<=end;i++)
+   {
+      if (score[i-start]>best_score[N-1])
+      {
+         float g1, g;
+         g1 = corr[i-start]/(energy[i-start]+10.);
+         g = sqrt(g1*corr[i-start]/(e0+10.));
+         if (g>g1)
+            g=g1;
+         if (g<0)
+            g=0;
+         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];
+                  gain[k] = gain[k-1];
+               }
+               best_score[j]=score[i-start];
+               pitch[j]=i;
+               gain[j]=g;
+               break;
+            }
+         }
+      }
+   }
+
+}
+
+#else
+
+
 #ifdef _USE_SSE
 #include "ltp_sse.h"
 #else
 #ifdef _USE_SSE
 #include "ltp_sse.h"
 #else
@@ -137,7 +271,7 @@ void open_loop_nbest_pitch(spx_sig_t *sw, int start, int end, int len, int *pitc
    }
 
 }
    }
 
 }
-
+#endif
 
 
 
 
 
 
index de37eaf..4c43cc5 100644 (file)
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: *unnormalized* fft transform
  ********************************************************************
 
  function: *unnormalized* fft transform
- last mod: $Id: smallft.c,v 1.10 2003/10/08 04:52:27 jm Exp $
+ last mod: $Id: smallft.c,v 1.11 2003/10/08 04:53:18 jm Exp $
 
  ********************************************************************/
 
 
  ********************************************************************/