func_talkdetect.c: Fix logical errors in silence detection.

There are 3 separate changes here:

1. The documentation erroneously stated that the dsp_talking_threshold
   argument was a number of milliseconds when it is actually an energy
   level used by the DSP code to classify talking vs. silence.

2. Fixes a copy paste error in the argument handling code.

3. Don't erroneously switch to the talking state if we aren't actively
   handling a frame we've classified as talking.

Patch inspired by one provided by Moritz Fain (License #6961).

ASTERISK-27816 #close

Change-Id: I5953fd570b98b49c41cee55bfe3b941753fb2511
This commit is contained in:
Sean Bright
2021-10-14 15:38:33 -04:00
committed by Friendly Automation
parent e3466893e9
commit 8c2720e540

View File

@@ -56,10 +56,20 @@
parameters. Can be called multiple times to change parameters parameters. Can be called multiple times to change parameters
on a channel with talk detection already enabled.</para> on a channel with talk detection already enabled.</para>
<argument name="dsp_silence_threshold" required="false"> <argument name="dsp_silence_threshold" required="false">
<para>The time in milliseconds before which a user is considered silent.</para> <para>The time in milliseconds of sound falling below the
<replaceable>dsp_talking_threshold</replaceable> option when
a user is considered to stop talking. The default value is
2500.</para>
</argument> </argument>
<argument name="dsp_talking_threshold" required="false"> <argument name="dsp_talking_threshold" required="false">
<para>The time in milliseconds after which a user is considered talking.</para> <para>The minimum average magnitude per sample in a frame
for the DSP to consider talking/noise present. A value below
this level is considered silence. If not specified, the
value comes from the <filename>dsp.conf</filename>
<replaceable>silencethreshold</replaceable> option or 256
if <filename>dsp.conf</filename> doesn't exist or the
<replaceable>silencethreshold</replaceable> option is not
set.</para>
</argument> </argument>
</option> </option>
</optionlist> </optionlist>
@@ -159,6 +169,7 @@ 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) 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 total_silence;
int is_talking;
int update_talking = 0; int update_talking = 0;
struct ast_datastore *datastore; struct ast_datastore *datastore;
struct talk_detect_params *td_params; struct talk_detect_params *td_params;
@@ -181,15 +192,14 @@ static int talk_detect_audiohook_cb(struct ast_audiohook *audiohook, struct ast_
} }
td_params = datastore->data; td_params = datastore->data;
ast_dsp_silence(td_params->dsp, frame, &total_silence); is_talking = !ast_dsp_silence(td_params->dsp, frame, &total_silence);
if (is_talking) {
if (total_silence < td_params->dsp_silence_threshold) {
if (!td_params->talking) { if (!td_params->talking) {
update_talking = 1; update_talking = 1;
td_params->talking_start = ast_tvnow(); td_params->talking_start = ast_tvnow();
} }
td_params->talking = 1; td_params->talking = 1;
} else { } else if (total_silence >= td_params->dsp_silence_threshold) {
if (td_params->talking) { if (td_params->talking) {
update_talking = 1; update_talking = 1;
} }
@@ -357,7 +367,7 @@ static int talk_detect_fn_write(struct ast_channel *chan, const char *function,
if (dsp_talking_threshold < 1) { if (dsp_talking_threshold < 1) {
ast_log(AST_LOG_WARNING, "Invalid value %d for dsp_talking_threshold\n", ast_log(AST_LOG_WARNING, "Invalid value %d for dsp_talking_threshold\n",
dsp_silence_threshold); dsp_talking_threshold);
return -1; return -1;
} }
} }