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