~ubuntu-branches/ubuntu/vivid/linphone/vivid

« back to all changes in this revision

Viewing changes to mediastreamer2/src/speexec.c

  • Committer: Bazaar Package Importer
  • Author(s): Mark Purcell
  • Date: 2009-10-14 08:26:02 UTC
  • mfrom: (1.3.1 upstream) (6.1.1 sid)
  • Revision ID: james.westby@ubuntu.com-20091014082602-751618nxdjooja3l
Tags: 3.2.1-1
New upstream release 

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
18
*/
19
19
 
20
 
#include "mediastreamer2/msfilter.h"
 
20
#include "mediastreamer2/msspeexec.h"
21
21
 
22
22
#include <speex/speex_echo.h>
23
23
#include <speex/speex_preprocess.h>
46
46
        int ref;
47
47
        int echo;
48
48
        int out;
 
49
        int delay_ms;
 
50
        int tail_length_ms;
49
51
}SpeexECState;
50
52
 
51
53
static void speex_ec_init(MSFilter *f){
57
59
 
58
60
        ms_bufferizer_init(&s->speak_delay);
59
61
        s->size_delay=0;
 
62
        s->delay_ms=0;
60
63
        s->playback_delay=0;
 
64
        s->tail_length_ms=250;
61
65
 
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);
 
68
        s->ecstate=NULL;
 
69
        s->den = NULL;
68
70
 
69
71
        f->data=s;
70
72
}
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);
 
79
        if (s->ecstate!=NULL)
 
80
                speex_echo_state_destroy(s->ecstate);
78
81
        if (s->den!=NULL)
79
 
          speex_preprocess_state_destroy(s->den);
 
82
                speex_preprocess_state_destroy(s->den);
80
83
 
81
84
        ms_free(s);
82
85
}
83
86
 
 
87
 
 
88
static void speex_ec_preprocess(MSFilter *f){
 
89
        SpeexECState *s=(SpeexECState*)f->data;
 
90
        if (s->ecstate!=NULL)
 
91
                speex_echo_state_destroy(s->ecstate);
 
92
        if (s->den!=NULL)
 
93
                speex_preprocess_state_destroy(s->den);
 
94
 
 
95
        if (s->tail_length_ms!=0)
 
96
                s->filterlength=(s->tail_length_ms*s->samplerate)/1000;
 
97
        if (s->delay_ms!=0)
 
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);
 
105
}
 
106
 
84
107
/*      inputs[0]= reference signal (sent to soundcard)
85
108
        inputs[1]= echo signal  (read from soundcard)
86
109
*/
98
121
        mblk_t *md;     
99
122
 
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);
105
 
                md = copyb(m);
106
 
                s->size_delay = s->size_delay + size;
 
127
                        md = copyb(m);
 
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);
109
131
                }
110
132
 
111
 
                if (s->size_delay<s->playback_delay)
 
133
                if (s->size_delay<=s->playback_delay)
112
134
                {
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);
130
152
                        }
131
153
                        /* we are now equal and speaker is delayed */
132
154
                        return;
133
155
                }
134
 
    }
 
156
        }
135
157
 
136
158
        ms_bufferizer_put_from_queue(&s->in[1],f->inputs[1]);
137
159
 
185
207
        }
186
208
 
187
209
        if (ms_bufferizer_get_avail(&s->speak_delay)> 5*320*(s->samplerate/8000)) /* above 4*20ms -> useless */
188
 
          {
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);
197
 
      s->size_delay=0;
198
 
            speex_echo_state_reset(s->ecstate);
199
 
          }
 
210
        {
 
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);
 
219
                s->size_delay=0;
 
220
                speex_echo_state_reset(s->ecstate);
 
221
        }
200
222
 
201
223
        while (ms_bufferizer_get_avail(&s->in[1])> 5*320*(s->samplerate/8000)){
202
224
                om1=allocb(nbytes,0);
211
233
 
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);
220
242
        s->size_delay=0;
221
243
 
222
 
        if (s->ecstate!=NULL)
 
244
        if (s->ecstate!=NULL){
223
245
                speex_echo_state_destroy(s->ecstate);
224
 
        if (s->den!=NULL)
225
 
          speex_preprocess_state_destroy(s->den);
226
 
 
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);
 
246
                s->ecstate=NULL;
 
247
        }
 
248
        if (s->den!=NULL){
 
249
                speex_preprocess_state_destroy(s->den);
 
250
                s->den=NULL;
 
251
        }
231
252
}
232
253
 
233
254
static int speex_ec_set_sr(MSFilter *f, void *arg){
235
256
 
236
257
        s->samplerate = *(int*)arg;
237
258
 
238
 
        if (s->ecstate!=NULL)
 
259
        if (s->ecstate!=NULL){
239
260
                speex_echo_state_destroy(s->ecstate);
240
 
        if (s->den!=NULL)
241
 
          speex_preprocess_state_destroy(s->den);
242
 
 
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);
 
261
                if (s->den!=NULL)
 
262
                        speex_preprocess_state_destroy(s->den);
 
263
        
 
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);
 
268
        }
247
269
        return 0;
248
270
}
249
271
 
251
273
        SpeexECState *s=(SpeexECState*)f->data;
252
274
        s->framesize = *(int*)arg;
253
275
 
254
 
        if (s->ecstate!=NULL)
 
276
        if (s->ecstate!=NULL){
255
277
                speex_echo_state_destroy(s->ecstate);
256
 
        if (s->den!=NULL)
257
 
          speex_preprocess_state_destroy(s->den);
258
 
 
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);
 
278
                if (s->den!=NULL)
 
279
                        speex_preprocess_state_destroy(s->den);
 
280
        
 
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);
 
285
        }
263
286
        return 0;
264
287
}
265
288
 
266
289
static int speex_ec_set_filterlength(MSFilter *f, void *arg){
267
290
        SpeexECState *s=(SpeexECState*)f->data;
268
 
        s->filterlength = *(int*)arg;
269
 
 
 
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);
274
297
 
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);
279
302
        return 0;
280
303
}
281
304
 
 
305
static int speex_ec_set_delay2(MSFilter *f, void *arg){
 
306
        SpeexECState *s=(SpeexECState*)f->data;
 
307
        s->delay_ms = *(int*)arg;
 
308
        return 0;
 
309
}
 
310
 
 
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;
 
314
        return 0;
 
315
}
 
316
 
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;
296
331
 
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 },
302
341
        {       0                       , NULL}
303
342
};
304
343
 
313
352
        2,
314
353
        2,
315
354
        speex_ec_init,
316
 
        NULL,
 
355
        speex_ec_preprocess,
317
356
        speex_ec_process,
318
357
        speex_ec_postprocess,
319
358
        speex_ec_uninit,
330
369
        .ninputs=2,
331
370
        .noutputs=2,
332
371
        .init=speex_ec_init,
 
372
        .preprocess=speex_ec_preprocess,
333
373
        .process=speex_ec_process,
334
374
        .postprocess=speex_ec_postprocess,
335
375
        .uninit=speex_ec_uninit,