1 /*
2 * SpanDSP - a series of DSP components for telephony
3 *
4 * echo.c - 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). One day....
7 *
8 * Written by Steve Underwood <steveu@coppice.org>
9 *
10 * Copyright (C) 2001, 2003 Steve Underwood
11 *
12 * Based on a bit from here, a bit from there, eye of toad,
13 * ear of bat, etc - plus, of course, my own 2 cents.
14 *
15 * All rights reserved.
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU Lesser General Public License version 2.1,
19 * as published by the Free Software Foundation.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU Lesser General Public License for more details.
25 *
26 * You should have received a copy of the GNU Lesser General Public
27 * License along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 */
30
31 /*! \file */
32
33 /* TODO:
34 Finish the echo suppressor option, however nasty suppression may be.
35 Add an option to reintroduce side tone at -24dB under appropriate conditions.
36 Improve double talk detector (iterative!)
37 */
38
39 /* We need to differentiate between transmitted energy which will train the echo
40 canceller well (voice, white noise, and other broadband sources) and energy
41 which will train it badly (supervisory tones, DTMF, whistles, and other
42 narrowband sources). There are many ways this might be done. This canceller uses
43 a method based on the autocorrelation qualities of the transmitted signal. A rather
44 peaky autocorrelation function is a clear sign of a narrowband signal. We only need
45 perform the autocorrelation at well spaced intervals, so the compute load is not too
46 great. Multiple successive autocorrelation functions with a similar peaky shape are a
47 clear indication of a stationary narrowband signal. Using TKEO, it should be possible to
48 greatly reduce the compute requirement for narrowband detection. */
49
50 /* The FIR taps must be adapted as 32 bit values, to get the necessary finesse
51 in the adaption process. However, they are applied as 16 bit values (bits 30-15
52 of the 32 bit values) in the FIR. For the working 16 bit values, we need 4 sets.
53
54 3 of the 16 bit sets are used on a rotating basis. Normally the canceller steps
55 round these 3 sets at regular intervals. Any time we detect double talk, we can go
56 back to the set from two steps ago with reasonable assurance it is a well adapted
57 set. We cannot just go back one step, as we may have rotated the sets just before
58 double talk or tone was detected, and that set may already be somewhat corrupted.
59
60 When narrowband energy is detected we need to continue adapting to it, to echo
61 cancel it. However, the adaption will almost certainly be going astray. Broadband
62 (or even complex sequences of narrowband) energy will normally lead to a well
63 trained cancellor, with taps matching the impulse response of the channel.
64 For stationary narrowband energy, there is usually has an infinite number of
65 alternative tap sets which will cancel it well. A previously well trained set of
66 taps will tend to drift amongst the alternatives. When broadband energy resumes, the
67 taps may be a total mismatch for the signal, and could even amplify rather than
68 attenuate the echo. The solution is to use a fourth set of 16 bit taps. When we first
69 detect the narrowband energy we save the oldest of the group of three sets, but do
70 not change back to an older set. We let the canceller cancel, and it adaption drift
71 while the narrowband energy is present. When we detect the narrowband energy has ceased,
72 we switch to using the fourth set of taps which was saved.
73
74 When we revert to an older set of taps, we must replace both the 16 bit and 32 bit
75 working tap sets. The saved 16 bit values are good enough to also be used as a replacement
76 for the 32 bit values. We loose the fractions, but they should soon settle down in a
77 reasonable way. */
78
79 #if defined(HAVE_CONFIG_H)
80 #include "config.h"
81 #endif
82
83 #include <inttypes.h>
84 #include <stdlib.h>
85 #if defined(HAVE_TGMATH_H)
86 #include <tgmath.h>
87 #endif
88 #if defined(HAVE_MATH_H)
89 #include <math.h>
90 #endif
91 #if defined(HAVE_STDBOOL_H)
92 #include <stdbool.h>
93 #else
94 #include "spandsp/stdbool.h"
95 #endif
96 #include "floating_fudge.h"
97 #include <string.h>
98 #include <stdio.h>
99
100 #include "spandsp/telephony.h"
101 #include "spandsp/alloc.h"
102 #include "spandsp/fast_convert.h"
103 #include "spandsp/logging.h"
104 #include "spandsp/saturated.h"
105 #include "spandsp/dc_restore.h"
106 #include "spandsp/bit_operations.h"
107 #include "spandsp/echo.h"
108
109 #include "spandsp/private/echo.h"
110
111 #if !defined(NULL)
112 #define NULL (void *) 0
113 #endif
114
115 #define NONUPDATE_DWELL_TIME 600 /* 600 samples, or 75ms */
116
117 #define MIN_TX_POWER_FOR_ADAPTION 64*64
118 #define MIN_RX_POWER_FOR_ADAPTION 64*64
119
narrowband_detect(echo_can_state_t * ec)120 static int narrowband_detect(echo_can_state_t *ec)
121 {
122 int k;
123 int i;
124 float temp;
125 float scale;
126 float sf[128];
127 float f_acf[128];
128 int32_t acf[28];
129 int score;
130 int len = 32;
131 int alen = 9;
132
133 k = ec->curr_pos;
134 for (i = 0; i < len; i++)
135 {
136 sf[i] = ec->fir_state.history[k++];
137 if (k >= 256)
138 k = 0;
139 }
140 for (k = 0; k < alen; k++)
141 {
142 temp = 0;
143 for (i = k; i < len; i++)
144 temp += sf[i]*sf[i - k];
145 f_acf[k] = temp;
146 }
147 scale = 0x1FFFFFFF/f_acf[0];
148 for (k = 0; k < alen; k++)
149 acf[k] = (int32_t) (f_acf[k]*scale);
150 score = 0;
151 for (i = 0; i < 9; i++)
152 {
153 if (ec->last_acf[i] >= 0 && acf[i] >= 0)
154 {
155 if ((ec->last_acf[i] >> 1) < acf[i] && acf[i] < (ec->last_acf[i] << 1))
156 score++;
157 }
158 else if (ec->last_acf[i] < 0 && acf[i] < 0)
159 {
160 if ((ec->last_acf[i] >> 1) > acf[i] && acf[i] > (ec->last_acf[i] << 1))
161 score++;
162 }
163 }
164 memcpy(ec->last_acf, acf, alen*sizeof(ec->last_acf[0]));
165 return score;
166 }
167
lms_adapt(echo_can_state_t * ec,int factor)168 static __inline__ void lms_adapt(echo_can_state_t *ec, int factor)
169 {
170 int i;
171
172 #if 0
173 mmx_t *mmx_taps;
174 mmx_t *mmx_coeffs;
175 mmx_t *mmx_hist;
176 mmx_t mmx;
177
178 mmx.w[0] =
179 mmx.w[1] =
180 mmx.w[2] =
181 mmx.w[3] = factor;
182 mmx_hist = (mmx_t *) &fir->history[fir->curr_pos];
183 mmx_taps = (mmx_t *) &fir->taps;
184 mmx_coeffs = (mmx_t *) fir->coeffs;
185 i = fir->taps;
186 movq_m2r(mmx, mm0);
187 while (i > 0)
188 {
189 movq_m2r(mmx_hist[0], mm1);
190 movq_m2r(mmx_taps[0], mm0);
191 movq_m2r(mmx_taps[1], mm1);
192 movq_r2r(mm1, mm2);
193 pmulhw(mm0, mm1);
194 pmullw(mm0, mm2);
195
196 pmaddwd_r2r(mm1, mm0);
197 pmaddwd_r2r(mm3, mm2);
198 paddd_r2r(mm0, mm4);
199 paddd_r2r(mm2, mm4);
200 movq_r2m(mm0, mmx_taps[0]);
201 movq_r2m(mm1, mmx_taps[0]);
202 movq_r2m(mm2, mmx_coeffs[0]);
203 mmx_taps += 2;
204 mmx_coeffs += 1;
205 mmx_hist += 1;
206 i -= 4;
207 )
208 emms();
209 #elif 0
210 /* Update the FIR taps */
211 for (i = ec->taps - 1; i >= 0; i--)
212 {
213 /* Leak to avoid the coefficients drifting beyond the ability of the
214 adaption process to bring them back under control. */
215 ec->fir_taps32[i] -= (ec->fir_taps32[i] >> 23);
216 ec->fir_taps32[i] += (ec->fir_state.history[i + ec->curr_pos]*factor);
217 ec->latest_correction = (ec->fir_state.history[i + ec->curr_pos]*factor);
218 ec->fir_taps16[ec->tap_set][i] = ec->fir_taps32[i] >> 15;
219 }
220 #else
221 int offset1;
222 int offset2;
223
224 /* Update the FIR taps */
225 offset2 = ec->curr_pos;
226 offset1 = ec->taps - offset2;
227 for (i = ec->taps - 1; i >= offset1; i--)
228 {
229 ec->fir_taps32[i] += (ec->fir_state.history[i - offset1]*factor);
230 ec->fir_taps16[ec->tap_set][i] = (int16_t) (ec->fir_taps32[i] >> 15);
231 }
232 for ( ; i >= 0; i--)
233 {
234 ec->fir_taps32[i] += (ec->fir_state.history[i + offset2]*factor);
235 ec->fir_taps16[ec->tap_set][i] = (int16_t) (ec->fir_taps32[i] >> 15);
236 }
237 #endif
238 }
239 /*- End of function --------------------------------------------------------*/
240
241 SPAN_DECLARE(echo_can_state_t *) echo_can_init(int len, int adaption_mode)
242 {
243 echo_can_state_t *ec;
244 int i;
245 int j;
246
247 if ((ec = (echo_can_state_t *) span_alloc(sizeof(*ec))) == NULL)
248 return NULL;
249 memset(ec, 0, sizeof(*ec));
250 ec->taps = len;
251 ec->curr_pos = ec->taps - 1;
252 ec->tap_mask = ec->taps - 1;
253 if ((ec->fir_taps32 = (int32_t *) span_alloc(ec->taps*sizeof(int32_t))) == NULL)
254 {
255 span_free(ec);
256 return NULL;
257 }
258 memset(ec->fir_taps32, 0, ec->taps*sizeof(int32_t));
259 for (i = 0; i < 4; i++)
260 {
261 if ((ec->fir_taps16[i] = (int16_t *) span_alloc(ec->taps*sizeof(int16_t))) == NULL)
262 {
263 for (j = 0; j < i; j++)
264 span_free(ec->fir_taps16[j]);
265 span_free(ec->fir_taps32);
266 span_free(ec);
267 return NULL;
268 }
269 memset(ec->fir_taps16[i], 0, ec->taps*sizeof(int16_t));
270 }
271 fir16_create(&ec->fir_state,
272 ec->fir_taps16[0],
273 ec->taps);
274 ec->rx_power_threshold = 10000000;
275 ec->geigel_max = 0;
276 ec->geigel_lag = 0;
277 ec->dtd_onset = false;
278 ec->tap_set = 0;
279 ec->tap_rotate_counter = 1600;
280 ec->cng_level = 1000;
281 echo_can_adaption_mode(ec, adaption_mode);
282 return ec;
283 }
284 /*- End of function --------------------------------------------------------*/
285
286 SPAN_DECLARE(int) echo_can_release(echo_can_state_t *ec)
287 {
288 return 0;
289 }
290 /*- End of function --------------------------------------------------------*/
291
292 SPAN_DECLARE(int) echo_can_free(echo_can_state_t *ec)
293 {
294 int i;
295
296 fir16_free(&ec->fir_state);
297 span_free(ec->fir_taps32);
298 for (i = 0; i < 4; i++)
299 span_free(ec->fir_taps16[i]);
300 span_free(ec);
301 return 0;
302 }
303 /*- End of function --------------------------------------------------------*/
304
305 SPAN_DECLARE(void) echo_can_adaption_mode(echo_can_state_t *ec, int adaption_mode)
306 {
307 ec->adaption_mode = adaption_mode;
308 }
309 /*- End of function --------------------------------------------------------*/
310
311 SPAN_DECLARE(void) echo_can_flush(echo_can_state_t *ec)
312 {
313 int i;
314
315 for (i = 0; i < 4; i++)
316 ec->tx_power[i] = 0;
317 for (i = 0; i < 3; i++)
318 ec->rx_power[i] = 0;
319 ec->clean_rx_power = 0;
320 ec->nonupdate_dwell = 0;
321
322 fir16_flush(&ec->fir_state);
323 ec->fir_state.curr_pos = ec->taps - 1;
324 memset(ec->fir_taps32, 0, ec->taps*sizeof(int32_t));
325 for (i = 0; i < 4; i++)
326 memset(ec->fir_taps16[i], 0, ec->taps*sizeof(int16_t));
327
328 ec->curr_pos = ec->taps - 1;
329
330 ec->supp_test1 = 0;
331 ec->supp_test2 = 0;
332 ec->supp1 = 0;
333 ec->supp2 = 0;
334 ec->vad = 0;
335 ec->cng_level = 1000;
336 ec->cng_filter = 0;
337
338 ec->geigel_max = 0;
339 ec->geigel_lag = 0;
340 ec->dtd_onset = false;
341 ec->tap_set = 0;
342 ec->tap_rotate_counter = 1600;
343
344 ec->latest_correction = 0;
345
346 memset(ec->last_acf, 0, sizeof(ec->last_acf));
347 ec->narrowband_count = 0;
348 ec->narrowband_score = 0;
349 }
350 /*- End of function --------------------------------------------------------*/
351
352 int sample_no = 0;
353
354 SPAN_DECLARE(void) echo_can_snapshot(echo_can_state_t *ec)
355 {
356 memcpy(ec->snapshot, ec->fir_taps16[0], ec->taps*sizeof(int16_t));
357 }
358 /*- End of function --------------------------------------------------------*/
359
360 static __inline__ int16_t echo_can_hpf(int32_t coeff[2], int16_t amp)
361 {
362 int32_t z;
363
364 /*
365 Filter DC, 3dB point is 160Hz (I think), note 32 bit precision required
366 otherwise values do not track down to 0. Zero at DC, Pole at (1-Beta)
367 only real axis. Some chip sets (like Si labs) don't need
368 this, but something like a $10 X100P card does. Any DC really slows
369 down convergence.
370
371 Note: removes some low frequency from the signal, this reduces
372 the speech quality when listening to samples through headphones
373 but may not be obvious through a telephone handset.
374
375 Note that the 3dB frequency in radians is approx Beta, e.g. for
376 Beta = 2^(-3) = 0.125, 3dB freq is 0.125 rads = 159Hz.
377
378 This is one of the classic DC removal filters, adjusted to provide sufficient
379 bass rolloff to meet the above requirement to protect hybrids from things that
380 upset them. The difference between successive samples produces a lousy HPF, and
381 then a suitably placed pole flattens things out. The final result is a nicely
382 rolled off bass end. The filtering is implemented with extended fractional
383 precision, which noise shapes things, giving very clean DC removal.
384
385 Make sure the gain of the HPF is 1.0. The first can still saturate a little under
386 impulse conditions, and it might roll to 32768 and need clipping on sustained peak
387 level signals. However, the scale of such clipping is small, and the error due to
388 any saturation should not markedly affect the downstream processing. */
389 z = amp << 15;
390 z -= (z >> 4);
391 coeff[0] += z - (coeff[0] >> 3) - coeff[1];
392 coeff[1] = z;
393 z = coeff[0] >> 15;
394
395 return saturate16(z);
396 }
397 /*- End of function --------------------------------------------------------*/
398
399 SPAN_DECLARE(int16_t) echo_can_update(echo_can_state_t *ec, int16_t tx, int16_t rx)
400 {
401 int32_t echo_value;
402 int clean_rx;
403 int nsuppr;
404 int score;
405 int i;
406
407 sample_no++;
408 if (ec->adaption_mode & ECHO_CAN_USE_RX_HPF)
409 rx = echo_can_hpf(ec->rx_hpf, rx);
410
411 ec->latest_correction = 0;
412 /* Evaluate the echo - i.e. apply the FIR filter */
413 /* Assume the gain of the FIR does not exceed unity. Exceeding unity
414 would seem like a rather poor thing for an echo cancellor to do :)
415 This means we can compute the result with a total disregard for
416 overflows. 16bits x 16bits -> 31bits, so no overflow can occur in
417 any multiply. While accumulating we may overflow and underflow the
418 32 bit scale often. However, if the gain does not exceed unity,
419 everything should work itself out, and the final result will be
420 OK, without any saturation logic. */
421 /* Overflow is very much possible here, and we do nothing about it because
422 of the compute costs */
423 /* 16 bit coeffs for the LMS give lousy results (maths good, actual sound
424 bad!), but 32 bit coeffs require some shifting. On balance 32 bit seems
425 best */
426 echo_value = fir16(&ec->fir_state, tx);
427
428 /* And the answer is..... */
429 clean_rx = rx - echo_value;
430 printf("echo is %" PRId32 "\n", echo_value);
431 /* That was the easy part. Now we need to adapt! */
432 if (ec->nonupdate_dwell > 0)
433 ec->nonupdate_dwell--;
434
435 /* Calculate short term power levels using very simple single pole IIRs */
436 /* TODO: Is the nasty modulus approach the fastest, or would a real
437 tx*tx power calculation actually be faster? Using the squares
438 makes the numbers grow a lot! */
439 ec->tx_power[3] += ((abs(tx) - ec->tx_power[3]) >> 5);
440 ec->tx_power[2] += ((tx*tx - ec->tx_power[2]) >> 8);
441 ec->tx_power[1] += ((tx*tx - ec->tx_power[1]) >> 5);
442 ec->tx_power[0] += ((tx*tx - ec->tx_power[0]) >> 3);
443 ec->rx_power[1] += ((rx*rx - ec->rx_power[1]) >> 6);
444 ec->rx_power[0] += ((rx*rx - ec->rx_power[0]) >> 3);
445 ec->clean_rx_power += ((clean_rx*clean_rx - ec->clean_rx_power) >> 6);
446
447 score = 0;
448 /* If there is very little being transmitted, any attempt to train is
449 futile. We would either be training on the far end's noise or signal,
450 the channel's own noise, or our noise. Either way, this is hardly good
451 training, so don't do it (avoid trouble). */
452 if (ec->tx_power[0] > MIN_TX_POWER_FOR_ADAPTION)
453 {
454 /* If the received power is very low, either we are sending very little or
455 we are already well adapted. There is little point in trying to improve
456 the adaption under these circumstances, so don't do it (reduce the
457 compute load). */
458 if (ec->tx_power[1] > ec->rx_power[0])
459 {
460 /* There is no (or little) far-end speech. */
461 if (ec->nonupdate_dwell == 0)
462 {
463 if (++ec->narrowband_count >= 160)
464 {
465 ec->narrowband_count = 0;
466 score = narrowband_detect(ec);
467 printf("Do the narrowband test %d at %d\n", score, ec->curr_pos);
468 if (score > 6)
469 {
470 if (ec->narrowband_score == 0)
471 memcpy(ec->fir_taps16[3], ec->fir_taps16[(ec->tap_set + 1)%3], ec->taps*sizeof(int16_t));
472 ec->narrowband_score += score;
473 }
474 else
475 {
476 if (ec->narrowband_score > 200)
477 {
478 printf("Revert to %d at %d\n", (ec->tap_set + 1)%3, sample_no);
479 memcpy(ec->fir_taps16[ec->tap_set], ec->fir_taps16[3], ec->taps*sizeof(int16_t));
480 memcpy(ec->fir_taps16[(ec->tap_set - 1)%3], ec->fir_taps16[3], ec->taps*sizeof(int16_t));
481 for (i = 0; i < ec->taps; i++)
482 ec->fir_taps32[i] = ec->fir_taps16[3][i] << 15;
483 ec->tap_rotate_counter = 1600;
484 }
485 ec->narrowband_score = 0;
486 }
487 }
488 ec->dtd_onset = false;
489 if (--ec->tap_rotate_counter <= 0)
490 {
491 printf("Rotate to %d at %d\n", ec->tap_set, sample_no);
492 ec->tap_rotate_counter = 1600;
493 ec->tap_set++;
494 if (ec->tap_set > 2)
495 ec->tap_set = 0;
496 ec->fir_state.coeffs = ec->fir_taps16[ec->tap_set];
497 }
498 /* ... and we are not in the dwell time from previous speech. */
499 if ((ec->adaption_mode & ECHO_CAN_USE_ADAPTION) && ec->narrowband_score == 0)
500 {
501 //nsuppr = saturate16((clean_rx << 16)/ec->tx_power[1]);
502 //nsuppr = clean_rx/ec->tx_power[1];
503 /* If a sudden surge in signal level (e.g. the onset of a tone
504 burst) cause an abnormally high instantaneous to average
505 signal power ratio, we could kick the adaption badly in the
506 wrong direction. This is because the tx_power takes too long
507 to react and rise. We need to stop too rapid adaption to the
508 new signal. We normalise to a value derived from the
509 instantaneous signal if it exceeds the peak by too much. */
510 nsuppr = clean_rx;
511 /* Divide isn't very quick, but the "where is the top bit" and shift
512 instructions are single cycle. */
513 if (tx > 4*ec->tx_power[3])
514 i = top_bit(tx) - 8;
515 else
516 i = top_bit(ec->tx_power[3]) - 8;
517 if (i > 0)
518 nsuppr >>= i;
519 lms_adapt(ec, nsuppr);
520 }
521 }
522 //printf("%10d %10d %10d %10d %10d\n", rx, clean_rx, nsuppr, ec->tx_power[1], ec->rx_power[1]);
523 //printf("%.4f\n", (float) ec->rx_power[1]/(float) ec->clean_rx_power);
524 }
525 else
526 {
527 if (!ec->dtd_onset)
528 {
529 printf("Revert to %d at %d\n", (ec->tap_set + 1)%3, sample_no);
530 memcpy(ec->fir_taps16[ec->tap_set], ec->fir_taps16[(ec->tap_set + 1)%3], ec->taps*sizeof(int16_t));
531 memcpy(ec->fir_taps16[(ec->tap_set - 1)%3], ec->fir_taps16[(ec->tap_set + 1)%3], ec->taps*sizeof(int16_t));
532 for (i = 0; i < ec->taps; i++)
533 ec->fir_taps32[i] = ec->fir_taps16[(ec->tap_set + 1)%3][i] << 15;
534 ec->tap_rotate_counter = 1600;
535 ec->dtd_onset = true;
536 }
537 ec->nonupdate_dwell = NONUPDATE_DWELL_TIME;
538 }
539 }
540
541 if (ec->rx_power[1])
542 ec->vad = (8000*ec->clean_rx_power)/ec->rx_power[1];
543 else
544 ec->vad = 0;
545 if (ec->rx_power[1] > 2048*2048 && ec->clean_rx_power > 4*ec->rx_power[1])
546 {
547 /* The EC seems to be making things worse, instead of better. Zap it! */
548 memset(ec->fir_taps32, 0, ec->taps*sizeof(int32_t));
549 for (i = 0; i < 4; i++)
550 memset(ec->fir_taps16[i], 0, ec->taps*sizeof(int16_t));
551 }
552
553 #if defined(XYZZY)
554 if ((ec->adaption_mode & ECHO_CAN_USE_SUPPRESSOR))
555 {
556 ec->supp_test1 += (ec->fir_state.history[ec->curr_pos] - ec->fir_state.history[(ec->curr_pos - 7) & ec->tap_mask]);
557 ec->supp_test2 += (ec->fir_state.history[(ec->curr_pos - 24) & ec->tap_mask] - ec->fir_state.history[(ec->curr_pos - 31) & ec->tap_mask]);
558 if (ec->supp_test1 > 42 && ec->supp_test2 > 42)
559 supp_change = 25;
560 else
561 supp_change = 50;
562 supp = supp_change + k1*ec->supp1 + k2*ec->supp2;
563 ec->supp2 = ec->supp1;
564 ec->supp1 = supp;
565 clean_rx *= (1 - supp);
566 }
567 #endif
568
569 if ((ec->adaption_mode & ECHO_CAN_USE_NLP))
570 {
571 /* Non-linear processor - a fancy way to say "zap small signals, to avoid
572 residual echo due to (uLaw/ALaw) non-linearity in the channel.". */
573 if (ec->rx_power[1] < 30000000)
574 {
575 if (!ec->cng)
576 {
577 ec->cng_level = ec->clean_rx_power;
578 ec->cng = true;
579 }
580 if ((ec->adaption_mode & ECHO_CAN_USE_CNG))
581 {
582 /* Very elementary comfort noise generation */
583 /* Just random numbers rolled off very vaguely Hoth-like */
584 ec->cng_rndnum = 1664525U*ec->cng_rndnum + 1013904223U;
585 ec->cng_filter = ((ec->cng_rndnum & 0xFFFF) - 32768 + 5*ec->cng_filter) >> 3;
586 clean_rx = (ec->cng_filter*ec->cng_level) >> 17;
587 /* TODO: A better CNG, with more accurate (tracking) spectral shaping! */
588 }
589 else
590 {
591 clean_rx = 0;
592 }
593 //clean_rx = -16000;
594 }
595 else
596 {
597 ec->cng = false;
598 }
599 }
600 else
601 {
602 ec->cng = false;
603 }
604
605 printf("Narrowband score %4d %5d at %d\n", ec->narrowband_score, score, sample_no);
606 /* Roll around the rolling buffer */
607 if (ec->curr_pos <= 0)
608 ec->curr_pos = ec->taps;
609 ec->curr_pos--;
610 return (int16_t) clean_rx;
611 }
612 /*- End of function --------------------------------------------------------*/
613
614 SPAN_DECLARE(int16_t) echo_can_hpf_tx(echo_can_state_t *ec, int16_t tx)
615 {
616 if (ec->adaption_mode & ECHO_CAN_USE_TX_HPF)
617 tx = echo_can_hpf(ec->tx_hpf, tx);
618 return tx;
619 }
620 /*- End of function --------------------------------------------------------*/
621 /*- End of file ------------------------------------------------------------*/
622