#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 | |
AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"Playback with Talk Detection") | |
static int | background_detect_exec (struct ast_channel *chan, void *data) |
static int | load_module (void) |
static int | unload_module (void) |
Variables | |
static char * | app = "BackgroundDetect" |
static char * | descrip |
static char * | synopsis = "Background a file with talk detect" |
Definition in file app_talkdetect.c.
AST_MODULE_INFO_STANDARD | ( | ASTERISK_GPL_KEY | , | |
"Playback with Talk Detection" | ||||
) |
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_waitfor(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_frame::frametype, LOG_DEBUG, LOG_WARNING, pbx_builtin_setvar_helper(), ast_channel::readformat, ast_channel::sched, ast_channel::stream, strsep(), ast_frame::subclass, t, ast_channel::timingfunc, 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, "%d", &x) == 1) && (x > 0)) 00093 sil = x; 00094 options = strsep(&stringp, "|"); 00095 if (options) { 00096 if ((sscanf(options, "%d", &x) == 1) && (x > 0)) 00097 min = x; 00098 options = strsep(&stringp, "|"); 00099 if (options) { 00100 if ((sscanf(options, "%d", &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 }
char* app = "BackgroundDetect" [static] |
Definition at line 46 of file app_talkdetect.c.
char* descrip [static] |
Definition at line 50 of file app_talkdetect.c.
Definition at line 48 of file app_talkdetect.c.