Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /* SPDX-License-Identifier: GPL-2.0-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * SpanDSP - a series of DSP components for telephony
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * echo.c - A line echo canceller.  This code is being developed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *          against and partially complies with G168.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * Written by Steve Underwood <steveu@coppice.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *         and David Rowe <david_at_rowetel_dot_com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * Copyright (C) 2001 Steve Underwood and 2007 David Rowe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #ifndef __ECHO_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #define __ECHO_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) Line echo cancellation for voice
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) What does it do?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) This module aims to provide G.168-2002 compliant echo cancellation, to remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) electrical echoes (e.g. from 2-4 wire hybrids) from voice calls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) How does it work?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) The heart of the echo cancellor is FIR filter. This is adapted to match the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) echo impulse response of the telephone line. It must be long enough to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) adequately cover the duration of that impulse response. The signal transmitted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) to the telephone line is passed through the FIR filter. Once the FIR is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) properly adapted, the resulting output is an estimate of the echo signal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) received from the line. This is subtracted from the received signal. The result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) is an estimate of the signal which originated at the far end of the line, free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) from echos of our own transmitted signal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) The least mean squares (LMS) algorithm is attributed to Widrow and Hoff, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) was introduced in 1960. It is the commonest form of filter adaption used in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) things like modem line equalisers and line echo cancellers. There it works very
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) well.  However, it only works well for signals of constant amplitude. It works
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) very poorly for things like speech echo cancellation, where the signal level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) varies widely.  This is quite easy to fix. If the signal level is normalised -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) similar to applying AGC - LMS can work as well for a signal of varying
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) amplitude as it does for a modem signal. This normalised least mean squares
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) (NLMS) algorithm is the commonest one used for speech echo cancellation. Many
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) other algorithms exist - e.g. RLS (essentially the same as Kalman filtering),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) FAP, etc. Some perform significantly better than NLMS.  However, factors such
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) as computational complexity and patents favour the use of NLMS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) A simple refinement to NLMS can improve its performance with speech. NLMS tends
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) to adapt best to the strongest parts of a signal. If the signal is white noise,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) the NLMS algorithm works very well. However, speech has more low frequency than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) high frequency content. Pre-whitening (i.e. filtering the signal to flatten its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) spectrum) the echo signal improves the adapt rate for speech, and ensures the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) final residual signal is not heavily biased towards high frequencies. A very
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) low complexity filter is adequate for this, so pre-whitening adds little to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) compute requirements of the echo canceller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) An FIR filter adapted using pre-whitened NLMS performs well, provided certain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) conditions are met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)     - The transmitted signal has poor self-correlation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)     - There is no signal being generated within the environment being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)       cancelled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) The difficulty is that neither of these can be guaranteed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) If the adaption is performed while transmitting noise (or something fairly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) noise like, such as voice) the adaption works very well. If the adaption is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) performed while transmitting something highly correlative (typically narrow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) band energy such as signalling tones or DTMF), the adaption can go seriously
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) wrong. The reason is there is only one solution for the adaption on a near
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) random signal - the impulse response of the line. For a repetitive signal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) there are any number of solutions which converge the adaption, and nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) guides the adaption to choose the generalised one. Allowing an untrained
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) canceller to converge on this kind of narrowband energy probably a good thing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) since at least it cancels the tones. Allowing a well converged canceller to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) continue converging on such energy is just a way to ruin its generalised
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) adaption. A narrowband detector is needed, so adapation can be suspended at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) appropriate times.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) The adaption process is based on trying to eliminate the received signal. When
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) there is any signal from within the environment being cancelled it may upset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) the adaption process. Similarly, if the signal we are transmitting is small,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) noise may dominate and disturb the adaption process. If we can ensure that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) adaption is only performed when we are transmitting a significant signal level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) and the environment is not, things will be OK. Clearly, it is easy to tell when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) we are sending a significant signal. Telling, if the environment is generating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) a significant signal, and doing it with sufficient speed that the adaption will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) not have diverged too much more we stop it, is a little harder.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) The key problem in detecting when the environment is sourcing significant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) energy is that we must do this very quickly. Given a reasonably long sample of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) the received signal, there are a number of strategies which may be used to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) assess whether that signal contains a strong far end component. However, by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) time that assessment is complete the far end signal will have already caused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) major mis-convergence in the adaption process. An assessment algorithm is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) needed which produces a fairly accurate result from a very short burst of far
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) end energy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) How do I use it?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) The echo cancellor processes both the transmit and receive streams sample by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) sample. The processing function is not declared inline. Unfortunately,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) cancellation requires many operations per sample, so the call overhead is only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) a minor burden.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #include "fir.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #include "oslec.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)     G.168 echo canceller descriptor. This defines the working state for a line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)     echo canceller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct oslec_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	int16_t tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	int16_t rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	int16_t clean;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	int16_t clean_nlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	int nonupdate_dwell;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	int curr_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	int taps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	int log2taps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	int adaption_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	int cond_met;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	int32_t pstates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	int16_t adapt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	int32_t factor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	int16_t shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	/* Average levels and averaging filter states */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	int ltxacc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	int lrxacc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	int lcleanacc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	int lclean_bgacc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	int ltx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	int lrx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	int lclean;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	int lclean_bg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	int lbgn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	int lbgn_acc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	int lbgn_upper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	int lbgn_upper_acc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	/* foreground and background filter states */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	struct fir16_state_t fir_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	struct fir16_state_t fir_state_bg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	int16_t *fir_taps16[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	/* DC blocking filter states */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	int tx_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	int tx_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	int rx_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	int rx_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	/* optional High Pass Filter states */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	int32_t xvtx[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	int32_t yvtx[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	int32_t xvrx[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	int32_t yvrx[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	/* Parameters for the optional Hoth noise generator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	int cng_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	int cng_rndnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	int cng_filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	/* snapshot sample of coeffs used for development */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	int16_t *snapshot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) #endif /* __ECHO_H */