~ubuntu-branches/ubuntu/saucy/sflphone/saucy-proposed

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject/pjmedia/src/pjmedia/echo_speex.c

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2013-06-30 11:40:56 UTC
  • mfrom: (20.1.3 sid)
  • Revision ID: package-import@ubuntu.com-20130630114056-i0rz9ibang07g7qr
Tags: 1.2.3-2
* changeset_r92d62cfc54732bbbcfff2b1d36c096b120b981a5.diff 
  - fixes automatic endian detection 
* Update Vcs: fixes vcs-field-not-canonical

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: echo_speex.c 3553 2011-05-05 06:14:19Z nanang $ */
2
 
/* 
3
 
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4
 
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5
 
 *
6
 
 * This program is free software; you can redistribute it and/or modify
7
 
 * it under the terms of the GNU General Public License as published by
8
 
 * the Free Software Foundation; either version 2 of the License, or
9
 
 * (at your option) any later version.
10
 
 *
11
 
 * This program is distributed in the hope that it will be useful,
12
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 * GNU General Public License for more details.
15
 
 *
16
 
 * You should have received a copy of the GNU General Public License
17
 
 * along with this program; if not, write to the Free Software
18
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
19
 
 */
20
 
 
21
 
#include <pjmedia/echo.h>
22
 
#include <pjmedia/errno.h>
23
 
#include <pj/assert.h>
24
 
#include <pj/log.h>
25
 
#include <pj/pool.h>
26
 
 
27
 
#if defined(PJMEDIA_HAS_SPEEX_AEC) && PJMEDIA_HAS_SPEEX_AEC != 0
28
 
 
29
 
#include <speex/speex_echo.h>
30
 
#include <speex/speex_preprocess.h>
31
 
 
32
 
#include "echo_internal.h"
33
 
 
34
 
typedef struct speex_ec
35
 
{
36
 
    SpeexEchoState       *state;
37
 
    SpeexPreprocessState *preprocess;
38
 
 
39
 
    unsigned              samples_per_frame;
40
 
    unsigned              prefetch;
41
 
    unsigned              options;
42
 
    pj_int16_t           *tmp_frame;
43
 
} speex_ec;
44
 
 
45
 
 
46
 
 
47
 
/*
48
 
 * Create the AEC. 
49
 
 */
50
 
PJ_DEF(pj_status_t) speex_aec_create(pj_pool_t *pool,
51
 
                                     unsigned clock_rate,
52
 
                                     unsigned channel_count,
53
 
                                     unsigned samples_per_frame,
54
 
                                     unsigned tail_ms,
55
 
                                     unsigned options,
56
 
                                     void **p_echo )
57
 
{
58
 
    speex_ec *echo;
59
 
    int sampling_rate;
60
 
 
61
 
    *p_echo = NULL;
62
 
 
63
 
    echo = PJ_POOL_ZALLOC_T(pool, speex_ec);
64
 
    PJ_ASSERT_RETURN(echo != NULL, PJ_ENOMEM);
65
 
 
66
 
    echo->samples_per_frame = samples_per_frame;
67
 
    echo->options = options;
68
 
 
69
 
#if 0
70
 
    echo->state = speex_echo_state_init_mc(echo->samples_per_frame,
71
 
                                           clock_rate * tail_ms / 1000,
72
 
                                           channel_count, channel_count);
73
 
#else
74
 
    if (channel_count != 1) {
75
 
        PJ_LOG(2,("echo_speex.c", "Multichannel EC is not supported by this "
76
 
                                  "echo canceller. It may not work."));
77
 
    }
78
 
    echo->state = speex_echo_state_init(echo->samples_per_frame,
79
 
                                        clock_rate * tail_ms / 1000);
80
 
#endif
81
 
    if (echo->state == NULL) {
82
 
        return PJ_ENOMEM;
83
 
    }
84
 
 
85
 
    /* Set sampling rate */
86
 
    sampling_rate = clock_rate;
87
 
    speex_echo_ctl(echo->state, SPEEX_ECHO_SET_SAMPLING_RATE, 
88
 
                   &sampling_rate);
89
 
 
90
 
    echo->preprocess = speex_preprocess_state_init(echo->samples_per_frame,
91
 
                                                   clock_rate);
92
 
    if (echo->preprocess == NULL) {
93
 
        speex_echo_state_destroy(echo->state);
94
 
        return PJ_ENOMEM;
95
 
    }
96
 
 
97
 
    /* Disable all preprocessing, we only want echo cancellation */
98
 
#if 0
99
 
    disabled = 0;
100
 
    enabled = 1;
101
 
    speex_preprocess_ctl(echo->preprocess, SPEEX_PREPROCESS_SET_DENOISE, 
102
 
                         &enabled);
103
 
    speex_preprocess_ctl(echo->preprocess, SPEEX_PREPROCESS_SET_AGC, 
104
 
                         &disabled);
105
 
    speex_preprocess_ctl(echo->preprocess, SPEEX_PREPROCESS_SET_VAD, 
106
 
                         &disabled);
107
 
    speex_preprocess_ctl(echo->preprocess, SPEEX_PREPROCESS_SET_DEREVERB, 
108
 
                         &enabled);
109
 
#endif
110
 
 
111
 
    /* Control echo cancellation in the preprocessor */
112
 
   speex_preprocess_ctl(echo->preprocess, SPEEX_PREPROCESS_SET_ECHO_STATE, 
113
 
                        echo->state);
114
 
 
115
 
 
116
 
    /* Create temporary frame for echo cancellation */
117
 
    echo->tmp_frame = (pj_int16_t*) pj_pool_zalloc(pool, 2*samples_per_frame);
118
 
    PJ_ASSERT_RETURN(echo->tmp_frame != NULL, PJ_ENOMEM);
119
 
 
120
 
    /* Done */
121
 
    *p_echo = echo;
122
 
    return PJ_SUCCESS;
123
 
 
124
 
}
125
 
 
126
 
 
127
 
/*
128
 
 * Destroy AEC
129
 
 */
130
 
PJ_DEF(pj_status_t) speex_aec_destroy(void *state )
131
 
{
132
 
    speex_ec *echo = (speex_ec*) state;
133
 
 
134
 
    PJ_ASSERT_RETURN(echo && echo->state, PJ_EINVAL);
135
 
 
136
 
    if (echo->state) {
137
 
        speex_echo_state_destroy(echo->state);
138
 
        echo->state = NULL;
139
 
    }
140
 
 
141
 
    if (echo->preprocess) {
142
 
        speex_preprocess_state_destroy(echo->preprocess);
143
 
        echo->preprocess = NULL;
144
 
    }
145
 
 
146
 
    return PJ_SUCCESS;
147
 
}
148
 
 
149
 
 
150
 
/*
151
 
 * Reset AEC
152
 
 */
153
 
PJ_DEF(void) speex_aec_reset(void *state )
154
 
{
155
 
    speex_ec *echo = (speex_ec*) state;
156
 
    speex_echo_state_reset(echo->state);
157
 
}
158
 
 
159
 
 
160
 
/*
161
 
 * Perform echo cancellation.
162
 
 */
163
 
PJ_DEF(pj_status_t) speex_aec_cancel_echo( void *state,
164
 
                                           pj_int16_t *rec_frm,
165
 
                                           const pj_int16_t *play_frm,
166
 
                                           unsigned options,
167
 
                                           void *reserved )
168
 
{
169
 
    speex_ec *echo = (speex_ec*) state;
170
 
 
171
 
    /* Sanity checks */
172
 
    PJ_ASSERT_RETURN(echo && rec_frm && play_frm && options==0 &&
173
 
                     reserved==NULL, PJ_EINVAL);
174
 
 
175
 
    /* Cancel echo, put output in temporary buffer */
176
 
    speex_echo_cancellation(echo->state, (const spx_int16_t*)rec_frm,
177
 
                            (const spx_int16_t*)play_frm,
178
 
                            (spx_int16_t*)echo->tmp_frame);
179
 
 
180
 
 
181
 
    /* Preprocess output */
182
 
    speex_preprocess_run(echo->preprocess, (spx_int16_t*)echo->tmp_frame);
183
 
 
184
 
    /* Copy temporary buffer back to original rec_frm */
185
 
    pjmedia_copy_samples(rec_frm, echo->tmp_frame, echo->samples_per_frame);
186
 
 
187
 
    return PJ_SUCCESS;
188
 
 
189
 
}
190
 
 
191
 
#endif