Merge branch 'master' into stereo
authorJean-Marc Valin <Jean-Marc.Valin@csiro.au>
Mon, 26 Nov 2007 03:47:00 +0000 (14:47 +1100)
committerJean-Marc Valin <Jean-Marc.Valin@csiro.au>
Mon, 19 May 2008 06:14:15 +0000 (16:14 +1000)
Conflicts:

libspeex/mdf.c

1  2 
include/speex/speex_echo.h
libspeex/mdf.c

Simple merge
diff --cc libspeex/mdf.c
@@@ -393,15 -384,11 +399,15 @@@ static void dump_audio(const spx_int16_
  #endif
  
  /** Creates a new echo canceller state */
- SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length, int nb_mic, int nb_speakers)
 -EXPORT SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length)
++EXPORT SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length, int nb_mic, int nb_speakers)
  {
 -   int i,N,M;
 +   int i,N,M, C, K;
     SpeexEchoState *st = (SpeexEchoState *)speex_alloc(sizeof(SpeexEchoState));
  
 +   st->K = nb_speakers;
 +   st->C = nb_mic;
 +   C=st->C;
 +   K=st->K;
  #ifdef DUMP_ECHO_CANCEL_DATA
     if (rFile || pFile || oFile)
        speex_fatal("Opening dump files twice");
  }
  
  /** Resets echo canceller state */
- void speex_echo_state_reset(SpeexEchoState *st)
EXPORT void speex_echo_state_reset(SpeexEchoState *st)
  {
 -   int i, M, N;
 +   int i, M, N, C, K;
     st->cancel_count=0;
     st->screwed_up = 0;
     N = st->window_size;
@@@ -673,10 -649,10 +679,10 @@@ EXPORT void speex_echo_cancel(SpeexEcho
  }
  
  /** Performs echo cancellation on a frame */
- void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, const spx_int16_t *far_end, spx_int16_t *out)
EXPORT void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, const spx_int16_t *far_end, spx_int16_t *out)
  {
 -   int i,j;
 -   int N,M;
 +   int i,j, chan, speak;
 +   int N,M, C, K;
     spx_word32_t Syy,See,Sxx,Sdd, Sff;
  #ifdef TWO_PATH
     spx_word32_t Dbf;
     }
  #endif
  
 -   /* Compute error signal (for the output with de-emphasis) */ 
 -   for (i=0;i<st->frame_size;i++)
 -   {
 -      spx_word32_t tmp_out;
 +   Sey = Syy = Sdd = 0;  
 +   for (chan = 0; chan < C; chan++)
 +   {    
 +      /* Compute error signal (for the output with de-emphasis) */ 
 +      for (i=0;i<st->frame_size;i++)
 +      {
 +         spx_word32_t tmp_out;
  #ifdef TWO_PATH
 -      tmp_out = SUB32(EXTEND32(st->input[i]), EXTEND32(st->e[i+st->frame_size]));
 +         tmp_out = SUB32(EXTEND32(st->input[chan*st->frame_size+i]), EXTEND32(st->e[chan*N+i+st->frame_size]));
  #else
 -      tmp_out = SUB32(EXTEND32(st->input[i]), EXTEND32(st->y[i+st->frame_size]));
 +         tmp_out = SUB32(EXTEND32(st->input[chan*st->frame_size+i]), EXTEND32(st->y[chan*N+i+st->frame_size]));
  #endif
-          /* Saturation */
-          if (tmp_out>32767)
-             tmp_out = 32767;
-          else if (tmp_out<-32768)
-             tmp_out = -32768;
 -      tmp_out = ADD32(tmp_out, EXTEND32(MULT16_16_P15(st->preemph, st->memE)));
 +         tmp_out = ADD32(tmp_out, EXTEND32(MULT16_16_P15(st->preemph, st->memE[chan])));
        /* This is an arbitrary test for saturation in the microphone signal */
 -      if (in[i] <= -32000 || in[i] >= 32000)
 -      {
 +         if (in[i*C+chan] <= -32000 || in[i*C+chan] >= 32000)
 +         {
-             tmp_out = 0;
           if (st->saturated == 0)
              st->saturated = 1;
-          out[i*C+chan] = (spx_int16_t)tmp_out;
 +         }
++         out[i*C+chan] = WORD2INT(tmp_out);
 +         st->memE[chan] = tmp_out;
        }
 -      out[i] = WORD2INT(tmp_out);
 -      st->memE = tmp_out;
 -   }
 -   
 +
  #ifdef DUMP_ECHO_CANCEL_DATA
 -   dump_audio(in, far_end, out, st->frame_size);
 +      dump_audio(in, far_end, out, st->frame_size);
  #endif
     
 -   /* Compute error signal (filter update version) */ 
 -   for (i=0;i<st->frame_size;i++)
 -   {
 -      st->e[i+st->frame_size] = st->e[i];
 -      st->e[i] = 0;
 +      /* Compute error signal (filter update version) */ 
 +      for (i=0;i<st->frame_size;i++)
 +      {
 +         st->e[chan*N+i+st->frame_size] = st->e[chan*N+i];
 +         st->e[chan*N+i] = 0;
 +      }
 +      
 +      /* Compute a bunch of correlations */
 +      /* FIXME: bad merge */
 +      Sey += mdf_inner_prod(st->e+chan*N+st->frame_size, st->y+chan*N+st->frame_size, st->frame_size);
 +      Syy += mdf_inner_prod(st->y+chan*N+st->frame_size, st->y+chan*N+st->frame_size, st->frame_size);
 +      Sdd += mdf_inner_prod(st->input+chan*st->frame_size, st->input+chan*st->frame_size, st->frame_size);
 +      
 +      /* Convert error to frequency domain */
 +      spx_fft(st->fft_table, st->e+chan*N, st->E+chan*N);
 +      for (i=0;i<st->frame_size;i++)
 +         st->y[i+chan*N] = 0;
 +      spx_fft(st->fft_table, st->y+chan*N, st->Y+chan*N);
 +   
 +      /* Compute power spectrum of echo (X), error (E) and filter response (Y) */
 +      power_spectrum_accum(st->E+chan*N, st->Rf, N);
 +      power_spectrum_accum(st->Y+chan*N, st->Yf, N);
 +    
     }
 -
 -   /* Compute a bunch of correlations */
 -   Sey = mdf_inner_prod(st->e+st->frame_size, st->y+st->frame_size, st->frame_size);
 -   Syy = mdf_inner_prod(st->y+st->frame_size, st->y+st->frame_size, st->frame_size);
 -   Sdd = mdf_inner_prod(st->input, st->input, st->frame_size);
     
     /*printf ("%f %f %f %f\n", Sff, See, Syy, Sdd, st->update_cond);*/
     
@@@ -1244,6 -1169,27 +1244,29 @@@ EXPORT int speex_echo_ctl(SpeexEchoStat
        case SPEEX_ECHO_GET_SAMPLING_RATE:
           (*(int*)ptr) = st->sampling_rate;
           break;
+       case SPEEX_ECHO_GET_IMPULSE_RESPONSE_SIZE:
++         /*FIXME: Implement this for multiple channels */
+          *((spx_int32_t *)ptr) = st->M * st->frame_size;
+          break;
+       case SPEEX_ECHO_GET_IMPULSE_RESPONSE:
+       {
+          int M = st->M, N = st->window_size, n = st->frame_size, i, j;
+          spx_int32_t *filt = (spx_int32_t *) ptr;
+          for(j=0;j<M;j++)
+          {
++            /*FIXME: Implement this for multiple channels */
+ #ifdef FIXED_POINT
+             for (i=0;i<N;i++)
+                st->wtmp2[i] = EXTRACT16(PSHR32(st->W[j*N+i],16+NORMALIZE_SCALEDOWN));
+             spx_ifft(st->fft_table, st->wtmp2, st->wtmp);
+ #else
+             spx_ifft(st->fft_table, &st->W[j*N], st->wtmp);
+ #endif
+             for(i=0;i<n;i++)
+                filt[j*n+i] = PSHR32(MULT16_16(32767,st->wtmp[i]), WEIGHT_SHIFT-NORMALIZE_SCALEDOWN);
+          }
+       }
+          break;
        default:
           speex_warning_int("Unknown speex_echo_ctl request: ", request);
           return -1;