Skip to content

Instantly share code, notes, and snippets.

@maurice2k
Last active April 19, 2018 15:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maurice2k/5b25c1dbf528a398736d08e52989cab9 to your computer and use it in GitHub Desktop.
Save maurice2k/5b25c1dbf528a398736d08e52989cab9 to your computer and use it in GitHub Desktop.
Fixing Asterisk talk detection
diff --git a/funcs/func_talkdetect.c b/funcs/func_talkdetect.c
index 5c7f41ab39..ddf4eab5cc 100644
--- a/funcs/func_talkdetect.c
+++ b/funcs/func_talkdetect.c
@@ -126,6 +126,8 @@ struct talk_detect_params {
int talking;
/*! The time the current burst of talking started */
struct timeval talking_start;
+ /*! Whether we triggered a talking event */
+ int talking_event_triggered;
/*! The DSP used to do the heavy lifting */
struct ast_dsp *dsp;
};
@@ -159,7 +161,8 @@ static const struct ast_datastore_info talk_detect_datastore = {
static int talk_detect_audiohook_cb(struct ast_audiohook *audiohook, struct ast_channel *chan, struct ast_frame *frame, enum ast_audiohook_direction direction)
{
int total_silence;
- int update_talking = 0;
+ int total_talking;
+ int trigger_event = 0;
struct ast_datastore *datastore;
struct talk_detect_params *td_params;
struct stasis_message *message;
@@ -182,21 +185,49 @@ static int talk_detect_audiohook_cb(struct ast_audiohook *audiohook, struct ast_
td_params = datastore->data;
ast_dsp_silence(td_params->dsp, frame, &total_silence);
+ ast_dsp_noise(td_params->dsp, frame, &total_talking);
- if (total_silence < td_params->dsp_silence_threshold) {
- if (!td_params->talking) {
- update_talking = 1;
+ //ast_verb(4, "talkdetect: total_talking: %6d, total_silence: %6d (talking_threshold: %4d, silence_threshold: %4d)\n", total_talking, total_silence, td_params->dsp_talking_threshold, td_params->dsp_silence_threshold);
+
+ if (total_silence > td_params->dsp_silence_threshold) {
+
+ // there has been silence longer than the threshold
+
+ // if there was noise/talking before, see if we have already triggered the
+ // talking event, which means we now have to trigger the silence event
+ if (td_params->talking == 1) {
+ td_params->talking = 0;
+ trigger_event = td_params->talking_event_triggered;
+ td_params->talking_event_triggered = 0;
+ }
+
+ } else if (total_talking > 0) {
+
+ int64_t talking_period_ms;
+
+ // we are below the silence threshold but have talking time > 0, so there seems
+ // to be talking right now or there has been some talking a few milliseconds ago
+
+ // if there was no talking until this moment, let's start the timer.
+ // we're *NOT* triggering the event right now but wait for some more talking
+ // to get past the dsp_talking_threshold
+ if (td_params->talking == 0) {
+ td_params->talking = 1;
td_params->talking_start = ast_tvnow();
}
- td_params->talking = 1;
- } else {
- if (td_params->talking) {
- update_talking = 1;
+
+ talking_period_ms = ast_tvdiff_ms(ast_tvnow(), td_params->talking_start);
+
+ if (talking_period_ms > td_params->dsp_talking_threshold &&
+ td_params->talking_event_triggered == 0) {
+
+ td_params->talking_event_triggered = 1;
+ trigger_event = td_params->talking_event_triggered;
}
- td_params->talking = 0;
+
}
- if (update_talking) {
+ if (trigger_event) {
struct ast_json *blob = NULL;
if (!td_params->talking) {
@@ -301,7 +332,8 @@ static int set_talk_detect(struct ast_channel *chan, int dsp_silence_threshold,
td_params->dsp_talking_threshold = dsp_talking_threshold;
td_params->dsp_silence_threshold = dsp_silence_threshold;
- ast_dsp_set_threshold(td_params->dsp, td_params->dsp_talking_threshold);
+ ast_verb(4, "Setting dsp_threshold: %d\n", ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE));
+ ast_dsp_set_threshold(td_params->dsp, ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE));
return 0;
}
@@ -363,6 +395,8 @@ static int talk_detect_fn_write(struct ast_channel *chan, const char *function,
}
}
+ ast_verb(4, "Setting dsp_silence_threshold: %d, dsp_talking_threshold: %d\n", dsp_silence_threshold, dsp_talking_threshold);
+
res = set_talk_detect(chan, dsp_silence_threshold, dsp_talking_threshold);
} else if (!strcasecmp(data, "remove")) {
res = remove_talk_detect(chan);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment