Thu Jul 9 13:40:49 2009

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"

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 = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, }
static char * app = "BackgroundDetect"
static const struct ast_module_infoast_module_info = &__mod_info
static char * descrip
static char * synopsis = "Background a file with talk detect"


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 211 of file app_talkdetect.c.

static void __unreg_module ( void   )  [static]

Definition at line 211 of file app_talkdetect.c.

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

Definition at line 58 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_waitfor(), chan, 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().

00059 {
00060    int res = 0;
00061    char *tmp;
00062    struct ast_frame *fr;
00063    int notsilent = 0;
00064    struct timeval start = { 0, 0};
00065    int sil = 1000;
00066    int min = 100;
00067    int max = -1;
00068    int x;
00069    int origrformat=0;
00070    struct ast_dsp *dsp = NULL;
00071    AST_DECLARE_APP_ARGS(args,
00072       AST_APP_ARG(filename);
00073       AST_APP_ARG(silence);
00074       AST_APP_ARG(min);
00075       AST_APP_ARG(max);
00076    );
00077    
00078    if (ast_strlen_zero(data)) {
00079       ast_log(LOG_WARNING, "BackgroundDetect requires an argument (filename)\n");
00080       return -1;
00081    }
00082 
00083    tmp = ast_strdupa(data);
00084    AST_STANDARD_APP_ARGS(args, tmp);
00085 
00086    if (!ast_strlen_zero(args.silence) && (sscanf(args.silence, "%d", &x) == 1) && (x > 0))
00087       sil = x;
00088    if (!ast_strlen_zero(args.min) && (sscanf(args.min, "%d", &x) == 1) && (x > 0))
00089       min = x;
00090    if (!ast_strlen_zero(args.max) && (sscanf(args.max, "%d", &x) == 1) && (x > 0))
00091       max = x;
00092 
00093    ast_debug(1, "Preparing detect of '%s', sil=%d, min=%d, max=%d\n", args.filename, sil, min, max);
00094    do {
00095       if (chan->_state != AST_STATE_UP) {
00096          if ((res = ast_answer(chan)))
00097             break;
00098       }
00099 
00100       origrformat = chan->readformat;
00101       if ((ast_set_read_format(chan, AST_FORMAT_SLINEAR))) {
00102          ast_log(LOG_WARNING, "Unable to set read format to linear!\n");
00103          res = -1;
00104          break;
00105       }
00106 
00107       if (!(dsp = ast_dsp_new())) {
00108          ast_log(LOG_WARNING, "Unable to allocate DSP!\n");
00109          res = -1;
00110          break;
00111       }
00112       ast_stopstream(chan);
00113       if (ast_streamfile(chan, tmp, chan->language)) {
00114          ast_log(LOG_WARNING, "ast_streamfile failed on %s for %s\n", chan->name, (char *)data);
00115          break;
00116       }
00117 
00118       while (chan->stream) {
00119          res = ast_sched_wait(chan->sched);
00120          if ((res < 0) && !chan->timingfunc) {
00121             res = 0;
00122             break;
00123          }
00124          if (res < 0)
00125             res = 1000;
00126          res = ast_waitfor(chan, res);
00127          if (res < 0) {
00128             ast_log(LOG_WARNING, "Waitfor failed on %s\n", chan->name);
00129             break;
00130          } else if (res > 0) {
00131             fr = ast_read(chan);
00132             if (!fr) {
00133                res = -1;
00134                break;
00135             } else if (fr->frametype == AST_FRAME_DTMF) {
00136                char t[2];
00137                t[0] = fr->subclass;
00138                t[1] = '\0';
00139                if (ast_canmatch_extension(chan, chan->context, t, 1, chan->cid.cid_num)) {
00140                   /* They entered a valid  extension, or might be anyhow */
00141                   res = fr->subclass;
00142                   ast_frfree(fr);
00143                   break;
00144                }
00145             } else if ((fr->frametype == AST_FRAME_VOICE) && (fr->subclass == AST_FORMAT_SLINEAR)) {
00146                int totalsilence;
00147                int ms;
00148                res = ast_dsp_silence(dsp, fr, &totalsilence);
00149                if (res && (totalsilence > sil)) {
00150                   /* We've been quiet a little while */
00151                   if (notsilent) {
00152                      /* We had heard some talking */
00153                      ms = ast_tvdiff_ms(ast_tvnow(), start);
00154                      ms -= sil;
00155                      if (ms < 0)
00156                         ms = 0;
00157                      if ((ms > min) && ((max < 0) || (ms < max))) {
00158                         char ms_str[10];
00159                         ast_debug(1, "Found qualified token of %d ms\n", ms);
00160 
00161                         /* Save detected talk time (in milliseconds) */ 
00162                         sprintf(ms_str, "%d", ms );   
00163                         pbx_builtin_setvar_helper(chan, "TALK_DETECTED", ms_str);
00164 
00165                         ast_goto_if_exists(chan, chan->context, "talk", 1);
00166                         res = 0;
00167                         ast_frfree(fr);
00168                         break;
00169                      } else {
00170                         ast_debug(1, "Found unqualified token of %d ms\n", ms);
00171                      }
00172                      notsilent = 0;
00173                   }
00174                } else {
00175                   if (!notsilent) {
00176                      /* Heard some audio, mark the begining of the token */
00177                      start = ast_tvnow();
00178                      ast_debug(1, "Start of voice token!\n");
00179                      notsilent = 1;
00180                   }
00181                }
00182             }
00183             ast_frfree(fr);
00184          }
00185          ast_sched_runq(chan->sched);
00186       }
00187       ast_stopstream(chan);
00188    } while (0);
00189 
00190    if (res > -1) {
00191       if (origrformat && ast_set_read_format(chan, origrformat)) {
00192          ast_log(LOG_WARNING, "Failed to restore read format for %s to %s\n", 
00193             chan->name, ast_getformatname(origrformat));
00194       }
00195    }
00196    if (dsp)
00197       ast_dsp_free(dsp);
00198    return res;
00199 }

static int load_module ( void   )  [static]

Definition at line 206 of file app_talkdetect.c.

References ast_register_application, and background_detect_exec().

static int unload_module ( void   )  [static]

Definition at line 201 of file app_talkdetect.c.

References ast_unregister_application().

00202 {
00203    return ast_unregister_application(app);
00204 }


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 = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, } [static]

Definition at line 211 of file app_talkdetect.c.

char* app = "BackgroundDetect" [static]

Definition at line 42 of file app_talkdetect.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 211 of file app_talkdetect.c.

char* descrip [static]

Definition at line 46 of file app_talkdetect.c.

char* synopsis = "Background a file with talk detect" [static]

Definition at line 44 of file app_talkdetect.c.


Generated on Thu Jul 9 13:40:49 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7