-
-
Save maurice2k/5b25c1dbf528a398736d08e52989cab9 to your computer and use it in GitHub Desktop.
Fixing Asterisk talk detection
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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