Thu Oct 11 06:47:52 2012

Asterisk developer's documentation


app_talkdetect.c File Reference

Playback a file with audio detect. More...

#include "asterisk.h"
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/translate.h"
#include "asterisk/utils.h"
#include "asterisk/dsp.h"
#include "asterisk/app.h"

Include dependency graph for app_talkdetect.c:

Go to the source code of this file.

Functions

static void __reg_module (void)
static void __unreg_module (void)
static int background_detect_exec (struct ast_channel *chan, void *data)
static int load_module (void)
static int unload_module (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Playback with Talk Detection" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, }
static char * app = "BackgroundDetect"
static struct ast_module_infoast_module_info = &__mod_info


Detailed Description

Playback a file with audio detect.

Author:
Mark Spencer <markster@digium.com>

Definition in file app_talkdetect.c.


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 251 of file app_talkdetect.c.

static void __unreg_module ( void   )  [static]

Definition at line 251 of file app_talkdetect.c.

static int background_detect_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 76 of file app_talkdetect.c.

References ast_channel::_state, ast_answer(), AST_APP_ARG, ast_canmatch_extension(), ast_debug, AST_DECLARE_APP_ARGS, ast_dsp_free(), ast_dsp_new(), ast_dsp_silence(), AST_FORMAT_SLINEAR, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_frfree, ast_getformatname(), ast_goto_if_exists(), ast_log(), ast_read(), ast_sched_runq(), ast_sched_wait(), ast_set_read_format(), AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_stopstream(), ast_strdupa, ast_streamfile(), ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), ast_verb, ast_waitfor(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_frame::frametype, ast_channel::language, LOG_WARNING, ast_channel::name, pbx_builtin_setvar_helper(), ast_channel::readformat, ast_channel::sched, ast_channel::stream, ast_frame::subclass, ast_channel::timingfunc, and ast_dsp::totalsilence.

Referenced by load_module().

00077 {
00078    int res = 0;
00079    char *tmp;
00080    struct ast_frame *fr;
00081    int notsilent = 0;
00082    struct timeval start = { 0, 0 };
00083    struct timeval detection_start = { 0, 0 };
00084    int sil = 1000;
00085    int min = 100;
00086    int max = -1;
00087    int analysistime = -1;
00088    int continue_analysis = 1;
00089    int x;
00090    int origrformat = 0;
00091    struct ast_dsp *dsp = NULL;
00092    AST_DECLARE_APP_ARGS(args,
00093       AST_APP_ARG(filename);
00094       AST_APP_ARG(silence);
00095       AST_APP_ARG(min);
00096       AST_APP_ARG(max);
00097       AST_APP_ARG(analysistime);
00098    );
00099    
00100    if (ast_strlen_zero(data)) {
00101       ast_log(LOG_WARNING, "BackgroundDetect requires an argument (filename)\n");
00102       return -1;
00103    }
00104 
00105    tmp = ast_strdupa(data);
00106    AST_STANDARD_APP_ARGS(args, tmp);
00107 
00108    if (!ast_strlen_zero(args.silence) && (sscanf(args.silence, "%30d", &x) == 1) && (x > 0)) {
00109       sil = x;
00110    }
00111    if (!ast_strlen_zero(args.min) && (sscanf(args.min, "%30d", &x) == 1) && (x > 0)) {
00112       min = x;
00113    }
00114    if (!ast_strlen_zero(args.max) && (sscanf(args.max, "%30d", &x) == 1) && (x > 0)) {
00115       max = x;
00116    }
00117    if (!ast_strlen_zero(args.analysistime) && (sscanf(args.analysistime, "%30d", &x) == 1) && (x > 0)) {
00118       analysistime = x;
00119    }
00120 
00121    ast_debug(1, "Preparing detect of '%s', sil=%d, min=%d, max=%d, analysistime=%d\n", args.filename, sil, min, max, analysistime);
00122    do {
00123       if (chan->_state != AST_STATE_UP) {
00124          if ((res = ast_answer(chan))) {
00125             break;
00126          }
00127       }
00128 
00129       origrformat = chan->readformat;
00130       if ((ast_set_read_format(chan, AST_FORMAT_SLINEAR))) {
00131          ast_log(LOG_WARNING, "Unable to set read format to linear!\n");
00132          res = -1;
00133          break;
00134       }
00135 
00136       if (!(dsp = ast_dsp_new())) {
00137          ast_log(LOG_WARNING, "Unable to allocate DSP!\n");
00138          res = -1;
00139          break;
00140       }
00141       ast_stopstream(chan);
00142       if (ast_streamfile(chan, tmp, chan->language)) {
00143          ast_log(LOG_WARNING, "ast_streamfile failed on %s for %s\n", chan->name, (char *)data);
00144          break;
00145       }
00146       detection_start = ast_tvnow();
00147       while (chan->stream) {
00148          res = ast_sched_wait(chan->sched);
00149          if ((res < 0) && !chan->timingfunc) {
00150             res = 0;
00151             break;
00152          }
00153          if (res < 0) {
00154             res = 1000;
00155          }
00156          res = ast_waitfor(chan, res);
00157          if (res < 0) {
00158             ast_log(LOG_WARNING, "Waitfor failed on %s\n", chan->name);
00159             break;
00160          } else if (res > 0) {
00161             fr = ast_read(chan);
00162             if (continue_analysis && analysistime >= 0) {
00163                /* If we have a limit for the time to analyze voice
00164                 * frames and the time has not expired */
00165                if (ast_tvdiff_ms(ast_tvnow(), detection_start) >= analysistime) {
00166                   continue_analysis = 0;
00167                   ast_verb(3, "BackgroundDetect: Talk analysis time complete on %s.\n", chan->name);
00168                }
00169             }
00170             
00171             if (!fr) {
00172                res = -1;
00173                break;
00174             } else if (fr->frametype == AST_FRAME_DTMF) {
00175                char t[2];
00176                t[0] = fr->subclass;
00177                t[1] = '\0';
00178                if (ast_canmatch_extension(chan, chan->context, t, 1, chan->cid.cid_num)) {
00179                   /* They entered a valid  extension, or might be anyhow */
00180                   res = fr->subclass;
00181                   ast_frfree(fr);
00182                   break;
00183                }
00184             } else if ((fr->frametype == AST_FRAME_VOICE) && (fr->subclass == AST_FORMAT_SLINEAR) && continue_analysis) {
00185                int totalsilence;
00186                int ms;
00187                res = ast_dsp_silence(dsp, fr, &totalsilence);
00188                if (res && (totalsilence > sil)) {
00189                   /* We've been quiet a little while */
00190                   if (notsilent) {
00191                      /* We had heard some talking */
00192                      ms = ast_tvdiff_ms(ast_tvnow(), start);
00193                      ms -= sil;
00194                      if (ms < 0)
00195                         ms = 0;
00196                      if ((ms > min) && ((max < 0) || (ms < max))) {
00197                         char ms_str[12];
00198                         ast_debug(1, "Found qualified token of %d ms\n", ms);
00199 
00200                         /* Save detected talk time (in milliseconds) */ 
00201                         snprintf(ms_str, sizeof(ms_str), "%d", ms);  
00202                         pbx_builtin_setvar_helper(chan, "TALK_DETECTED", ms_str);
00203 
00204                         ast_goto_if_exists(chan, chan->context, "talk", 1);
00205                         res = 0;
00206                         ast_frfree(fr);
00207                         break;
00208                      } else {
00209                         ast_debug(1, "Found unqualified token of %d ms\n", ms);
00210                      }
00211                      notsilent = 0;
00212                   }
00213                } else {
00214                   if (!notsilent) {
00215                      /* Heard some audio, mark the begining of the token */
00216                      start = ast_tvnow();
00217                      ast_debug(1, "Start of voice token!\n");
00218                      notsilent = 1;
00219                   }
00220                }
00221             }
00222             ast_frfree(fr);
00223          }
00224          ast_sched_runq(chan->sched);
00225       }
00226       ast_stopstream(chan);
00227    } while (0);
00228 
00229    if (res > -1) {
00230       if (origrformat && ast_set_read_format(chan, origrformat)) {
00231          ast_log(LOG_WARNING, "Failed to restore read format for %s to %s\n", 
00232             chan->name, ast_getformatname(origrformat));
00233       }
00234    }
00235    if (dsp) {
00236       ast_dsp_free(dsp);
00237    }
00238    return res;
00239 }

static int load_module ( void   )  [static]

Definition at line 246 of file app_talkdetect.c.

References ast_register_application_xml, and background_detect_exec().

static int unload_module ( void   )  [static]

Definition at line 241 of file app_talkdetect.c.

References ast_unregister_application().

00242 {
00243    return ast_unregister_application(app);
00244 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Playback with Talk Detection" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, } [static]

Definition at line 251 of file app_talkdetect.c.

char* app = "BackgroundDetect" [static]

Definition at line 74 of file app_talkdetect.c.

Definition at line 251 of file app_talkdetect.c.


Generated on Thu Oct 11 06:47:52 2012 for Asterisk - the Open Source PBX by  doxygen 1.5.6