getting close to non-totally garbage output
authorjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Wed, 17 Jan 2007 12:39:13 +0000 (12:39 +0000)
committerjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Wed, 17 Jan 2007 12:39:13 +0000 (12:39 +0000)
git-svn-id: http://svn.xiph.org/trunk/speex@12333 0101bb08-14d6-0310-b084-bc0e0c8e3800

libspeex/resample.c

index 1eb7261..276ebad 100644 (file)
@@ -31,7 +31,8 @@
 */
 
 #include "misc.h"
-      
+#include <math.h>
+            
 typedef struct {
    int in_rate;
    int out_rate;
@@ -44,7 +45,7 @@ typedef struct {
 } SpeexResamplerState;
 
 
-SpeexResamplerState *speex_resampler_init(int in_rate, int out_rate)
+SpeexResamplerState *speex_resampler_init(int in_rate, int out_rate, int in_rate_den, int out_rate_den)
 {
    SpeexResamplerState *st = (SpeexResamplerState *)speex_alloc(sizeof(SpeexResamplerState));
    int fact, i;
@@ -53,7 +54,7 @@ SpeexResamplerState *speex_resampler_init(int in_rate, int out_rate)
    st->num_rate = in_rate;
    st->den_rate = out_rate;
    /* FIXME: This is terribly inefficient, but who cares (at least for now)? */
-   for (fact=2;fact<=spx_sqrt(MAX32(in_rate, out_rate));fact++)
+   for (fact=2;fact<=sqrt(MAX32(in_rate, out_rate));fact++)
    {
       while ((st->num_rate % fact == 0) && (st->den_rate % fact == 0))
       {
@@ -69,12 +70,21 @@ SpeexResamplerState *speex_resampler_init(int in_rate, int out_rate)
    return st;
 }
 
-void speex_resampler_init(SpeexResamplerState *st)
+void speex_resampler_destroy(SpeexResamplerState *st)
 {
    speex_free(st->mem);
    speex_free(st);
 }
 
+static float sinc(float x, int N)
+{
+   if (fabs(x)<1e-6)
+      return 1;
+   else if (fabs(x) > .5f*N)
+      return 0;
+   return sin(M_PI*x)/(M_PI*x) * (.5-.5*cos(2*x*M_PI/N));
+}
+
 int speex_resample_float(SpeexResamplerState *st, const float *in, int len, float *out)
 {
    int i=0;
@@ -85,7 +95,10 @@ int speex_resample_float(SpeexResamplerState *st, const float *in, int len, floa
       float sum=0;
       for (j=0;j<N;j++)
       {
-         sum += in[st->last_sample-N+1+j]*sinc((j-N/2)-((float)st->samp_frac_num)/st->den_rate);
+         if (st->last_sample-N+1+j < 0)
+            sum += st->mem[st->last_sample+j]*sinc((j-N/2)-((float)st->samp_frac_num)/st->den_rate, N);
+         else
+            sum += in[st->last_sample-N+1+j]*sinc((j-N/2)-((float)st->samp_frac_num)/st->den_rate, N);
       }
       out[i++] = sum;
       
@@ -101,6 +114,35 @@ int speex_resample_float(SpeexResamplerState *st, const float *in, int len, floa
          break;
       }      
    }
+   for (i=0;i<st->filt_len-1;i++)
+      st->mem[i] = in[i+len-N+1];
    return i;
 }
 
+#include <stdio.h>
+#define NN 256
+
+int main(int argc, char **argv)
+{
+   int i;
+   SpeexResamplerState *st = speex_resampler_init(8000, 16000, 1, 1);
+   while (1)
+   {
+      int out_num;
+      short in[NN];
+      short out[2*NN];
+      float fin[NN], fout[2*NN];
+      fread(in, sizeof(short), NN, stdin);
+      if (feof(stdin))
+         break;
+      for (i=0;i<NN;i++)
+         fin[i]=in[i];
+      out_num = speex_resample_float(st, fin, NN, fout);
+      fprintf (stderr, "%d\n", out_num);
+      for (i=0;i<2*NN;i++)
+         out[i]=fout[i];
+      fwrite(in, sizeof(short), 2*NN, stdout);
+   }
+   return 0;
+}
+