110
80
#define MIN_RX_POWER_FOR_ADAPTION 64
113
static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p,
114
struct echo_can_state **ec)
83
static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
84
struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec);
85
static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec);
86
static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size);
87
static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val);
88
static void echocan_NLP_toggle(struct dahdi_echocan_state *ec, unsigned int enable);
90
static const struct dahdi_echocan_factory my_factory = {
93
.echocan_create = echo_can_create,
96
static const struct dahdi_echocan_features my_features = {
100
static const struct dahdi_echocan_ops my_ops = {
102
.echocan_free = echo_can_free,
103
.echocan_process = echo_can_process,
104
.echocan_traintap = echo_can_traintap,
105
.echocan_NLP_toggle = echocan_NLP_toggle,
109
struct dahdi_echocan_state dahdi;
114
int rx_power_threshold;
117
int16_t *tx_history; /* Last N tx samples */
118
int32_t *fir_taps; /* Echo FIR taps */
119
int16_t *fir_taps_short; /* Echo FIR taps, shorts instead of ints */
133
int32_t latest_correction; /* Indication of the magnitude of the latest
134
adaption, or a code to indicate why adaption
135
was skipped, for test purposes */
138
#define dahdi_to_pvt(a) container_of(a, struct ec_pvt, dahdi)
140
static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
141
struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec)
118
146
if (ecp->param_count > 0) {
119
printk(KERN_WARNING "SEC echo canceler does not support parameters; failing request\n");
147
printk(KERN_WARNING "SEC does not support parameters; failing request\n");
123
size = sizeof(**ec) + ecp->tap_length * sizeof(int32_t) + ecp->tap_length * 3 * sizeof(int16_t);
125
if (!(*ec = kmalloc(size, GFP_KERNEL)))
151
size = sizeof(*pvt) + ecp->tap_length * sizeof(int32_t) + ecp->tap_length * 3 * sizeof(int16_t);
153
pvt = kzalloc(size, GFP_KERNEL);
128
memset(*ec, 0, size);
130
(*ec)->taps = ecp->tap_length;
131
(*ec)->tap_mask = ecp->tap_length - 1;
132
(*ec)->tx_history = (int16_t *) (*ec + sizeof(**ec));
133
(*ec)->fir_taps = (int32_t *) (*ec + sizeof(**ec) +
134
ecp->tap_length * 2 * sizeof(int16_t));
135
(*ec)->fir_taps_short = (int16_t *) (*ec + sizeof(**ec) +
136
ecp->tap_length * sizeof(int32_t) +
137
ecp->tap_length * 2 * sizeof(int16_t));
138
(*ec)->rx_power_threshold = 10000000;
139
(*ec)->use_suppressor = FALSE;
157
pvt->dahdi.ops = &my_ops;
158
pvt->dahdi.features = my_features;
160
pvt->taps = ecp->tap_length;
161
pvt->tap_mask = ecp->tap_length - 1;
162
pvt->tx_history = (int16_t *) (pvt + sizeof(*pvt));
163
pvt->fir_taps = (int32_t *) (pvt + sizeof(*pvt) +
164
ecp->tap_length * 2 * sizeof(int16_t));
165
pvt->fir_taps_short = (int16_t *) (pvt + sizeof(*pvt) +
166
ecp->tap_length * sizeof(int32_t) +
167
ecp->tap_length * 2 * sizeof(int16_t));
168
pvt->rx_power_threshold = 10000000;
169
pvt->use_suppressor = FALSE;
140
170
/* Non-linear processor - a fancy way to say "zap small signals, to avoid
141
171
accumulating noise". */
142
(*ec)->use_nlp = TRUE;
146
/*- End of function --------------------------------------------------------*/
148
static void echo_can_free(struct echo_can_state *ec)
178
static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec)
180
struct ec_pvt *pvt = dahdi_to_pvt(ec);
152
/*- End of function --------------------------------------------------------*/
154
static inline int16_t sample_update(struct echo_can_state *ec, int16_t tx, int16_t rx)
185
static inline int16_t sample_update(struct ec_pvt *pvt, int16_t tx, int16_t rx)
160
ec->tx_history[ec->curr_pos] = tx;
161
ec->tx_history[ec->curr_pos + ec->taps] = tx;
163
/* Evaluate the echo - i.e. apply the FIR filter */
164
/* Assume the gain of the FIR does not exceed unity. Exceeding unity
165
would seem like a rather poor thing for an echo cancellor to do :)
166
This means we can compute the result with a total disregard for
167
overflows. 16bits x 16bits -> 31bits, so no overflow can occur in
168
any multiply. While accumulating we may overflow and underflow the
169
32 bit scale often. However, if the gain does not exceed unity,
170
everything should work itself out, and the final result will be
171
OK, without any saturation logic. */
172
/* Overflow is very much possible here, and we do nothing about it because
173
of the compute costs */
174
/* 16 bit coeffs for the LMS give lousy results (maths good, actual sound
175
bad!), but 32 bit coeffs require some shifting. On balance 32 bit seems
191
pvt->tx_history[pvt->curr_pos] = tx;
192
pvt->tx_history[pvt->curr_pos + pvt->taps] = tx;
194
/* Evaluate the echo - i.e. apply the FIR filter */
195
/* Assume the gain of the FIR does not exceed unity. Exceeding unity
196
would seem like a rather poor thing for an echo cancellor to do :)
197
This means we can compute the result with a total disregard for
198
overflows. 16bits x 16bits -> 31bits, so no overflow can occur in
199
any multiply. While accumulating we may overflow and underflow the
200
32 bit scale often. However, if the gain does not exceed unity,
201
everything should work itself out, and the final result will be
202
OK, without any saturation logic. */
203
/* Overflow is very much possible here, and we do nothing about it because
204
of the compute costs */
205
/* 16 bit coeffs for the LMS give lousy results (maths good, actual sound
206
bad!), but 32 bit coeffs require some shifting. On balance 32 bit seems
177
208
#ifdef USE_SHORTS
178
echo_value = CONVOLVE2(ec->fir_taps_short, ec->tx_history + ec->curr_pos, ec->taps);
209
echo_value = CONVOLVE2(pvt->fir_taps_short, pvt->tx_history + pvt->curr_pos, pvt->taps);
180
echo_value = CONVOLVE(ec->fir_taps, ec->tx_history + ec->curr_pos, ec->taps);
211
echo_value = CONVOLVE(pvt->fir_taps, pvt->tx_history + pvt->curr_pos, pvt->taps);
184
/* And the answer is..... */
185
clean_rx = rx - echo_value;
187
/* That was the easy part. Now we need to adapt! */
188
if (ec->nonupdate_dwell > 0)
189
ec->nonupdate_dwell--;
191
/* If there is very little being transmitted, any attempt to train is
192
futile. We would either be training on the far end's noise or signal,
193
the channel's own noise, or our noise. Either way, this is hardly good
194
training, so don't do it (avoid trouble). */
195
/* If the received power is very low, either we are sending very little or
196
we are already well adapted. There is little point in trying to improve
197
the adaption under these circumstanceson, so don't do it (reduce the
199
if (ec->tx_power > MIN_TX_POWER_FOR_ADAPTION
201
ec->rx_power > MIN_RX_POWER_FOR_ADAPTION)
203
/* This is a really crude piece of decision logic, but it does OK
205
if (ec->tx_power > ec->rx_power << 1)
207
/* There is no far-end speech detected */
208
if (ec->nonupdate_dwell == 0)
210
/* ... and we are not in the dwell time from previous speech. */
211
//nsuppr = saturate((clean_rx << 16)/ec->tx_power);
212
nsuppr = (clean_rx << 16) / ec->tx_power;
219
/* Update the FIR taps */
220
ec->latest_correction = 0;
215
/* And the answer is..... */
216
clean_rx = rx - echo_value;
218
/* That was the easy part. Now we need to adapt! */
219
if (pvt->nonupdate_dwell > 0)
220
pvt->nonupdate_dwell--;
222
/* If there is very little being transmitted, any attempt to train is
223
futile. We would either be training on the far end's noise or signal,
224
the channel's own noise, or our noise. Either way, this is hardly good
225
training, so don't do it (avoid trouble). */
226
/* If the received power is very low, either we are sending very little or
227
we are already well adapted. There is little point in trying to improve
228
the adaption under these circumstanceson, so don't do it (reduce the
230
if (pvt->tx_power > MIN_TX_POWER_FOR_ADAPTION && pvt->rx_power > MIN_RX_POWER_FOR_ADAPTION) {
231
/* This is a really crude piece of decision logic, but it does OK
233
if (pvt->tx_power > pvt->rx_power << 1) {
234
/* There is no far-end speech detected */
235
if (pvt->nonupdate_dwell == 0) {
236
/* ... and we are not in the dwell time from previous speech. */
237
/* nsuppr = saturate((clean_rx << 16)/pvt->tx_power); */
238
nsuppr = (clean_rx << 16) / pvt->tx_power;
245
/* Update the FIR taps */
246
pvt->latest_correction = 0;
221
247
#ifdef USE_SHORTS
222
UPDATE2(ec->fir_taps, ec->fir_taps_short, ec->tx_history + ec->curr_pos, nsuppr, ec->taps);
248
UPDATE2(pvt->fir_taps, pvt->fir_taps_short, pvt->tx_history + pvt->curr_pos, nsuppr, pvt->taps);
224
UPDATE(ec->fir_taps, ec->fir_taps_short, ec->tx_history + ec->curr_pos, nsuppr, ec->taps);
250
UPDATE(pvt->fir_taps, pvt->fir_taps_short, pvt->tx_history + pvt->curr_pos, nsuppr, pvt->taps);
228
ec->latest_correction = -3;
233
ec->nonupdate_dwell = NONUPDATE_DWELL_TIME;
234
ec->latest_correction = -2;
239
ec->nonupdate_dwell = 0;
240
ec->latest_correction = -1;
242
/* Calculate short term power levels using very simple single pole IIRs */
243
/* TODO: Is the nasty modulus approach the fastest, or would a real
244
tx*tx power calculation actually be faster? */
245
ec->tx_power += ((abs(tx) - ec->tx_power) >> 5);
246
ec->rx_power += ((abs(rx) - ec->rx_power) >> 5);
247
ec->clean_rx_power += ((abs(clean_rx) - ec->clean_rx_power) >> 5);
253
pvt->latest_correction = -3;
256
pvt->nonupdate_dwell = NONUPDATE_DWELL_TIME;
257
pvt->latest_correction = -2;
260
pvt->nonupdate_dwell = 0;
261
pvt->latest_correction = -1;
263
/* Calculate short term power levels using very simple single pole IIRs */
264
/* TODO: Is the nasty modulus approach the fastest, or would a real
265
tx*tx power calculation actually be faster? */
266
pvt->tx_power += ((abs(tx) - pvt->tx_power) >> 5);
267
pvt->rx_power += ((abs(rx) - pvt->rx_power) >> 5);
268
pvt->clean_rx_power += ((abs(clean_rx) - pvt->clean_rx_power) >> 5);
249
270
#if defined(XYZZY)
250
if (ec->use_suppressor)
252
ec->supp_test1 += (ec->tx_history[ec->curr_pos] - ec->tx_history[(ec->curr_pos - 7) & ec->tap_mask]);
253
ec->supp_test2 += (ec->tx_history[(ec->curr_pos - 24) & ec->tap_mask] - ec->tx_history[(ec->curr_pos - 31) & ec->tap_mask]);
254
if (ec->supp_test1 > 42 && ec->supp_test2 > 42)
258
supp = supp_change + k1*ec->supp1 + k2*ec->supp2;
259
ec->supp2 = ec->supp1;
261
clean_rx *= (1 - supp);
271
if (pvt->use_suppressor) {
272
pvt->supp_test1 += (pvt->tx_history[pvt->curr_pos] - pvt->tx_history[(pvt->curr_pos - 7) & pvt->tap_mask]);
273
pvt->supp_test2 += (pvt->tx_history[(pvt->curr_pos - 24) & pvt->tap_mask] - pvt->tx_history[(pvt->curr_pos - 31) & pvt->tap_mask]);
274
if (pvt->supp_test1 > 42 && pvt->supp_test2 > 42)
278
supp = supp_change + k1*pvt->supp1 + k2*pvt->supp2;
279
pvt->supp2 = pvt->supp1;
281
clean_rx *= (1 - supp);
265
if (ec->use_nlp && ec->rx_power < 32)
268
/* Roll around the rolling buffer */
269
ec->curr_pos = (ec->curr_pos - 1) & ec->tap_mask;
285
if (pvt->use_nlp && pvt->rx_power < 32)
288
/* Roll around the rolling buffer */
289
pvt->curr_pos = (pvt->curr_pos - 1) & pvt->tap_mask;
273
/*- End of function --------------------------------------------------------*/
275
static void echo_can_update(struct echo_can_state *ec, short *iref, short *isig)
294
static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size)
296
struct ec_pvt *pvt = dahdi_to_pvt(ec);
280
for (x = 0; x < DAHDI_CHUNKSIZE; x++) {
281
result = sample_update(ec, *iref, *isig);
300
for (x = 0; x < size; x++) {
301
result = sample_update(pvt, *iref, *isig);
282
302
*isig++ = result;
286
/*- End of function --------------------------------------------------------*/
288
static int echo_can_traintap(struct echo_can_state *ec, int pos, short val)
307
static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val)
309
struct ec_pvt *pvt = dahdi_to_pvt(ec);
290
311
/* Reset hang counter to avoid adjustments after
291
312
initial forced training */
292
ec->nonupdate_dwell = ec->taps << 1;
295
ec->fir_taps[pos] = val << 17;
296
ec->fir_taps_short[pos] = val << 1;
297
if (++pos >= ec->taps)
301
/*- End of function --------------------------------------------------------*/
303
static const struct dahdi_echocan me = {
305
.owner = THIS_MODULE,
306
.echo_can_create = echo_can_create,
307
.echo_can_free = echo_can_free,
308
.echo_can_array_update = echo_can_update,
309
.echo_can_traintap = echo_can_traintap,
313
pvt->nonupdate_dwell = pvt->taps << 1;
314
if (pos >= pvt->taps)
316
pvt->fir_taps[pos] = val << 17;
317
pvt->fir_taps_short[pos] = val << 1;
318
if (++pos >= pvt->taps)
324
static void echocan_NLP_toggle(struct dahdi_echocan_state *ec, unsigned int enable)
326
struct ec_pvt *pvt = dahdi_to_pvt(ec);
328
pvt->use_nlp = enable ? 1 : 0;
312
331
static int __init mod_init(void)
314
if (dahdi_register_echocan(&me)) {
333
if (dahdi_register_echocan_factory(&my_factory)) {
315
334
module_printk(KERN_ERR, "could not register with DAHDI core\n");
320
module_printk(KERN_NOTICE, "Registered echo canceler '%s'\n", me.name);
339
module_printk(KERN_NOTICE, "Registered echo canceler '%s'\n", my_factory.name);
325
344
static void __exit mod_exit(void)
327
dahdi_unregister_echocan(&me);
346
dahdi_unregister_echocan_factory(&my_factory);
330
349
module_param(debug, int, S_IRUGO | S_IWUSR);