summaryrefslogtreecommitdiff
path: root/apps/app_talkdetect.c
diff options
context:
space:
mode:
authorTilghman Lesher <tilghman@meg.abyt.es>2008-06-17 21:42:42 +0000
committerTilghman Lesher <tilghman@meg.abyt.es>2008-06-17 21:42:42 +0000
commit9d403c379fcac970210c6d42dbfe4e98b175bccc (patch)
treebf1d54e3370bb8abcfde8ea37a7d8345ec4a16b0 /apps/app_talkdetect.c
parentb0b8bcd3b2b761d35038255bcec5a202e4db00f7 (diff)
Add an option, specifying maximum analysis time for talk detection.
(closes issue #12149) Reported by: davevg Patches: app_talkdetect.c.diff uploaded by davevg (license 209) (Plus a few additional cleanups by moi) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@123544 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'apps/app_talkdetect.c')
-rw-r--r--apps/app_talkdetect.c66
1 files changed, 44 insertions, 22 deletions
diff --git a/apps/app_talkdetect.c b/apps/app_talkdetect.c
index fb862440d..9bc5e84dd 100644
--- a/apps/app_talkdetect.c
+++ b/apps/app_talkdetect.c
@@ -44,15 +44,15 @@ static char *app = "BackgroundDetect";
static char *synopsis = "Background a file with talk detect";
static char *descrip =
-" BackgroundDetect(filename[,sil[,min,[max]]]): Plays back a given\n"
-"filename, waiting for interruption from a given digit (the digit must\n"
-"start the beginning of a valid extension, or it will be ignored).\n"
-"During the playback of the file, audio is monitored in the receive\n"
-"direction, and if a period of non-silence which is greater than 'min' ms\n"
-"yet less than 'max' ms is followed by silence for at least 'sil' ms then\n"
-"the audio playback is aborted and processing jumps to the 'talk' extension\n"
-"if available. If unspecified, sil, min, and max default to 1000, 100, and\n"
-"infinity respectively.\n";
+" BackgroundDetect(<filename>[,<sil>[,<min>[,<max>[,<analysistime>]]]]):\n"
+"Plays back <filename>, waiting for interruption from a given digit (the digit\n"
+"must start the beginning of a valid extension, or it will be ignored). During\n"
+"the playback of the file, audio is monitored in the receive direction, and if\n"
+"a period of non-silence which is greater than <min> ms yet less than <max> ms\n"
+"is followed by silence for at least <sil> ms, which occurs during the first\n"
+"<analysistime> ms, then the audio playback is aborted and processing jumps to\n"
+"the <talk> extension, if available. If unspecified, <sil>, <min>, <max>, and\n"
+"<analysistime> default to 1000, 100, infinity, and infinity respectively.\n";
static int background_detect_exec(struct ast_channel *chan, void *data)
@@ -61,18 +61,22 @@ static int background_detect_exec(struct ast_channel *chan, void *data)
char *tmp;
struct ast_frame *fr;
int notsilent = 0;
- struct timeval start = { 0, 0};
+ struct timeval start = { 0, 0 };
+ struct timeval detection_start = { 0, 0 };
int sil = 1000;
int min = 100;
int max = -1;
+ int analysistime = -1;
+ int continue_analysis = 1;
int x;
- int origrformat=0;
+ int origrformat = 0;
struct ast_dsp *dsp = NULL;
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(filename);
AST_APP_ARG(silence);
AST_APP_ARG(min);
AST_APP_ARG(max);
+ AST_APP_ARG(analysistime);
);
if (ast_strlen_zero(data)) {
@@ -83,18 +87,25 @@ static int background_detect_exec(struct ast_channel *chan, void *data)
tmp = ast_strdupa(data);
AST_STANDARD_APP_ARGS(args, tmp);
- if (!ast_strlen_zero(args.silence) && (sscanf(args.silence, "%d", &x) == 1) && (x > 0))
+ if (!ast_strlen_zero(args.silence) && (sscanf(args.silence, "%d", &x) == 1) && (x > 0)) {
sil = x;
- if (!ast_strlen_zero(args.min) && (sscanf(args.min, "%d", &x) == 1) && (x > 0))
+ }
+ if (!ast_strlen_zero(args.min) && (sscanf(args.min, "%d", &x) == 1) && (x > 0)) {
min = x;
- if (!ast_strlen_zero(args.max) && (sscanf(args.max, "%d", &x) == 1) && (x > 0))
+ }
+ if (!ast_strlen_zero(args.max) && (sscanf(args.max, "%d", &x) == 1) && (x > 0)) {
max = x;
+ }
+ if (!ast_strlen_zero(args.analysistime) && (sscanf(args.analysistime, "%d", &x) == 1) && (x > 0)) {
+ analysistime = x;
+ }
- ast_debug(1, "Preparing detect of '%s', sil=%d, min=%d, max=%d\n", args.filename, sil, min, max);
+ ast_debug(1, "Preparing detect of '%s', sil=%d, min=%d, max=%d, analysistime=%d\n", args.filename, sil, min, max, analysistime);
do {
if (chan->_state != AST_STATE_UP) {
- if ((res = ast_answer(chan)))
+ if ((res = ast_answer(chan))) {
break;
+ }
}
origrformat = chan->readformat;
@@ -114,21 +125,31 @@ static int background_detect_exec(struct ast_channel *chan, void *data)
ast_log(LOG_WARNING, "ast_streamfile failed on %s for %s\n", chan->name, (char *)data);
break;
}
-
+ detection_start = ast_tvnow();
while (chan->stream) {
res = ast_sched_wait(chan->sched);
if ((res < 0) && !chan->timingfunc) {
res = 0;
break;
}
- if (res < 0)
+ if (res < 0) {
res = 1000;
+ }
res = ast_waitfor(chan, res);
if (res < 0) {
ast_log(LOG_WARNING, "Waitfor failed on %s\n", chan->name);
break;
} else if (res > 0) {
fr = ast_read(chan);
+ if (continue_analysis && analysistime >= 0) {
+ /* If we have a limit for the time to analyze voice
+ * frames and the time has not expired */
+ if (ast_tvdiff_ms(ast_tvnow(), detection_start) >= analysistime) {
+ continue_analysis = 0;
+ ast_verb(3, "BackgroundDetect: Talk analysis time complete on %s.\n", chan->name);
+ }
+ }
+
if (!fr) {
res = -1;
break;
@@ -142,7 +163,7 @@ static int background_detect_exec(struct ast_channel *chan, void *data)
ast_frfree(fr);
break;
}
- } else if ((fr->frametype == AST_FRAME_VOICE) && (fr->subclass == AST_FORMAT_SLINEAR)) {
+ } else if ((fr->frametype == AST_FRAME_VOICE) && (fr->subclass == AST_FORMAT_SLINEAR) && continue_analysis) {
int totalsilence;
int ms;
res = ast_dsp_silence(dsp, fr, &totalsilence);
@@ -155,11 +176,11 @@ static int background_detect_exec(struct ast_channel *chan, void *data)
if (ms < 0)
ms = 0;
if ((ms > min) && ((max < 0) || (ms < max))) {
- char ms_str[10];
+ char ms_str[12];
ast_debug(1, "Found qualified token of %d ms\n", ms);
/* Save detected talk time (in milliseconds) */
- sprintf(ms_str, "%d", ms );
+ snprintf(ms_str, sizeof(ms_str), "%d", ms);
pbx_builtin_setvar_helper(chan, "TALK_DETECTED", ms_str);
ast_goto_if_exists(chan, chan->context, "talk", 1);
@@ -193,8 +214,9 @@ static int background_detect_exec(struct ast_channel *chan, void *data)
chan->name, ast_getformatname(origrformat));
}
}
- if (dsp)
+ if (dsp) {
ast_dsp_free(dsp);
+ }
return res;
}