diff options
Diffstat (limited to 'apps/app_talkdetect.c')
-rw-r--r-- | apps/app_talkdetect.c | 205 |
1 files changed, 102 insertions, 103 deletions
diff --git a/apps/app_talkdetect.c b/apps/app_talkdetect.c index 9e4d2a4ee..0438111c5 100644 --- a/apps/app_talkdetect.c +++ b/apps/app_talkdetect.c @@ -43,6 +43,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/utils.h" #include "asterisk/dsp.h" #include "asterisk/options.h" +#include "asterisk/app.h" static char *app = "BackgroundDetect"; @@ -64,17 +65,21 @@ static int background_detect_exec(struct ast_channel *chan, void *data) { int res = 0; char *tmp; - char *options; - char *stringp; struct ast_frame *fr; - int notsilent=0; + int notsilent = 0; struct timeval start = { 0, 0}; int sil = 1000; int min = 100; int max = -1; int x; int origrformat=0; - struct ast_dsp *dsp; + 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); + ); if (ast_strlen_zero(data)) { ast_log(LOG_WARNING, "BackgroundDetect requires an argument (filename)\n"); @@ -82,118 +87,112 @@ static int background_detect_exec(struct ast_channel *chan, void *data) } tmp = ast_strdupa(data); + AST_STANDARD_APP_ARGS(args, tmp); - stringp=tmp; - strsep(&stringp, "|"); - options = strsep(&stringp, "|"); - if (options) { - if ((sscanf(options, "%d", &x) == 1) && (x > 0)) - sil = x; - options = strsep(&stringp, "|"); - if (options) { - if ((sscanf(options, "%d", &x) == 1) && (x > 0)) - min = x; - options = strsep(&stringp, "|"); - if (options) { - if ((sscanf(options, "%d", &x) == 1) && (x > 0)) - max = x; - } + if ((sscanf(args.silence, "%d", &x) == 1) && (x > 0)) + sil = x; + if ((sscanf(args.min, "%d", &x) == 1) && (x > 0)) + min = x; + if ((sscanf(args.max, "%d", &x) == 1) && (x > 0)) + max = x; + + ast_debug(1, "Preparing detect of '%s', sil=%d, min=%d, max=%d\n", args.filename, sil, min, max); + do { + if (chan->_state != AST_STATE_UP) { + if ((res = ast_answer(chan))) + break; } - } - ast_debug(1, "Preparing detect of '%s', sil=%d,min=%d,max=%d\n", tmp, sil, min, max); - if (chan->_state != AST_STATE_UP) { - /* Otherwise answer unless we're supposed to send this while on-hook */ - res = ast_answer(chan); - } - if (!res) { + origrformat = chan->readformat; - if ((res = ast_set_read_format(chan, AST_FORMAT_SLINEAR))) + if ((ast_set_read_format(chan, AST_FORMAT_SLINEAR))) { ast_log(LOG_WARNING, "Unable to set read format to linear!\n"); - } - if (!(dsp = ast_dsp_new())) { - ast_log(LOG_WARNING, "Unable to allocate DSP!\n"); - res = -1; - } - if (!res) { + res = -1; + break; + } + + if (!(dsp = ast_dsp_new())) { + ast_log(LOG_WARNING, "Unable to allocate DSP!\n"); + res = -1; + break; + } ast_stopstream(chan); - res = ast_streamfile(chan, tmp, chan->language); - if (!res) { - while(chan->stream) { - res = ast_sched_wait(chan->sched); - if ((res < 0) && !chan->timingfunc) { - res = 0; - break; - } - if (res < 0) - res = 1000; - res = ast_waitfor(chan, res); - if (res < 0) { - ast_log(LOG_WARNING, "Waitfor failed on %s\n", chan->name); + if (ast_streamfile(chan, tmp, chan->language)) { + ast_log(LOG_WARNING, "ast_streamfile failed on %s for %s\n", chan->name, (char *)data); + break; + } + + while (chan->stream) { + res = ast_sched_wait(chan->sched); + if ((res < 0) && !chan->timingfunc) { + res = 0; + break; + } + 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 (!fr) { + res = -1; break; - } else if (res > 0) { - fr = ast_read(chan); - if (!fr) { - res = -1; + } else if (fr->frametype == AST_FRAME_DTMF) { + char t[2]; + t[0] = fr->subclass; + t[1] = '\0'; + if (ast_canmatch_extension(chan, chan->context, t, 1, chan->cid.cid_num)) { + /* They entered a valid extension, or might be anyhow */ + res = fr->subclass; + ast_frfree(fr); break; - } else if (fr->frametype == AST_FRAME_DTMF) { - char t[2]; - t[0] = fr->subclass; - t[1] = '\0'; - if (ast_canmatch_extension(chan, chan->context, t, 1, chan->cid.cid_num)) { - /* They entered a valid extension, or might be anyhow */ - res = fr->subclass; - ast_frfree(fr); - break; - } - } else if ((fr->frametype == AST_FRAME_VOICE) && (fr->subclass == AST_FORMAT_SLINEAR)) { - int totalsilence; - int ms; - res = ast_dsp_silence(dsp, fr, &totalsilence); - if (res && (totalsilence > sil)) { - /* We've been quiet a little while */ - if (notsilent) { - /* We had heard some talking */ - ms = ast_tvdiff_ms(ast_tvnow(), start); - ms -= sil; - if (ms < 0) - ms = 0; - if ((ms > min) && ((max < 0) || (ms < max))) { - char ms_str[10]; - ast_debug(1, "Found qualified token of %d ms\n", ms); - - /* Save detected talk time (in milliseconds) */ - sprintf(ms_str, "%d", ms ); - pbx_builtin_setvar_helper(chan, "TALK_DETECTED", ms_str); - - ast_goto_if_exists(chan, chan->context, "talk", 1); - res = 0; - ast_frfree(fr); - break; - } else { - ast_debug(1, "Found unqualified token of %d ms\n", ms); - } - notsilent = 0; - } - } else { - if (!notsilent) { - /* Heard some audio, mark the begining of the token */ - start = ast_tvnow(); - ast_debug(1, "Start of voice token!\n"); - notsilent = 1; + } + } else if ((fr->frametype == AST_FRAME_VOICE) && (fr->subclass == AST_FORMAT_SLINEAR)) { + int totalsilence; + int ms; + res = ast_dsp_silence(dsp, fr, &totalsilence); + if (res && (totalsilence > sil)) { + /* We've been quiet a little while */ + if (notsilent) { + /* We had heard some talking */ + ms = ast_tvdiff_ms(ast_tvnow(), start); + ms -= sil; + if (ms < 0) + ms = 0; + if ((ms > min) && ((max < 0) || (ms < max))) { + char ms_str[10]; + ast_debug(1, "Found qualified token of %d ms\n", ms); + + /* Save detected talk time (in milliseconds) */ + sprintf(ms_str, "%d", ms ); + pbx_builtin_setvar_helper(chan, "TALK_DETECTED", ms_str); + + ast_goto_if_exists(chan, chan->context, "talk", 1); + res = 0; + ast_frfree(fr); + break; + } else { + ast_debug(1, "Found unqualified token of %d ms\n", ms); } + notsilent = 0; + } + } else { + if (!notsilent) { + /* Heard some audio, mark the begining of the token */ + start = ast_tvnow(); + ast_debug(1, "Start of voice token!\n"); + notsilent = 1; } - } - ast_frfree(fr); } - ast_sched_runq(chan->sched); + ast_frfree(fr); } - ast_stopstream(chan); - } else { - ast_log(LOG_WARNING, "ast_streamfile failed on %s for %s\n", chan->name, (char *)data); - res = 0; + ast_sched_runq(chan->sched); } - } + ast_stopstream(chan); + } while (0); + if (res > -1) { if (origrformat && ast_set_read_format(chan, origrformat)) { ast_log(LOG_WARNING, "Failed to restore read format for %s to %s\n", |