Sat Aug 6 00:39:37 2011

Asterisk developer's documentation


app_talkdetect.c File Reference

Playback a file with audio detect. More...

#include "asterisk.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/logger.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"

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 | AST_MODFLAG_BUILDSUM, .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 = "361d7bb937402d51e4658efb5b4d76e4" , .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 227 of file app_talkdetect.c.

static void __unreg_module ( void   )  [static]

Definition at line 227 of file app_talkdetect.c.

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

Definition at line 62 of file app_talkdetect.c.

References ast_channel::_state, ast_answer(), ast_canmatch_extension(), 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_module_user_add, ast_module_user_remove, ast_read(), ast_sched_runq(), ast_sched_wait(), ast_set_read_format(), AST_STATE_UP, ast_stopstream(), ast_strdupa, ast_streamfile(), ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), ast_waitfor(), ast_frame::frametype, LOG_DEBUG, LOG_WARNING, ast_channel::name, pbx_builtin_setvar_helper(), ast_channel::readformat, ast_frame::subclass, t, and ast_dsp::totalsilence.

Referenced by load_module().

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

static int load_module ( void   )  [static]

Definition at line 222 of file app_talkdetect.c.

References ast_register_application(), and background_detect_exec().

static int unload_module ( void   )  [static]

Definition at line 211 of file app_talkdetect.c.

References ast_module_user_hangup_all, and ast_unregister_application().

00212 {
00213    int res;
00214 
00215    res = ast_unregister_application(app);
00216    
00217    ast_module_user_hangup_all();
00218 
00219    return res; 
00220 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .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 = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, } [static]

Definition at line 227 of file app_talkdetect.c.

char* app = "BackgroundDetect" [static]

Definition at line 46 of file app_talkdetect.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 227 of file app_talkdetect.c.

char* descrip [static]

Definition at line 50 of file app_talkdetect.c.

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

Definition at line 48 of file app_talkdetect.c.


Generated on Sat Aug 6 00:39:37 2011 for Asterisk - the Open Source PBX by  doxygen 1.4.7