17
17
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
#include "mediastreamer2/msfilter.h"
20
#include "mediastreamer2/msspeexec.h"
22
22
#include <speex/speex_echo.h>
23
23
#include <speex/speex_preprocess.h>
58
60
ms_bufferizer_init(&s->speak_delay);
60
63
s->playback_delay=0;
64
s->tail_length_ms=250;
62
66
ms_bufferizer_init(&s->in[0]);
63
67
ms_bufferizer_init(&s->in[1]);
64
s->ecstate=speex_echo_state_init(s->framesize,s->filterlength);
65
s->den = speex_preprocess_state_init(s->framesize, s->samplerate);
66
speex_echo_ctl(s->ecstate, SPEEX_ECHO_SET_SAMPLING_RATE, &s->samplerate);
67
speex_preprocess_ctl(s->den, SPEEX_PREPROCESS_SET_ECHO_STATE, s->ecstate);
74
76
ms_bufferizer_uninit(&s->speak_delay);
75
77
ms_bufferizer_uninit(&s->in[0]);
76
78
ms_bufferizer_uninit(&s->in[1]);
77
speex_echo_state_destroy(s->ecstate);
80
speex_echo_state_destroy(s->ecstate);
79
speex_preprocess_state_destroy(s->den);
82
speex_preprocess_state_destroy(s->den);
88
static void speex_ec_preprocess(MSFilter *f){
89
SpeexECState *s=(SpeexECState*)f->data;
91
speex_echo_state_destroy(s->ecstate);
93
speex_preprocess_state_destroy(s->den);
95
if (s->tail_length_ms!=0)
96
s->filterlength=(s->tail_length_ms*s->samplerate)/1000;
98
s->playback_delay=s->delay_ms*s->samplerate/1000;
99
ms_message("Initializing speex echo canceler with framesize=%i, filterlength=%i, playback_delay=%i",
100
s->framesize,s->filterlength,s->playback_delay);
101
s->ecstate=speex_echo_state_init(s->framesize,s->filterlength);
102
s->den = speex_preprocess_state_init(s->framesize, s->samplerate);
103
speex_echo_ctl(s->ecstate, SPEEX_ECHO_SET_SAMPLING_RATE, &s->samplerate);
104
speex_preprocess_ctl(s->den, SPEEX_PREPROCESS_SET_ECHO_STATE, s->ecstate);
84
107
/* inputs[0]= reference signal (sent to soundcard)
85
108
inputs[1]= echo signal (read from soundcard)
100
123
if (s->size_delay<s->playback_delay){
101
while((m=ms_queue_get(f->inputs[0]))!=NULL
102
&& s->size_delay<s->playback_delay){
124
while((m=ms_queue_get(f->inputs[0]))!=NULL && s->size_delay<s->playback_delay){
103
125
// Duplicate queue : one to write to the output speaker, the other will be delayed for AEC
104
126
int size=msgdsize(m);
106
s->size_delay = s->size_delay + size;
128
s->size_delay = s->size_delay + size;
107
129
ms_bufferizer_put(&s->speak_delay,md);
108
ms_bufferizer_put(&s->in[0],m);
130
ms_bufferizer_put(&s->in[0],m);
111
if (s->size_delay<s->playback_delay)
133
if (s->size_delay<=s->playback_delay)
113
135
/* make sure we always send block with same size */
114
136
while (ms_bufferizer_get_avail(&s->speak_delay)>=nbytes)
126
148
om0=allocb(nbytes,0);
127
149
ms_bufferizer_read(&s->in[1],(uint8_t*)om0->b_wptr,nbytes);
128
150
om0->b_wptr+=nbytes;
129
ms_queue_put(f->outputs[1],om0);
151
ms_queue_put(f->outputs[1],om0);
131
153
/* we are now equal and speaker is delayed */
136
158
ms_bufferizer_put_from_queue(&s->in[1],f->inputs[1]);
187
209
if (ms_bufferizer_get_avail(&s->speak_delay)> 5*320*(s->samplerate/8000)) /* above 4*20ms -> useless */
189
/* reset evrything */
190
ms_warning("speexec: -reset of echo canceller- in0=%i, in1=%i",ms_bufferizer_get_avail(&s->in[0]),ms_bufferizer_get_avail(&s->in[1]));
191
flushq(&s->in[1].q,0);
192
flushq(&s->in[0].q,0);
193
flushq(&s->speak_delay.q,0);
194
ms_bufferizer_init(&s->in[0]);
195
ms_bufferizer_init(&s->in[1]);
196
ms_bufferizer_init(&s->speak_delay);
198
speex_echo_state_reset(s->ecstate);
211
/* reset evrything */
212
ms_warning("speexec: -reset of echo canceller- in0=%i, in1=%i",ms_bufferizer_get_avail(&s->in[0]),ms_bufferizer_get_avail(&s->in[1]));
213
flushq(&s->in[1].q,0);
214
flushq(&s->in[0].q,0);
215
flushq(&s->speak_delay.q,0);
216
ms_bufferizer_init(&s->in[0]);
217
ms_bufferizer_init(&s->in[1]);
218
ms_bufferizer_init(&s->speak_delay);
220
speex_echo_state_reset(s->ecstate);
201
223
while (ms_bufferizer_get_avail(&s->in[1])> 5*320*(s->samplerate/8000)){
202
224
om1=allocb(nbytes,0);
212
234
static void speex_ec_postprocess(MSFilter *f){
213
235
SpeexECState *s=(SpeexECState*)f->data;
214
flushq(&s->in[1].q,0);
215
flushq(&s->in[0].q,0);
216
flushq(&s->speak_delay.q,0);
236
ms_bufferizer_uninit(&s->in[0]);
237
ms_bufferizer_uninit(&s->in[1]);
238
ms_bufferizer_uninit(&s->speak_delay);
217
239
ms_bufferizer_init(&s->in[0]);
218
240
ms_bufferizer_init(&s->in[1]);
219
241
ms_bufferizer_init(&s->speak_delay);
222
if (s->ecstate!=NULL)
244
if (s->ecstate!=NULL){
223
245
speex_echo_state_destroy(s->ecstate);
225
speex_preprocess_state_destroy(s->den);
227
s->ecstate=speex_echo_state_init(s->framesize,s->filterlength*(s->samplerate/8000));
228
s->den = speex_preprocess_state_init(s->framesize, s->samplerate);
229
speex_echo_ctl(s->ecstate, SPEEX_ECHO_SET_SAMPLING_RATE, &s->samplerate);
230
speex_preprocess_ctl(s->den, SPEEX_PREPROCESS_SET_ECHO_STATE, s->ecstate);
249
speex_preprocess_state_destroy(s->den);
233
254
static int speex_ec_set_sr(MSFilter *f, void *arg){
236
257
s->samplerate = *(int*)arg;
238
if (s->ecstate!=NULL)
259
if (s->ecstate!=NULL){
239
260
speex_echo_state_destroy(s->ecstate);
241
speex_preprocess_state_destroy(s->den);
243
s->ecstate=speex_echo_state_init(s->framesize,s->filterlength*(s->samplerate/8000));
244
s->den = speex_preprocess_state_init(s->framesize, s->samplerate);
245
speex_echo_ctl(s->ecstate, SPEEX_ECHO_SET_SAMPLING_RATE, &s->samplerate);
246
speex_preprocess_ctl(s->den, SPEEX_PREPROCESS_SET_ECHO_STATE, s->ecstate);
262
speex_preprocess_state_destroy(s->den);
264
s->ecstate=speex_echo_state_init(s->framesize,s->filterlength);
265
s->den = speex_preprocess_state_init(s->framesize, s->samplerate);
266
speex_echo_ctl(s->ecstate, SPEEX_ECHO_SET_SAMPLING_RATE, &s->samplerate);
267
speex_preprocess_ctl(s->den, SPEEX_PREPROCESS_SET_ECHO_STATE, s->ecstate);
251
273
SpeexECState *s=(SpeexECState*)f->data;
252
274
s->framesize = *(int*)arg;
254
if (s->ecstate!=NULL)
276
if (s->ecstate!=NULL){
255
277
speex_echo_state_destroy(s->ecstate);
257
speex_preprocess_state_destroy(s->den);
259
s->ecstate=speex_echo_state_init(s->framesize,s->filterlength*(s->samplerate/8000));
260
s->den = speex_preprocess_state_init(s->framesize, s->samplerate);
261
speex_echo_ctl(s->ecstate, SPEEX_ECHO_SET_SAMPLING_RATE, &s->samplerate);
262
speex_preprocess_ctl(s->den, SPEEX_PREPROCESS_SET_ECHO_STATE, s->ecstate);
279
speex_preprocess_state_destroy(s->den);
281
s->ecstate=speex_echo_state_init(s->framesize,s->filterlength);
282
s->den = speex_preprocess_state_init(s->framesize, s->samplerate);
283
speex_echo_ctl(s->ecstate, SPEEX_ECHO_SET_SAMPLING_RATE, &s->samplerate);
284
speex_preprocess_ctl(s->den, SPEEX_PREPROCESS_SET_ECHO_STATE, s->ecstate);
266
289
static int speex_ec_set_filterlength(MSFilter *f, void *arg){
267
290
SpeexECState *s=(SpeexECState*)f->data;
268
s->filterlength = *(int*)arg;
291
s->filterlength = (*(int*)arg)*(s->samplerate/8000);
292
s->tail_length_ms=0;/*trust the length in sample, not the length in milliseconds*/
270
293
if (s->ecstate!=NULL)
271
294
speex_echo_state_destroy(s->ecstate);
272
295
if (s->den!=NULL)
273
296
speex_preprocess_state_destroy(s->den);
275
s->ecstate=speex_echo_state_init(s->framesize,s->filterlength*(s->samplerate/8000));
298
s->ecstate=speex_echo_state_init(s->framesize,s->filterlength);
276
299
s->den = speex_preprocess_state_init(s->framesize, s->samplerate);
277
300
speex_echo_ctl(s->ecstate, SPEEX_ECHO_SET_SAMPLING_RATE, &s->samplerate);
278
301
speex_preprocess_ctl(s->den, SPEEX_PREPROCESS_SET_ECHO_STATE, s->ecstate);
305
static int speex_ec_set_delay2(MSFilter *f, void *arg){
306
SpeexECState *s=(SpeexECState*)f->data;
307
s->delay_ms = *(int*)arg;
311
static int speex_ec_set_tail_length2(MSFilter *f, void *arg){
312
SpeexECState *s=(SpeexECState*)f->data;
313
s->tail_length_ms=*(int*)arg;
282
317
static int speex_ec_set_playbackdelay(MSFilter *f, void *arg){
283
318
SpeexECState *s=(SpeexECState*)f->data;
284
319
s->playback_delay = *(int*)arg;
297
332
static MSFilterMethod speex_ec_methods[]={
298
333
{ MS_FILTER_SET_SAMPLE_RATE, speex_ec_set_sr },
334
{ MS_SPEEX_EC_SET_TAIL_LENGTH , speex_ec_set_tail_length2 },
335
{ MS_SPEEX_EC_SET_DELAY , speex_ec_set_delay2 },
336
{ MS_SPEEX_EC_SET_FRAME_SIZE , speex_ec_set_framesize },
337
/*these are kept for backward compatibility */
299
338
{ MS_FILTER_SET_FRAMESIZE, speex_ec_set_framesize },
300
339
{ MS_FILTER_SET_FILTERLENGTH, speex_ec_set_filterlength },
301
{ MS_FILTER_SET_PLAYBACKDELAY, speex_ec_set_playbackdelay },
340
{ MS_FILTER_SET_PLAYBACKDELAY, speex_ec_set_playbackdelay },