|
|
|
@ -60,6 +60,7 @@
|
|
|
|
|
#include <osmocom/core/talloc.h>
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
|
|
#include "echo_suppress.h"
|
|
|
|
@ -70,15 +71,19 @@
|
|
|
|
|
#define SUPPRESS_THRESHOLD -31.0
|
|
|
|
|
#define RELEASE_SUPPRESS -31.0
|
|
|
|
|
#define INSERTION_LOSS 6.0
|
|
|
|
|
#define DT_MIN_LEVEL_DB -20
|
|
|
|
|
#define DT_MAX_OFFSET_DB 0.2
|
|
|
|
|
|
|
|
|
|
#define SUPPRESS_OPERATE 0.000
|
|
|
|
|
#define SUPPRESS_HANGOVER 0.050
|
|
|
|
|
#define BREAK_IN_OPERATE 0.030
|
|
|
|
|
#define BREAK_IN_HANGOVER 0.050
|
|
|
|
|
#define DT_INTERVAL 0.250
|
|
|
|
|
|
|
|
|
|
#define LP_FREQUENCY 3400.0
|
|
|
|
|
#define HP_FREQUENCY 500.0
|
|
|
|
|
#define ENV_FREQUENCY 500.0
|
|
|
|
|
#define DT_ENV_FREQUENCY 10.0
|
|
|
|
|
|
|
|
|
|
//#define DEBUG_ES
|
|
|
|
|
|
|
|
|
@ -181,6 +186,9 @@ echo_sup_state_t *echo_sup_create(void *ctx, int samplerate)
|
|
|
|
|
iir_highpass_init(&es->hp_receive, HP_FREQUENCY, samplerate);
|
|
|
|
|
iir_lowpass_init(&es->env_send, ENV_FREQUENCY, samplerate);
|
|
|
|
|
iir_lowpass_init(&es->env_receive, ENV_FREQUENCY, samplerate);
|
|
|
|
|
iir_lowpass_init(&es->dt_receive, DT_ENV_FREQUENCY, samplerate);
|
|
|
|
|
|
|
|
|
|
es->dt_interval = floor(DT_INTERVAL * (double)samplerate);
|
|
|
|
|
|
|
|
|
|
return es;
|
|
|
|
|
}
|
|
|
|
@ -194,7 +202,7 @@ void echo_sup_free(echo_sup_state_t *es)
|
|
|
|
|
/* tx is what we sent to user interface, aka 'receive' */
|
|
|
|
|
int16_t echo_sup_update(echo_sup_state_t *es, int16_t tx, int16_t rx)
|
|
|
|
|
{
|
|
|
|
|
float send, receive;
|
|
|
|
|
float send, receive, dt, offset;
|
|
|
|
|
|
|
|
|
|
/* convert from integer samples to float (@ 0 dBm scale) */
|
|
|
|
|
receive = (float)tx / 23196.0; /* towards user interface */
|
|
|
|
@ -208,11 +216,44 @@ int16_t echo_sup_update(echo_sup_state_t *es, int16_t tx, int16_t rx)
|
|
|
|
|
|
|
|
|
|
/* get absolute value (rectifying with 3 dB gain) */
|
|
|
|
|
send = fabsf(send) * 1.4142136;
|
|
|
|
|
receive = fabsf(receive) * 1.4142136;
|
|
|
|
|
receive = dt = fabsf(receive) * 1.4142136;
|
|
|
|
|
|
|
|
|
|
/* filter envelope */
|
|
|
|
|
iir_process(&es->env_send, &send, 1);
|
|
|
|
|
iir_process(&es->env_receive, &receive, 1);
|
|
|
|
|
iir_process(&es->dt_receive, &dt, 1);
|
|
|
|
|
|
|
|
|
|
/* detect dial tone and do not suppress while it is detected */
|
|
|
|
|
if (++es->dt_timer == es->dt_interval) {
|
|
|
|
|
#ifdef DEBUG_ES
|
|
|
|
|
printf("dt_level=%.3f dt_offset=%.3f*\n", level2db(es->dt_level), level2db(es->dt_offset));
|
|
|
|
|
#endif
|
|
|
|
|
if (level2db(es->dt_level) > DT_MIN_LEVEL_DB && level2db(es->dt_offset) < DT_MAX_OFFSET_DB) {
|
|
|
|
|
if (!es->dt_disable) {
|
|
|
|
|
#ifdef DEBUG_ES
|
|
|
|
|
printf("Detected dial tone, disabling suppressor\n");
|
|
|
|
|
#endif
|
|
|
|
|
es->dt_disable = true;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (es->dt_disable) {
|
|
|
|
|
#ifdef DEBUG_ES
|
|
|
|
|
printf("dial tone ceases, enabling suppressor\n");
|
|
|
|
|
#endif
|
|
|
|
|
es->dt_disable = false;
|
|
|
|
|
es->state = SUP_STATE_SILENCE;
|
|
|
|
|
es->timer = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
es->dt_timer = 0;
|
|
|
|
|
es->dt_level = dt;
|
|
|
|
|
es->dt_offset = 0.0;
|
|
|
|
|
}
|
|
|
|
|
offset = fabsf(es->dt_level / dt);
|
|
|
|
|
if (offset > es->dt_offset)
|
|
|
|
|
es->dt_offset = offset;
|
|
|
|
|
if (es->dt_disable)
|
|
|
|
|
return rx;
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_ES
|
|
|
|
|
static int debug_interval = 0;
|
|
|
|
|