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