Mon Oct 8 12:39:08 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"

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, const char *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_LOAD_ORDER , .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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, }
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 256 of file app_talkdetect.c.

static void __unreg_module ( void   )  [static]

Definition at line 256 of file app_talkdetect.c.

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

Definition at line 80 of file app_talkdetect.c.

References ast_channel::_state, args, 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::caller, ast_frame_subclass::codec, ast_channel::context, ast_frame::frametype, ast_party_caller::id, ast_frame_subclass::integer, ast_channel::language, LOG_WARNING, ast_channel::name, ast_party_id::number, pbx_builtin_setvar_helper(), ast_channel::readformat, S_COR, ast_channel::sched, ast_party_number::str, ast_channel::stream, ast_frame::subclass, ast_channel::timingfunc, ast_dsp::totalsilence, and ast_party_number::valid.

Referenced by load_module().

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

static int load_module ( void   )  [static]

Definition at line 251 of file app_talkdetect.c.

References ast_register_application_xml, and background_detect_exec().

static int unload_module ( void   )  [static]

Definition at line 246 of file app_talkdetect.c.

References ast_unregister_application().

00247 {
00248    return ast_unregister_application(app);
00249 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } [static]

Definition at line 256 of file app_talkdetect.c.

char* app = "BackgroundDetect" [static]

Definition at line 78 of file app_talkdetect.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 256 of file app_talkdetect.c.


Generated on Mon Oct 8 12:39:08 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7