Index: libspeex/resample.c
===================================================================
--- libspeex/resample.c	(revision 14654)
+++ libspeex/resample.c	(working copy)
@@ -74,6 +74,7 @@
 #include "os_support.h"
 #endif /* OUTSIDE_SPEEX */
 
+#include "stack_alloc.h"
 #include <math.h>
 
 #ifndef M_PI
@@ -317,47 +318,37 @@
 
 static int resampler_basic_direct_single(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len)
 {
-   int N = st->filt_len;
+   const int N = st->filt_len;
    int out_sample = 0;
-   spx_word16_t *mem;
    int last_sample = st->last_sample[channel_index];
    spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];
-   mem = st->mem + channel_index * st->mem_alloc_size;
+   const spx_word16_t *sinc_table = st->sinc_table;
+   const int out_stride = st->out_stride;
+   const int int_advance = st->int_advance;
+   const int frac_advance = st->frac_advance;
+   const spx_uint32_t den_rate = st->den_rate;
+   int j;
+   spx_word32_t sum;
+
    while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))
    {
-      int j;
-      spx_word32_t sum=0;
-      
-      /* We already have all the filter coefficients pre-computed in the table */
-      const spx_word16_t *ptr;
-      /* Do the memory part */
-      for (j=0;last_sample-N+1+j < 0;j++)
-      {
-         sum += MULT16_16(mem[last_sample+j],st->sinc_table[samp_frac_num*st->filt_len+j]);
+      const spx_word16_t *sinc = & sinc_table[samp_frac_num*N];
+      const spx_word16_t *iptr = & in[last_sample];
+      sum=0;
+      for(j=0;j<N;j++) {
+        sum += MULT16_16(sinc[j], iptr[j]);
       }
       
-      /* Do the new part */
-      if (in != NULL)
+      out[out_sample++] = PSHR32(sum,15);
+      last_sample += int_advance;
+      samp_frac_num += frac_advance;
+      if (samp_frac_num >= den_rate)
       {
-         ptr = in+st->in_stride*(last_sample-N+1+j);
-         for (;j<N;j++)
-         {
-            sum += MULT16_16(*ptr,st->sinc_table[samp_frac_num*st->filt_len+j]);
-            ptr += st->in_stride;
-         }
-      }
-      
-      *out = PSHR32(sum,15);
-      out += st->out_stride;
-      out_sample++;
-      last_sample += st->int_advance;
-      samp_frac_num += st->frac_advance;
-      if (samp_frac_num >= st->den_rate)
-      {
-         samp_frac_num -= st->den_rate;
+         samp_frac_num -= den_rate;
          last_sample++;
       }
    }
+
    st->last_sample[channel_index] = last_sample;
    st->samp_frac_num[channel_index] = samp_frac_num;
    return out_sample;
@@ -417,69 +408,56 @@
 
 static int resampler_basic_interpolate_single(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len)
 {
-   int N = st->filt_len;
+   const int N = st->filt_len;
    int out_sample = 0;
-   spx_word16_t *mem;
    int last_sample = st->last_sample[channel_index];
    spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];
-   mem = st->mem + channel_index * st->mem_alloc_size;
+   const spx_word16_t *sinc_table = st->sinc_table;
+   const int out_stride = st->out_stride;
+   const int int_advance = st->int_advance;
+   const int frac_advance = st->frac_advance;
+   const spx_uint32_t den_rate = st->den_rate;
+   int j;
+   spx_word32_t accum[4];
+   spx_word16_t interp[4];
+   int offset;
+   spx_word16_t frac;
+   spx_word32_t sum;
+
    while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))
    {
-      int j;
-      spx_word32_t sum=0;
-      
-      /* We need to interpolate the sinc filter */
-      spx_word32_t accum[4] = {0.f,0.f, 0.f, 0.f};
-      spx_word16_t interp[4];
-      const spx_word16_t *ptr;
-      int offset;
-      spx_word16_t frac;
+      const spx_word16_t *sinc = & sinc_table[samp_frac_num*N];
+      const spx_word16_t *iptr = & in[last_sample];
+      accum[0]=accum[1]=accum[2]=accum[3]=0;
+
       offset = samp_frac_num*st->oversample/st->den_rate;
 #ifdef FIXED_POINT
       frac = PDIV32(SHL32((samp_frac_num*st->oversample) % st->den_rate,15),st->den_rate);
 #else
       frac = ((float)((samp_frac_num*st->oversample) % st->den_rate))/st->den_rate;
 #endif
-         /* This code is written like this to make it easy to optimise with SIMD.
-      For most DSPs, it would be best to split the loops in two because most DSPs 
-      have only two accumulators */
-      for (j=0;last_sample-N+1+j < 0;j++)
-      {
-         spx_word16_t curr_mem = mem[last_sample+j];
-         accum[0] += MULT16_16(curr_mem,st->sinc_table[4+(j+1)*st->oversample-offset-2]);
-         accum[1] += MULT16_16(curr_mem,st->sinc_table[4+(j+1)*st->oversample-offset-1]);
-         accum[2] += MULT16_16(curr_mem,st->sinc_table[4+(j+1)*st->oversample-offset]);
-         accum[3] += MULT16_16(curr_mem,st->sinc_table[4+(j+1)*st->oversample-offset+1]);
+
+      for(j=0;j<N;j++) {
+        const spx_word16_t curr_in=iptr[j];
+        accum[0] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-2]);
+        accum[1] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-1]);
+        accum[2] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset]);
+        accum[3] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset+1]);
       }
-      
-      if (in != NULL)
-      {
-         ptr = in+st->in_stride*(last_sample-N+1+j);
-         /* Do the new part */
-         for (;j<N;j++)
-         {
-            spx_word16_t curr_in = *ptr;
-            ptr += st->in_stride;
-            accum[0] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-2]);
-            accum[1] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-1]);
-            accum[2] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset]);
-            accum[3] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset+1]);
-         }
-      }
+
       cubic_coef(frac, interp);
       sum = MULT16_32_Q15(interp[0],accum[0]) + MULT16_32_Q15(interp[1],accum[1]) + MULT16_32_Q15(interp[2],accum[2]) + MULT16_32_Q15(interp[3],accum[3]);
-   
-      *out = PSHR32(sum,15);
-      out += st->out_stride;
-      out_sample++;
-      last_sample += st->int_advance;
-      samp_frac_num += st->frac_advance;
-      if (samp_frac_num >= st->den_rate)
+      
+      out[out_sample++] = PSHR32(sum,15);
+      last_sample += int_advance;
+      samp_frac_num += frac_advance;
+      if (samp_frac_num >= den_rate)
       {
-         samp_frac_num -= st->den_rate;
+         samp_frac_num -= den_rate;
          last_sample++;
       }
    }
+
    st->last_sample[channel_index] = last_sample;
    st->samp_frac_num[channel_index] = samp_frac_num;
    return out_sample;
@@ -789,9 +767,11 @@
    speex_free(st);
 }
 
+/*
+ * Here 'in' should already be deinterleaved and have st->filt_len empty elements before the data.
+ */
 
-
-static int speex_resampler_process_native(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len)
+static int speex_resampler_process_native(SpeexResamplerState *st, spx_uint32_t channel_index, spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len)
 {
    int j=0;
    int N = st->filt_len;
@@ -829,6 +809,10 @@
       out += tmp_out_len*st->out_stride;
       *out_len -= tmp_out_len;
    }
+
+   /* Prepend the memory */
+   for(j=0;j<st->filt_len-1;j++)
+     in[j] = mem[j];
    
    /* Call the right resampler through the function ptr */
    out_sample = st->resampler_ptr(st, channel_index, in, in_len, out, out_len);
@@ -837,17 +821,10 @@
       *in_len = st->last_sample[channel_index];
    *out_len = out_sample+tmp_out_len;
    st->last_sample[channel_index] -= *in_len;
-   
-   for (j=0;j<N-1-(spx_int32_t)*in_len;j++)
-      mem[j] = mem[j+*in_len];
-   if (in != NULL)
-   {
-      for (;j<N-1;j++)
-         mem[j] = in[st->in_stride*(j+*in_len-N+1)];
-   } else {
-      for (;j<N-1;j++)
-         mem[j] = 0;      
-   }
+
+   for(j=0;j<N;++j)
+     mem[j] = in[j+*in_len];
+
    return RESAMPLER_ERR_SUCCESS;
 }
 
@@ -927,7 +904,16 @@
 #else
 int speex_resampler_process_float(SpeexResamplerState *st, spx_uint32_t channel_index, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len)
 {
-   return speex_resampler_process_native(st, channel_index, in, in_len, out, out_len);
+   int j;
+   ALLOC(buffer, st->filt_len + *in_len, spx_word16_t);
+   if (in)
+     for(j=0;j<*in_len;++j)
+       buffer[j+st->filt_len-1]=in[j*st->in_stride + channel_index];
+   else
+     for(j=0;j<*in_len;++j)
+       buffer[j+st->filt_len-1]=0.0f;
+
+   return speex_resampler_process_native(st, channel_index, buffer, in_len, out, out_len);
 }
 int speex_resampler_process_int(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len)
 {
