#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_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 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().
00223 { 00224 return ast_register_application(app, background_detect_exec, synopsis, descrip); 00225 }
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 }
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.