More changes merged from single channel case, renamed back to speex_*
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 05:24:16 +0000 (15:24 +1000)
Merge commit '37657c2b0b228b26ebecf31e36c69327489e66f1' into stereo

Conflicts:

include/speex/speex_echo.h
libspeex/mdf.c
libspeex/testecho.c

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

@@@ -48,32 -51,59 +51,59 @@@ extern "C" 
  /** Get sampling rate */
  #define SPEEX_ECHO_GET_SAMPLING_RATE 25
  
- /*struct drft_lookup;*/
+ /** Internal echo canceller state. Should never be accessed directly. */
  struct SpeexEchoState_;
  
+ /** @class SpeexEchoState
+  * This holds the state of the echo canceller. You need one per channel. 
+ */
+ /** Internal echo canceller state. Should never be accessed directly. */
  typedef struct SpeexEchoState_ SpeexEchoState;
  
- /** Creates a new echo canceller state */
- SpeexEchoState *mc_echo_state_init(int frame_size, int filter_length, int nb_mic, int nb_speakers);
+ /** Creates a new echo canceller state
+  * @param frame_size Number of samples to process at one time (should correspond to 10-20 ms)
+  * @param filter_length Number of samples of echo to cancel (should generally correspond to 100-500 ms)
+  * @return Newly-created echo canceller state
+  */
 -SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length);
++SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length, int nb_mic, int nb_speakers);
  
- /** Destroys an echo canceller state */
- void mc_echo_state_destroy(SpeexEchoState *st);
+ /** Destroys an echo canceller state 
+  * @param st Echo canceller state
+ */
+ void speex_echo_state_destroy(SpeexEchoState *st);
  
- /** Performs echo cancellation a frame */
- void mc_echo_cancellation(SpeexEchoState *st, const spx_int16_t *rec, const spx_int16_t *play, spx_int16_t *out);
+ /** Performs echo cancellation a frame, based on the audio sent to the speaker (no delay is added
+  * to playback in this form)
+  *
+  * @param st Echo canceller state
+  * @param rec Signal from the microphone (near end + far end echo)
+  * @param play Signal played to the speaker (received from far end)
+  * @param out Returns near-end signal with echo removed
+  */
+ void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *rec, const spx_int16_t *play, spx_int16_t *out);
  
- /** Performs echo cancellation a frame */
- void mc_echo_cancel(SpeexEchoState *st, const spx_int16_t *rec, const spx_int16_t *play, spx_int16_t *out, spx_int32_t *Yout);
+ /** Performs echo cancellation a frame (deprecated) */
+ void speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *rec, const spx_int16_t *play, spx_int16_t *out, spx_int32_t *Yout);
  
- /** Perform echo cancellation using internal playback buffer */
- void mc_echo_capture(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out);
+ /** Perform echo cancellation using internal playback buffer, which is delayed by two frames
+  * to account for the delay introduced by most soundcards (but it could be off!)
+  * @param st Echo canceller state
+  * @param rec Signal from the microphone (near end + far end echo)
+  * @param out Returns near-end signal with echo removed
+ */
+ void speex_echo_capture(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out);
  
- /** Let the echo canceller know that a frame was just played */
- void mc_echo_playback(SpeexEchoState *st, const spx_int16_t *play);
+ /** Let the echo canceller know that a frame was just queued to the soundcard
+  * @param st Echo canceller state
+  * @param play Signal played to the speaker (received from far end)
+ */
+ void speex_echo_playback(SpeexEchoState *st, const spx_int16_t *play);
  
- /** Reset the echo canceller state */
- void mc_echo_state_reset(SpeexEchoState *st);
+ /** Reset the echo canceller to its original state 
+  * @param st Echo canceller state
+  */
+ void speex_echo_state_reset(SpeexEchoState *st);
  
  /** Used like the ioctl function to control the echo canceller parameters
   *
diff --cc libspeex/mdf.c
@@@ -395,21 -378,17 +393,21 @@@ static void dump_audio(const spx_int16_
  #endif
  
  /** Creates a new echo canceller state */
- SpeexEchoState *mc_echo_state_init(int frame_size, int filter_length, int nb_mic, int nb_speakers)
 -SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length)
++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_error("Opening dump files twice");
-    rFile = fopen("aec_rec.sw", "w");
-    pFile = fopen("aec_play.sw", "w");
-    oFile = fopen("aec_out.sw", "w");
+       speex_fatal("Opening dump files twice");
+    rFile = fopen("aec_rec.sw", "wb");
+    pFile = fopen("aec_play.sw", "wb");
+    oFile = fopen("aec_out.sw", "wb");
  #endif
     
     st->frame_size = frame_size;
        }
        for (i=M-1;i>=0;i--)
        {
-          st->prop[i] = DIV32(MULT16_16(QCONST16(.99f,15), st->prop[i]),sum);
 -         st->prop[i] = DIV32(MULT16_16(QCONST16(.8,15), st->prop[i]),sum);
++         st->prop[i] = DIV32(MULT16_16(QCONST16(.8f,15), st->prop[i]),sum);
        }
     }
     
@@@ -669,17 -636,17 +666,17 @@@ void speex_echo_playback(SpeexEchoStat
     }
  }
  
- /** Performs echo cancellation on a frame */
- void mc_echo_cancel(SpeexEchoState *st, const spx_int16_t *in, const spx_int16_t *far_end, spx_int16_t *out, spx_int32_t *Yout)
+ /** Performs echo cancellation on a frame (deprecated, last arg now ignored) */
+ void speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *in, const spx_int16_t *far_end, spx_int16_t *out, spx_int32_t *Yout)
  {
-    mc_echo_cancellation(st, in, far_end, out);
+    speex_echo_cancellation(st, in, far_end, out);
  }
  
- /** Performs echo cancellation on a frame (deprecated, last arg now ignored) */
- void mc_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, const spx_int16_t *far_end, spx_int16_t *out)
+ /** 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)
  {
 -   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;
@@@ -24,30 -24,30 +24,30 @@@ int main(int argc, char **argv
  
     if (argc != 4)
     {
-       fprintf (stderr, "testecho mic_signal.sw speaker_signal.sw output.sw\n");
+       fprintf(stderr, "testecho mic_signal.sw speaker_signal.sw output.sw\n");
        exit(1);
     }
-    echo_fd = open (argv[2], O_RDONLY);
-    ref_fd  = open (argv[1],  O_RDONLY);
-    e_fd    = open (argv[3], O_WRONLY | O_CREAT | O_TRUNC, 0644);
+    echo_fd = fopen(argv[2], "rb");
+    ref_fd  = fopen(argv[1],  "rb");
+    e_fd    = fopen(argv[3], "wb");
  
-    st = mc_echo_state_init(NN, TAIL, 1, 1);
-    den = speex_preprocess_state_init(NN, 8000);
-    int tmp = 8000;
-    mc_echo_ctl(st, SPEEX_ECHO_SET_SAMPLING_RATE, &tmp);
 -   st = speex_echo_state_init(NN, TAIL);
++   st = speex_echo_state_init(NN, TAIL, 1, 1);
+    den = speex_preprocess_state_init(NN, sampleRate);
+    speex_echo_ctl(st, SPEEX_ECHO_SET_SAMPLING_RATE, &sampleRate);
     speex_preprocess_ctl(den, SPEEX_PREPROCESS_SET_ECHO_STATE, st);
  
-    while (read(ref_fd, ref_buf, NN*2))
+    while (!feof(ref_fd) && !feof(echo_fd))
     {
-       read(echo_fd, echo_buf, NN*2);
-       mc_echo_cancellation(st, ref_buf, echo_buf, e_buf);
+       fread(ref_buf, sizeof(short), NN, ref_fd);
+       fread(echo_buf, sizeof(short), NN, echo_fd);
+       speex_echo_cancellation(st, ref_buf, echo_buf, e_buf);
        speex_preprocess_run(den, e_buf);
-       write(e_fd, e_buf, NN*2);
+       fwrite(e_buf, sizeof(short), NN, e_fd);
     }
-    mc_echo_state_destroy(st);
+    speex_echo_state_destroy(st);
     speex_preprocess_state_destroy(den);
-    close(e_fd);
-    close(echo_fd);
-    close(ref_fd);
+    fclose(e_fd);
+    fclose(echo_fd);
+    fclose(ref_fd);
     return 0;
  }