diff options
Diffstat (limited to 'apps/codecs/libspeex/mdf.c')
-rw-r--r-- | apps/codecs/libspeex/mdf.c | 57 |
1 files changed, 46 insertions, 11 deletions
diff --git a/apps/codecs/libspeex/mdf.c b/apps/codecs/libspeex/mdf.c index d67c36d6dc..2fe3bd08fd 100644 --- a/apps/codecs/libspeex/mdf.c +++ b/apps/codecs/libspeex/mdf.c | |||
@@ -41,8 +41,8 @@ | |||
41 | double-talk is achieved using a variable learning rate as described in: | 41 | double-talk is achieved using a variable learning rate as described in: |
42 | 42 | ||
43 | Valin, J.-M., On Adjusting the Learning Rate in Frequency Domain Echo | 43 | Valin, J.-M., On Adjusting the Learning Rate in Frequency Domain Echo |
44 | Cancellation With Double-Talk. To appear in IEEE Transactions on Audio, | 44 | Cancellation With Double-Talk. IEEE Transactions on Audio, |
45 | Speech and Language Processing, 2006. | 45 | Speech and Language Processing, Vol. 15, No. 3, pp. 1030-1034, 2007. |
46 | http://people.xiph.org/~jm/papers/valin_taslp2006.pdf | 46 | http://people.xiph.org/~jm/papers/valin_taslp2006.pdf |
47 | 47 | ||
48 | There is no explicit double-talk detection, but a continuous variation | 48 | There is no explicit double-talk detection, but a continuous variation |
@@ -360,12 +360,36 @@ static inline void mdf_adjust_prop(const spx_word32_t *W, int N, int M, spx_word | |||
360 | /*printf ("\n");*/ | 360 | /*printf ("\n");*/ |
361 | } | 361 | } |
362 | 362 | ||
363 | #ifdef DUMP_ECHO_CANCEL_DATA | ||
364 | #include <stdio.h> | ||
365 | static FILE *rFile=NULL, *pFile=NULL, *oFile=NULL; | ||
366 | |||
367 | static void dump_audio(const spx_int16_t *rec, const spx_int16_t *play, const spx_int16_t *out, int len) | ||
368 | { | ||
369 | if (!(rFile && pFile && oFile)) | ||
370 | { | ||
371 | speex_error("Dump files not open"); | ||
372 | } | ||
373 | fwrite(rec, sizeof(spx_int16_t), len, rFile); | ||
374 | fwrite(play, sizeof(spx_int16_t), len, pFile); | ||
375 | fwrite(out, sizeof(spx_int16_t), len, oFile); | ||
376 | } | ||
377 | #endif | ||
378 | |||
363 | /** Creates a new echo canceller state */ | 379 | /** Creates a new echo canceller state */ |
364 | SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length) | 380 | SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length) |
365 | { | 381 | { |
366 | int i,N,M; | 382 | int i,N,M; |
367 | SpeexEchoState *st = (SpeexEchoState *)speex_alloc(sizeof(SpeexEchoState)); | 383 | SpeexEchoState *st = (SpeexEchoState *)speex_alloc(sizeof(SpeexEchoState)); |
368 | 384 | ||
385 | #ifdef DUMP_ECHO_CANCEL_DATA | ||
386 | if (rFile || pFile || oFile) | ||
387 | speex_error("Opening dump files twice"); | ||
388 | rFile = fopen("aec_rec.sw", "w"); | ||
389 | pFile = fopen("aec_play.sw", "w"); | ||
390 | oFile = fopen("aec_out.sw", "w"); | ||
391 | #endif | ||
392 | |||
369 | st->frame_size = frame_size; | 393 | st->frame_size = frame_size; |
370 | st->window_size = 2*frame_size; | 394 | st->window_size = 2*frame_size; |
371 | N = st->window_size; | 395 | N = st->window_size; |
@@ -553,6 +577,13 @@ void speex_echo_state_destroy(SpeexEchoState *st) | |||
553 | #endif | 577 | #endif |
554 | speex_free(st->play_buf); | 578 | speex_free(st->play_buf); |
555 | speex_free(st); | 579 | speex_free(st); |
580 | |||
581 | #ifdef DUMP_ECHO_CANCEL_DATA | ||
582 | fclose(rFile); | ||
583 | fclose(pFile); | ||
584 | fclose(oFile); | ||
585 | rFile = pFile = oFile = NULL; | ||
586 | #endif | ||
556 | } | 587 | } |
557 | 588 | ||
558 | void speex_echo_capture(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out) | 589 | void speex_echo_capture(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out) |
@@ -701,8 +732,8 @@ void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, const sp | |||
701 | spectral_mul_accum16(st->X, st->foreground, st->Y, N, M); | 732 | spectral_mul_accum16(st->X, st->foreground, st->Y, N, M); |
702 | spx_ifft(st->fft_table, st->Y, st->e); | 733 | spx_ifft(st->fft_table, st->Y, st->e); |
703 | for (i=0;i<st->frame_size;i++) | 734 | for (i=0;i<st->frame_size;i++) |
704 | st->x[i+st->frame_size] = SUB16(st->input[i], st->e[i+st->frame_size]); | 735 | st->e[i] = SUB16(st->input[i], st->e[i+st->frame_size]); |
705 | Sff = mdf_inner_prod(st->x+st->frame_size, st->x+st->frame_size, st->frame_size); | 736 | Sff = mdf_inner_prod(st->e, st->e, st->frame_size); |
706 | #endif | 737 | #endif |
707 | 738 | ||
708 | /* Adjust proportional adaption rate */ | 739 | /* Adjust proportional adaption rate */ |
@@ -762,13 +793,13 @@ void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, const sp | |||
762 | #ifdef TWO_PATH | 793 | #ifdef TWO_PATH |
763 | /* Difference in response, this is used to estimate the variance of our residual power estimate */ | 794 | /* Difference in response, this is used to estimate the variance of our residual power estimate */ |
764 | for (i=0;i<st->frame_size;i++) | 795 | for (i=0;i<st->frame_size;i++) |
765 | st->x[i+st->frame_size] = SUB16(st->e[i+st->frame_size], st->y[i+st->frame_size]); | 796 | st->e[i] = SUB16(st->e[i+st->frame_size], st->y[i+st->frame_size]); |
766 | Dbf = 10+mdf_inner_prod(st->x+st->frame_size, st->x+st->frame_size, st->frame_size); | 797 | Dbf = 10+mdf_inner_prod(st->e, st->e, st->frame_size); |
767 | #endif | 798 | #endif |
768 | 799 | ||
769 | for (i=0;i<st->frame_size;i++) | 800 | for (i=0;i<st->frame_size;i++) |
770 | st->x[i+st->frame_size] = SUB16(st->input[i], st->y[i+st->frame_size]); | 801 | st->e[i] = SUB16(st->input[i], st->y[i+st->frame_size]); |
771 | See = mdf_inner_prod(st->x+st->frame_size, st->x+st->frame_size, st->frame_size); | 802 | See = mdf_inner_prod(st->e, st->e, st->frame_size); |
772 | #ifndef TWO_PATH | 803 | #ifndef TWO_PATH |
773 | Sff = See; | 804 | Sff = See; |
774 | #endif | 805 | #endif |
@@ -828,7 +859,7 @@ void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, const sp | |||
828 | for (i=0;i<st->frame_size;i++) | 859 | for (i=0;i<st->frame_size;i++) |
829 | st->y[i+st->frame_size] = st->e[i+st->frame_size]; | 860 | st->y[i+st->frame_size] = st->e[i+st->frame_size]; |
830 | for (i=0;i<st->frame_size;i++) | 861 | for (i=0;i<st->frame_size;i++) |
831 | st->x[i+st->frame_size] = SUB16(st->input[i], st->y[i+st->frame_size]); | 862 | st->e[i] = SUB16(st->input[i], st->y[i+st->frame_size]); |
832 | See = Sff; | 863 | See = Sff; |
833 | st->Davg1 = st->Davg2 = 0; | 864 | st->Davg1 = st->Davg2 = 0; |
834 | st->Dvar1 = st->Dvar2 = FLOAT_ZERO; | 865 | st->Dvar1 = st->Dvar2 = FLOAT_ZERO; |
@@ -861,12 +892,16 @@ void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, const sp | |||
861 | out[i] = (spx_int16_t)tmp_out; | 892 | out[i] = (spx_int16_t)tmp_out; |
862 | st->memE = tmp_out; | 893 | st->memE = tmp_out; |
863 | } | 894 | } |
864 | 895 | ||
896 | #ifdef DUMP_ECHO_CANCEL_DATA | ||
897 | dump_audio(in, far_end, out, st->frame_size); | ||
898 | #endif | ||
899 | |||
865 | /* Compute error signal (filter update version) */ | 900 | /* Compute error signal (filter update version) */ |
866 | for (i=0;i<st->frame_size;i++) | 901 | for (i=0;i<st->frame_size;i++) |
867 | { | 902 | { |
903 | st->e[i+st->frame_size] = st->e[i]; | ||
868 | st->e[i] = 0; | 904 | st->e[i] = 0; |
869 | st->e[i+st->frame_size] = st->x[i+st->frame_size]; | ||
870 | } | 905 | } |
871 | 906 | ||
872 | /* Compute a bunch of correlations */ | 907 | /* Compute a bunch of correlations */ |