Mercurial > hg > audiostuff
comparison spandsp-0.0.6pre17/src/spandsp/echo.h @ 4:26cd8f1ef0b1
import spandsp-0.0.6pre17
author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
---|---|
date | Fri, 25 Jun 2010 15:50:58 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
3:c6c5a16ce2f2 | 4:26cd8f1ef0b1 |
---|---|
1 /* | |
2 * SpanDSP - a series of DSP components for telephony | |
3 * | |
4 * echo.h - An echo cancellor, suitable for electrical and acoustic | |
5 * cancellation. This code does not currently comply with | |
6 * any relevant standards (e.g. G.164/5/7/8). | |
7 * | |
8 * Written by Steve Underwood <steveu@coppice.org> | |
9 * | |
10 * Copyright (C) 2001 Steve Underwood | |
11 * | |
12 * All rights reserved. | |
13 * | |
14 * This program is free software; you can redistribute it and/or modify | |
15 * it under the terms of the GNU Lesser General Public License version 2.1, | |
16 * as published by the Free Software Foundation. | |
17 * | |
18 * This program is distributed in the hope that it will be useful, | |
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21 * GNU Lesser General Public License for more details. | |
22 * | |
23 * You should have received a copy of the GNU Lesser General Public | |
24 * License along with this program; if not, write to the Free Software | |
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
26 * | |
27 * $Id: echo.h,v 1.20 2009/09/22 13:11:04 steveu Exp $ | |
28 */ | |
29 | |
30 /*! \file */ | |
31 | |
32 #if !defined(_SPANDSP_ECHO_H_) | |
33 #define _SPANDSP_ECHO_H_ | |
34 | |
35 /*! \page echo_can_page Line echo cancellation for voice | |
36 | |
37 \section echo_can_page_sec_1 What does it do? | |
38 This module aims to provide G.168-2002 compliant echo cancellation, to remove | |
39 electrical echoes (e.g. from 2-4 wire hybrids) from voice calls. | |
40 | |
41 \section echo_can_page_sec_2 How does it work? | |
42 The heart of the echo cancellor is FIR filter. This is adapted to match the echo | |
43 impulse response of the telephone line. It must be long enough to adequately cover | |
44 the duration of that impulse response. The signal transmitted to the telephone line | |
45 is passed through the FIR filter. Once the FIR is properly adapted, the resulting | |
46 output is an estimate of the echo signal received from the line. This is subtracted | |
47 from the received signal. The result is an estimate of the signal which originated | |
48 at the far end of the line, free from echos of our own transmitted signal. | |
49 | |
50 The least mean squares (LMS) algorithm is attributed to Widrow and Hoff, and was | |
51 introduced in 1960. It is the commonest form of filter adaption used in things | |
52 like modem line equalisers and line echo cancellers. There it works very well. | |
53 However, it only works well for signals of constant amplitude. It works very poorly | |
54 for things like speech echo cancellation, where the signal level varies widely. | |
55 This is quite easy to fix. If the signal level is normalised - similar to applying | |
56 AGC - LMS can work as well for a signal of varying amplitude as it does for a modem | |
57 signal. This normalised least mean squares (NLMS) algorithm is the commonest one used | |
58 for speech echo cancellation. Many other algorithms exist - e.g. RLS (essentially | |
59 the same as Kalman filtering), FAP, etc. Some perform significantly better than NLMS. | |
60 However, factors such as computational complexity and patents favour the use of NLMS. | |
61 | |
62 A simple refinement to NLMS can improve its performance with speech. NLMS tends | |
63 to adapt best to the strongest parts of a signal. If the signal is white noise, | |
64 the NLMS algorithm works very well. However, speech has more low frequency than | |
65 high frequency content. Pre-whitening (i.e. filtering the signal to flatten | |
66 its spectrum) the echo signal improves the adapt rate for speech, and ensures the | |
67 final residual signal is not heavily biased towards high frequencies. A very low | |
68 complexity filter is adequate for this, so pre-whitening adds little to the | |
69 compute requirements of the echo canceller. | |
70 | |
71 An FIR filter adapted using pre-whitened NLMS performs well, provided certain | |
72 conditions are met: | |
73 | |
74 - The transmitted signal has poor self-correlation. | |
75 - There is no signal being generated within the environment being cancelled. | |
76 | |
77 The difficulty is that neither of these can be guaranteed. | |
78 | |
79 If the adaption is performed while transmitting noise (or something fairly noise | |
80 like, such as voice) the adaption works very well. If the adaption is performed | |
81 while transmitting something highly correlative (typically narrow band energy | |
82 such as signalling tones or DTMF), the adaption can go seriously wrong. The reason | |
83 is there is only one solution for the adaption on a near random signal - the impulse | |
84 response of the line. For a repetitive signal, there are any number of solutions | |
85 which converge the adaption, and nothing guides the adaption to choose the generalised | |
86 one. Allowing an untrained canceller to converge on this kind of narrowband | |
87 energy probably a good thing, since at least it cancels the tones. Allowing a well | |
88 converged canceller to continue converging on such energy is just a way to ruin | |
89 its generalised adaption. A narrowband detector is needed, so adapation can be | |
90 suspended at appropriate times. | |
91 | |
92 The adaption process is based on trying to eliminate the received signal. When | |
93 there is any signal from within the environment being cancelled it may upset the | |
94 adaption process. Similarly, if the signal we are transmitting is small, noise | |
95 may dominate and disturb the adaption process. If we can ensure that the | |
96 adaption is only performed when we are transmitting a significant signal level, | |
97 and the environment is not, things will be OK. Clearly, it is easy to tell when | |
98 we are sending a significant signal. Telling, if the environment is generating a | |
99 significant signal, and doing it with sufficient speed that the adaption will | |
100 not have diverged too much more we stop it, is a little harder. | |
101 | |
102 The key problem in detecting when the environment is sourcing significant energy | |
103 is that we must do this very quickly. Given a reasonably long sample of the | |
104 received signal, there are a number of strategies which may be used to assess | |
105 whether that signal contains a strong far end component. However, by the time | |
106 that assessment is complete the far end signal will have already caused major | |
107 mis-convergence in the adaption process. An assessment algorithm is needed which | |
108 produces a fairly accurate result from a very short burst of far end energy. | |
109 | |
110 \section echo_can_page_sec_3 How do I use it? | |
111 The echo cancellor processes both the transmit and receive streams sample by | |
112 sample. The processing function is not declared inline. Unfortunately, | |
113 cancellation requires many operations per sample, so the call overhead is only a | |
114 minor burden. | |
115 */ | |
116 | |
117 #include "fir.h" | |
118 | |
119 /* Mask bits for the adaption mode */ | |
120 enum | |
121 { | |
122 ECHO_CAN_USE_ADAPTION = 0x01, | |
123 ECHO_CAN_USE_NLP = 0x02, | |
124 ECHO_CAN_USE_CNG = 0x04, | |
125 ECHO_CAN_USE_CLIP = 0x08, | |
126 ECHO_CAN_USE_SUPPRESSOR = 0x10, | |
127 ECHO_CAN_USE_TX_HPF = 0x20, | |
128 ECHO_CAN_USE_RX_HPF = 0x40, | |
129 ECHO_CAN_DISABLE = 0x80 | |
130 }; | |
131 | |
132 /*! | |
133 G.168 echo canceller descriptor. This defines the working state for a line | |
134 echo canceller. | |
135 */ | |
136 typedef struct echo_can_state_s echo_can_state_t; | |
137 | |
138 #if defined(__cplusplus) | |
139 extern "C" | |
140 { | |
141 #endif | |
142 | |
143 /*! Create a voice echo canceller context. | |
144 \param len The length of the canceller, in samples. | |
145 \return The new canceller context, or NULL if the canceller could not be created. | |
146 */ | |
147 SPAN_DECLARE(echo_can_state_t *) echo_can_init(int len, int adaption_mode); | |
148 | |
149 /*! Release a voice echo canceller context. | |
150 \param ec The echo canceller context. | |
151 \return 0 for OK, else -1. | |
152 */ | |
153 SPAN_DECLARE(int) echo_can_release(echo_can_state_t *ec); | |
154 | |
155 /*! Free a voice echo canceller context. | |
156 \param ec The echo canceller context. | |
157 \return 0 for OK, else -1. | |
158 */ | |
159 SPAN_DECLARE(int) echo_can_free(echo_can_state_t *ec); | |
160 | |
161 /*! Flush (reinitialise) a voice echo canceller context. | |
162 \param ec The echo canceller context. | |
163 */ | |
164 SPAN_DECLARE(void) echo_can_flush(echo_can_state_t *ec); | |
165 | |
166 /*! Set the adaption mode of a voice echo canceller context. | |
167 \param ec The echo canceller context. | |
168 \param adaption_mode The mode. | |
169 */ | |
170 SPAN_DECLARE(void) echo_can_adaption_mode(echo_can_state_t *ec, int adaption_mode); | |
171 | |
172 /*! Process a sample through a voice echo canceller. | |
173 \param ec The echo canceller context. | |
174 \param tx The transmitted audio sample. | |
175 \param rx The received audio sample. | |
176 \return The clean (echo cancelled) received sample. | |
177 */ | |
178 SPAN_DECLARE(int16_t) echo_can_update(echo_can_state_t *ec, int16_t tx, int16_t rx); | |
179 | |
180 /*! Process to high pass filter the tx signal. | |
181 \param ec The echo canceller context. | |
182 \param tx The transmitted auio sample. | |
183 \return The HP filtered transmit sample, send this to your D/A. | |
184 */ | |
185 SPAN_DECLARE(int16_t) echo_can_hpf_tx(echo_can_state_t *ec, int16_t tx); | |
186 | |
187 SPAN_DECLARE(void) echo_can_snapshot(echo_can_state_t *ec); | |
188 | |
189 #if defined(__cplusplus) | |
190 } | |
191 #endif | |
192 | |
193 #endif | |
194 /*- End of file ------------------------------------------------------------*/ |