#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "asterisk.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 | |
int | background_detect_exec (struct ast_channel *chan, void *data) |
char * | description (void) |
Provides a description of the module. | |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
int | load_module (void) |
Initialize the module. | |
int | unload_module (void) |
Cleanup all module structures, sockets, etc. | |
int | usecount (void) |
Provides a usecount. | |
Variables | |
char * | app = "BackgroundDetect" |
char * | descrip |
LOCAL_USER_DECL | |
STANDARD_LOCAL_USER | |
char * | synopsis = "Background a file with talk detect" |
char * | tdesc = "Playback with Talk Detection" |
Definition in file app_talkdetect.c.
|
Definition at line 65 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_frfree(), ast_getformatname(), ast_goto_if_exists(), ast_log(), ast_read(), ast_sched_runq(), ast_sched_wait(), ast_set_read_format(), ast_stopstream(), ast_strdupa, ast_streamfile(), ast_strlen_zero(), ast_waitfor(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, dsp, ast_frame::frametype, ast_channel::language, LOCAL_USER_ADD, LOCAL_USER_REMOVE, LOG_DEBUG, LOG_ERROR, LOG_WARNING, ast_channel::name, pbx_builtin_setvar_helper(), ast_channel::readformat, ast_channel::sched, ast_channel::stream, strsep(), ast_frame::subclass, and ast_channel::timingfunc. Referenced by load_module(). 00066 { 00067 int res = 0; 00068 struct localuser *u; 00069 char *tmp; 00070 char *options; 00071 char *stringp; 00072 struct ast_frame *fr; 00073 int notsilent=0; 00074 struct timeval start = { 0, 0}; 00075 int sil = 1000; 00076 int min = 100; 00077 int max = -1; 00078 int x; 00079 int origrformat=0; 00080 struct ast_dsp *dsp; 00081 00082 if (ast_strlen_zero(data)) { 00083 ast_log(LOG_WARNING, "BackgroundDetect requires an argument (filename)\n"); 00084 return -1; 00085 } 00086 00087 LOCAL_USER_ADD(u); 00088 00089 tmp = ast_strdupa(data); 00090 if (!tmp) { 00091 ast_log(LOG_ERROR, "Out of memory\n"); 00092 LOCAL_USER_REMOVE(u); 00093 return -1; 00094 } 00095 00096 stringp=tmp; 00097 strsep(&stringp, "|"); 00098 options = strsep(&stringp, "|"); 00099 if (options) { 00100 if ((sscanf(options, "%d", &x) == 1) && (x > 0)) 00101 sil = x; 00102 options = strsep(&stringp, "|"); 00103 if (options) { 00104 if ((sscanf(options, "%d", &x) == 1) && (x > 0)) 00105 min = x; 00106 options = strsep(&stringp, "|"); 00107 if (options) { 00108 if ((sscanf(options, "%d", &x) == 1) && (x > 0)) 00109 max = x; 00110 } 00111 } 00112 } 00113 ast_log(LOG_DEBUG, "Preparing detect of '%s', sil=%d,min=%d,max=%d\n", 00114 tmp, sil, min, max); 00115 if (chan->_state != AST_STATE_UP) { 00116 /* Otherwise answer unless we're supposed to send this while on-hook */ 00117 res = ast_answer(chan); 00118 } 00119 if (!res) { 00120 origrformat = chan->readformat; 00121 if ((res = ast_set_read_format(chan, AST_FORMAT_SLINEAR))) 00122 ast_log(LOG_WARNING, "Unable to set read format to linear!\n"); 00123 } 00124 if (!(dsp = ast_dsp_new())) { 00125 ast_log(LOG_WARNING, "Unable to allocate DSP!\n"); 00126 res = -1; 00127 } 00128 if (!res) { 00129 ast_stopstream(chan); 00130 res = ast_streamfile(chan, tmp, chan->language); 00131 if (!res) { 00132 while(chan->stream) { 00133 res = ast_sched_wait(chan->sched); 00134 if ((res < 0) && !chan->timingfunc) { 00135 res = 0; 00136 break; 00137 } 00138 if (res < 0) 00139 res = 1000; 00140 res = ast_waitfor(chan, res); 00141 if (res < 0) { 00142 ast_log(LOG_WARNING, "Waitfor failed on %s\n", chan->name); 00143 break; 00144 } else if (res > 0) { 00145 fr = ast_read(chan); 00146 if (!fr) { 00147 res = -1; 00148 break; 00149 } else if (fr->frametype == AST_FRAME_DTMF) { 00150 char t[2]; 00151 t[0] = fr->subclass; 00152 t[1] = '\0'; 00153 if (ast_canmatch_extension(chan, chan->context, t, 1, chan->cid.cid_num)) { 00154 /* They entered a valid extension, or might be anyhow */ 00155 res = fr->subclass; 00156 ast_frfree(fr); 00157 break; 00158 } 00159 } else if ((fr->frametype == AST_FRAME_VOICE) && (fr->subclass == AST_FORMAT_SLINEAR)) { 00160 int totalsilence; 00161 int ms; 00162 res = ast_dsp_silence(dsp, fr, &totalsilence); 00163 if (res && (totalsilence > sil)) { 00164 /* We've been quiet a little while */ 00165 if (notsilent) { 00166 /* We had heard some talking */ 00167 ms = ast_tvdiff_ms(ast_tvnow(), start); 00168 ms -= sil; 00169 if (ms < 0) 00170 ms = 0; 00171 if ((ms > min) && ((max < 0) || (ms < max))) { 00172 char ms_str[10]; 00173 ast_log(LOG_DEBUG, "Found qualified token of %d ms\n", ms); 00174 00175 /* Save detected talk time (in milliseconds) */ 00176 sprintf(ms_str, "%d", ms ); 00177 pbx_builtin_setvar_helper(chan, "TALK_DETECTED", ms_str); 00178 00179 ast_goto_if_exists(chan, chan->context, "talk", 1); 00180 res = 0; 00181 ast_frfree(fr); 00182 break; 00183 } else 00184 ast_log(LOG_DEBUG, "Found unqualified token of %d ms\n", ms); 00185 notsilent = 0; 00186 } 00187 } else { 00188 if (!notsilent) { 00189 /* Heard some audio, mark the begining of the token */ 00190 start = ast_tvnow(); 00191 ast_log(LOG_DEBUG, "Start of voice token!\n"); 00192 notsilent = 1; 00193 } 00194 } 00195 00196 } 00197 ast_frfree(fr); 00198 } 00199 ast_sched_runq(chan->sched); 00200 } 00201 ast_stopstream(chan); 00202 } else { 00203 ast_log(LOG_WARNING, "ast_streamfile failed on %s for %s\n", chan->name, (char *)data); 00204 res = 0; 00205 } 00206 } 00207 if (res > -1) { 00208 if (origrformat && ast_set_read_format(chan, origrformat)) { 00209 ast_log(LOG_WARNING, "Failed to restore read format for %s to %s\n", 00210 chan->name, ast_getformatname(origrformat)); 00211 } 00212 } 00213 if (dsp) 00214 ast_dsp_free(dsp); 00215 LOCAL_USER_REMOVE(u); 00216 return res; 00217 }
|
|
Provides a description of the module.
Definition at line 235 of file app_talkdetect.c. 00236 {
00237 return tdesc;
00238 }
|
|
Returns the ASTERISK_GPL_KEY. This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:
char *key(void) { return ASTERISK_GPL_KEY; }
Definition at line 247 of file app_talkdetect.c. 00248 {
00249 return ASTERISK_GPL_KEY;
00250 }
|
|
Initialize the module. Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.
Definition at line 230 of file app_talkdetect.c. References app, ast_register_application(), background_detect_exec(), descrip, and synopsis. 00231 { 00232 return ast_register_application(app, background_detect_exec, synopsis, descrip); 00233 }
|
|
Cleanup all module structures, sockets, etc. This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).
Definition at line 219 of file app_talkdetect.c. References app, and ast_unregister_application(). 00220 { 00221 int res; 00222 00223 res = ast_unregister_application(app); 00224 00225 STANDARD_HANGUP_LOCALUSERS; 00226 00227 return res; 00228 }
|
|
Provides a usecount. This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.
Definition at line 240 of file app_talkdetect.c. References STANDARD_USECOUNT. 00241 { 00242 int res; 00243 STANDARD_USECOUNT(res); 00244 return res; 00245 }
|
|
Definition at line 46 of file app_talkdetect.c. Referenced by load_module(), and unload_module(). |
|
Definition at line 50 of file app_talkdetect.c. Referenced by load_module(). |
|
Definition at line 63 of file app_talkdetect.c. |
|
Definition at line 61 of file app_talkdetect.c. |
|
Definition at line 48 of file app_talkdetect.c. Referenced by load_module(). |
|
Definition at line 44 of file app_talkdetect.c. |