Add dial tone detection to disable echo suppressor
This commit is contained in:
parent
71d73d9885
commit
a8ec7578c7
|
@ -60,6 +60,7 @@
|
||||||
#include <osmocom/core/talloc.h>
|
#include <osmocom/core/talloc.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include "echo_suppress.h"
|
#include "echo_suppress.h"
|
||||||
|
@ -70,15 +71,19 @@
|
||||||
#define SUPPRESS_THRESHOLD -31.0
|
#define SUPPRESS_THRESHOLD -31.0
|
||||||
#define RELEASE_SUPPRESS -31.0
|
#define RELEASE_SUPPRESS -31.0
|
||||||
#define INSERTION_LOSS 6.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_OPERATE 0.000
|
||||||
#define SUPPRESS_HANGOVER 0.050
|
#define SUPPRESS_HANGOVER 0.050
|
||||||
#define BREAK_IN_OPERATE 0.030
|
#define BREAK_IN_OPERATE 0.030
|
||||||
#define BREAK_IN_HANGOVER 0.050
|
#define BREAK_IN_HANGOVER 0.050
|
||||||
|
#define DT_INTERVAL 0.250
|
||||||
|
|
||||||
#define LP_FREQUENCY 3400.0
|
#define LP_FREQUENCY 3400.0
|
||||||
#define HP_FREQUENCY 500.0
|
#define HP_FREQUENCY 500.0
|
||||||
#define ENV_FREQUENCY 500.0
|
#define ENV_FREQUENCY 500.0
|
||||||
|
#define DT_ENV_FREQUENCY 10.0
|
||||||
|
|
||||||
//#define DEBUG_ES
|
//#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_highpass_init(&es->hp_receive, HP_FREQUENCY, samplerate);
|
||||||
iir_lowpass_init(&es->env_send, ENV_FREQUENCY, samplerate);
|
iir_lowpass_init(&es->env_send, ENV_FREQUENCY, samplerate);
|
||||||
iir_lowpass_init(&es->env_receive, 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;
|
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' */
|
/* 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)
|
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) */
|
/* convert from integer samples to float (@ 0 dBm scale) */
|
||||||
receive = (float)tx / 23196.0; /* towards user interface */
|
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) */
|
/* get absolute value (rectifying with 3 dB gain) */
|
||||||
send = fabsf(send) * 1.4142136;
|
send = fabsf(send) * 1.4142136;
|
||||||
receive = fabsf(receive) * 1.4142136;
|
receive = dt = fabsf(receive) * 1.4142136;
|
||||||
|
|
||||||
/* filter envelope */
|
/* filter envelope */
|
||||||
iir_process(&es->env_send, &send, 1);
|
iir_process(&es->env_send, &send, 1);
|
||||||
iir_process(&es->env_receive, &receive, 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
|
#ifdef DEBUG_ES
|
||||||
static int debug_interval = 0;
|
static int debug_interval = 0;
|
||||||
|
|
|
@ -23,6 +23,10 @@ typedef struct echo_sup_state {
|
||||||
iir_filter_t lp_send, lp_receive; /* filter to cut off high frequencies */
|
iir_filter_t lp_send, lp_receive; /* filter to cut off high frequencies */
|
||||||
iir_filter_t hp_send, hp_receive; /* filter to cut off low frequencies */
|
iir_filter_t hp_send, hp_receive; /* filter to cut off low frequencies */
|
||||||
iir_filter_t env_send, env_receive; /* filter to get the envelope after rectifying */
|
iir_filter_t env_send, env_receive; /* filter to get the envelope after rectifying */
|
||||||
|
iir_filter_t dt_receive; /* filter to detect steady tone (dial tone) */
|
||||||
|
int dt_timer, dt_interval; /* timer of dial tone detection interval */
|
||||||
|
float dt_level, dt_offset; /* initial level and max offset during interval */
|
||||||
|
bool dt_disable; /* true if suppressor is disabled, due to dial tone */
|
||||||
} echo_sup_state_t;
|
} echo_sup_state_t;
|
||||||
|
|
||||||
echo_sup_state_t *echo_sup_create(void *ctx, int samplerate);
|
echo_sup_state_t *echo_sup_create(void *ctx, int samplerate);
|
||||||
|
|
Loading…
Reference in New Issue