dect
/
asterisk
Archived
13
0
Fork 0

Create a centralized configuration option for silencethreshold

(closes issue #11236)
 Reported by: philipps
 Patches: 
       20080218__bug11236.diff.txt uploaded by Corydon76 (license 14)
 Tested by: philipps


git-svn-id: http://svn.digium.com/svn/asterisk/trunk@106072 f38db490-d61c-443f-a65b-d21fe96a405b
This commit is contained in:
tilghman 2008-03-05 16:23:44 +00:00
parent 6f39909904
commit 198829f2db
17 changed files with 248 additions and 111 deletions

View File

@ -175,7 +175,7 @@ Skinny changes
* Proper codec support in chan_skinny. * Proper codec support in chan_skinny.
* Added settings for IP and Ethernet QoS requests * Added settings for IP and Ethernet QoS requests
MGCP changes
------------ ------------
* Added separate settings for media QoS in mgcp.conf * Added separate settings for media QoS in mgcp.conf
@ -387,6 +387,8 @@ Other Dialplan Application Changes
* The ChannelRedirect application no longer exits the dialplan if the given channel * The ChannelRedirect application no longer exits the dialplan if the given channel
does not exist. It will now set the CHANNELREDIRECT_STATUS variable to SUCCESS upon success does not exist. It will now set the CHANNELREDIRECT_STATUS variable to SUCCESS upon success
or NOCHANNEL if the given channel was not found. or NOCHANNEL if the given channel was not found.
* The silencethreshold setting that was previously configurable in multiple
applications is now settable globally via dsp.conf.
Music On Hold Changes Music On Hold Changes
--------------------- ---------------------

View File

@ -56,6 +56,9 @@ Core:
* The concise versions of various CLI commands are now deprecated. We recommend * The concise versions of various CLI commands are now deprecated. We recommend
using the manager interface (AMI) for application integration with Asterisk. using the manager interface (AMI) for application integration with Asterisk.
* The silencethreshold used for various applications is now settable via a
centralized config option in dsp.conf.
Voicemail: Voicemail:
* The voicemail configuration values 'maxmessage' and 'minmessage' have * The voicemail configuration values 'maxmessage' and 'minmessage' have

View File

@ -371,6 +371,8 @@ static int load_config(int reload)
struct ast_variable *var = NULL; struct ast_variable *var = NULL;
struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
dfltSilenceThreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE);
if (!(cfg = ast_config_load("amd.conf", config_flags))) { if (!(cfg = ast_config_load("amd.conf", config_flags))) {
ast_log(LOG_ERROR, "Configuration file amd.conf missing.\n"); ast_log(LOG_ERROR, "Configuration file amd.conf missing.\n");
return -1; return -1;

View File

@ -60,6 +60,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/privacy.h" #include "asterisk/privacy.h"
#include "asterisk/stringfields.h" #include "asterisk/stringfields.h"
#include "asterisk/global_datastores.h" #include "asterisk/global_datastores.h"
#include "asterisk/dsp.h"
static char *app = "Dial"; static char *app = "Dial";
@ -1115,6 +1116,7 @@ static int setup_privacy_args(struct privacy_args *pa,
char callerid[60]; char callerid[60];
int res; int res;
char *l; char *l;
int silencethreshold;
if (!ast_strlen_zero(chan->cid.cid_num)) { if (!ast_strlen_zero(chan->cid.cid_num)) {
l = ast_strdupa(chan->cid.cid_num); l = ast_strdupa(chan->cid.cid_num);
@ -1188,8 +1190,9 @@ static int setup_privacy_args(struct privacy_args *pa,
"At the tone, please say your name:" "At the tone, please say your name:"
*/ */
silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE);
ast_answer(chan); ast_answer(chan);
res = ast_play_and_record(chan, "priv-recordintro", pa->privintro, 4, "gsm", &duration, 128, 2000, 0); /* NOTE: I've reduced the total time to 4 sec */ res = ast_play_and_record(chan, "priv-recordintro", pa->privintro, 4, "gsm", &duration, silencethreshold, 2000, 0); /* NOTE: I've reduced the total time to 4 sec */
/* don't think we'll need a lock removed, we took care of /* don't think we'll need a lock removed, we took care of
conflicts by naming the pa.privintro file */ conflicts by naming the pa.privintro file */
if (res == -1) { if (res == -1) {

View File

@ -55,6 +55,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/utils.h" #include "asterisk/utils.h"
#include "asterisk/causes.h" #include "asterisk/causes.h"
#include "asterisk/astdb.h" #include "asterisk/astdb.h"
#include "asterisk/dsp.h"
#include "asterisk/app.h" #include "asterisk/app.h"
static char *app = "FollowMe"; static char *app = "FollowMe";
@ -130,7 +131,7 @@ struct findme_user {
int ynidx; int ynidx;
long digts; long digts;
int cleared; int cleared;
AST_LIST_ENTRY(findme_user) entry; AST_LIST_ENTRY(findme_user) entry;
}; };
enum { enum {
@ -183,7 +184,6 @@ static void free_numbers(struct call_followme *f)
/* Free the whitelisted number */ /* Free the whitelisted number */
ast_free(prev); ast_free(prev);
AST_LIST_HEAD_INIT_NOLOCK(&f->wlnumbers); AST_LIST_HEAD_INIT_NOLOCK(&f->wlnumbers);
} }
@ -258,7 +258,6 @@ static struct number *create_followme_number(char *number, int timeout, int numo
{ {
struct number *cur; struct number *cur;
char *tmp; char *tmp;
if (!(cur = ast_calloc(1, sizeof(*cur)))) if (!(cur = ast_calloc(1, sizeof(*cur))))
return NULL; return NULL;
@ -284,7 +283,7 @@ static int reload_followme(int reload)
char numberstr[90]; char numberstr[90];
int timeout; int timeout;
char *timeoutstr; char *timeoutstr;
int numorder; int numorder;
const char *takecallstr; const char *takecallstr;
const char *declinecallstr; const char *declinecallstr;
const char *tmpstr; const char *tmpstr;
@ -307,7 +306,7 @@ static int reload_followme(int reload)
} }
featuredigittostr = ast_variable_retrieve(cfg, "general", "featuredigittimeout"); featuredigittostr = ast_variable_retrieve(cfg, "general", "featuredigittimeout");
if (!ast_strlen_zero(featuredigittostr)) { if (!ast_strlen_zero(featuredigittostr)) {
if (!sscanf(featuredigittostr, "%d", &featuredigittimeout)) if (!sscanf(featuredigittostr, "%d", &featuredigittimeout))
featuredigittimeout = 5000; featuredigittimeout = 5000;
@ -316,7 +315,7 @@ static int reload_followme(int reload)
takecallstr = ast_variable_retrieve(cfg, "general", "takecall"); takecallstr = ast_variable_retrieve(cfg, "general", "takecall");
if (!ast_strlen_zero(takecallstr)) if (!ast_strlen_zero(takecallstr))
ast_copy_string(takecall, takecallstr, sizeof(takecall)); ast_copy_string(takecall, takecallstr, sizeof(takecall));
declinecallstr = ast_variable_retrieve(cfg, "general", "declinecall"); declinecallstr = ast_variable_retrieve(cfg, "general", "declinecall");
if (!ast_strlen_zero(declinecallstr)) if (!ast_strlen_zero(declinecallstr))
ast_copy_string(nextindp, declinecallstr, sizeof(nextindp)); ast_copy_string(nextindp, declinecallstr, sizeof(nextindp));
@ -369,7 +368,7 @@ static int reload_followme(int reload)
/* Totally fail if we fail to find/create an entry */ /* Totally fail if we fail to find/create an entry */
if (!f) if (!f)
continue; continue;
if (!new) if (!new)
ast_mutex_lock(&f->lock); ast_mutex_lock(&f->lock);
/* Re-initialize the profile */ /* Re-initialize the profile */
@ -399,8 +398,8 @@ static int reload_followme(int reload)
timeout = 25; timeout = 25;
numorder = 0; numorder = 0;
} }
if (!numorder) { if (!numorder) {
idx = 1; idx = 1;
AST_LIST_TRAVERSE(&f->numbers, nm, entry) AST_LIST_TRAVERSE(&f->numbers, nm, entry)
idx++; idx++;
@ -414,7 +413,7 @@ static int reload_followme(int reload)
} }
var = var->next; var = var->next;
} /* End while(var) loop */ } /* End while(var) loop */
if (!new) if (!new)
ast_mutex_unlock(&f->lock); ast_mutex_unlock(&f->lock);
else else
@ -431,7 +430,7 @@ static int reload_followme(int reload)
static void clear_caller(struct findme_user *tmpuser) static void clear_caller(struct findme_user *tmpuser)
{ {
struct ast_channel *outbound; struct ast_channel *outbound;
if (tmpuser && tmpuser->ochan && tmpuser->state >= 0) { if (tmpuser && tmpuser->ochan && tmpuser->state >= 0) {
outbound = tmpuser->ochan; outbound = tmpuser->ochan;
if (!outbound->cdr) { if (!outbound->cdr) {
@ -460,12 +459,11 @@ static void clear_caller(struct findme_user *tmpuser)
static void clear_calling_tree(struct findme_user_listptr *findme_user_list) static void clear_calling_tree(struct findme_user_listptr *findme_user_list)
{ {
struct findme_user *tmpuser; struct findme_user *tmpuser;
AST_LIST_TRAVERSE(findme_user_list, tmpuser, entry) { AST_LIST_TRAVERSE(findme_user_list, tmpuser, entry) {
clear_caller(tmpuser); clear_caller(tmpuser);
tmpuser->cleared = 1; tmpuser->cleared = 1;
} }
} }
@ -489,29 +487,29 @@ static struct ast_channel *wait_for_winner(struct findme_user_listptr *findme_us
/* ------------ wait_for_winner_channel start --------------- */ /* ------------ wait_for_winner_channel start --------------- */
callfromname = ast_strdupa(tpargs->callfromprompt); callfromname = ast_strdupa(tpargs->callfromprompt);
pressbuttonname = ast_strdupa(tpargs->optionsprompt); pressbuttonname = ast_strdupa(tpargs->optionsprompt);
if (AST_LIST_EMPTY(findme_user_list)) { if (AST_LIST_EMPTY(findme_user_list)) {
ast_verb(3, "couldn't reach at this number.\n"); ast_verb(3, "couldn't reach at this number.\n");
return NULL; return NULL;
} }
if (!caller) { if (!caller) {
ast_verb(3, "Original caller hungup. Cleanup.\n"); ast_verb(3, "Original caller hungup. Cleanup.\n");
clear_calling_tree(findme_user_list); clear_calling_tree(findme_user_list);
return NULL; return NULL;
} }
totalwait = nm->timeout * 1000; totalwait = nm->timeout * 1000;
while (!ctstatus) { while (!ctstatus) {
to = 1000; to = 1000;
pos = 1; pos = 1;
livechannels = 0; livechannels = 0;
watchers[0] = caller; watchers[0] = caller;
dg = 0; dg = 0;
winner = NULL; winner = NULL;
AST_LIST_TRAVERSE(findme_user_list, tmpuser, entry) { AST_LIST_TRAVERSE(findme_user_list, tmpuser, entry) {
if (tmpuser->state >= 0 && tmpuser->ochan) { if (tmpuser->state >= 0 && tmpuser->ochan) {
if (tmpuser->state == 3) if (tmpuser->state == 3)
@ -526,7 +524,7 @@ static struct ast_channel *wait_for_winner(struct findme_user_listptr *findme_us
} else { } else {
ast_log(LOG_WARNING, "Unable to playback %s.\n", callfromname); ast_log(LOG_WARNING, "Unable to playback %s.\n", callfromname);
return NULL; return NULL;
} }
} else { } else {
tmpuser->state = 2; tmpuser->state = 2;
tmpuser->digts = 0; tmpuser->digts = 0;
@ -566,7 +564,6 @@ static struct ast_channel *wait_for_winner(struct findme_user_listptr *findme_us
tmpuser->ynidx = 0; tmpuser->ynidx = 0;
if (!ast_streamfile(tmpuser->ochan, pressbuttonname, tmpuser->ochan->language)) { if (!ast_streamfile(tmpuser->ochan, pressbuttonname, tmpuser->ochan->language)) {
tmpuser->state = 3; tmpuser->state = 3;
} else { } else {
return NULL; return NULL;
} }
@ -580,7 +577,7 @@ static struct ast_channel *wait_for_winner(struct findme_user_listptr *findme_us
livechannels++; livechannels++;
} }
} }
tmpto = to; tmpto = to;
if (to < 0) { if (to < 0) {
to = 1000; to = 1000;
@ -590,7 +587,7 @@ static struct ast_channel *wait_for_winner(struct findme_user_listptr *findme_us
winner = ast_waitfor_n(watchers, pos, &to); winner = ast_waitfor_n(watchers, pos, &to);
tmpto -= to; tmpto -= to;
totalwait -= tmpto; totalwait -= tmpto;
wtd = to; wtd = to;
if (totalwait <= 0) { if (totalwait <= 0) {
ast_verb(3, "We've hit our timeout for this step. Drop everyone and move on to the next one. %ld\n", totalwait); ast_verb(3, "We've hit our timeout for this step. Drop everyone and move on to the next one. %ld\n", totalwait);
clear_calling_tree(findme_user_list); clear_calling_tree(findme_user_list);
@ -631,8 +628,8 @@ static struct ast_channel *wait_for_winner(struct findme_user_listptr *findme_us
ast_log(LOG_WARNING, "Unable to playback %s.\n", callfromname); ast_log(LOG_WARNING, "Unable to playback %s.\n", callfromname);
ast_frfree(f); ast_frfree(f);
return NULL; return NULL;
} }
} else { } else {
tmpuser->state = 2; tmpuser->state = 2;
if (!ast_streamfile(tmpuser->ochan, tpargs->norecordingprompt, tmpuser->ochan->language)) if (!ast_streamfile(tmpuser->ochan, tpargs->norecordingprompt, tmpuser->ochan->language))
ast_sched_runq(tmpuser->ochan->sched); ast_sched_runq(tmpuser->ochan->sched);
@ -693,18 +690,18 @@ static struct ast_channel *wait_for_winner(struct findme_user_listptr *findme_us
if (!strcmp(tmpuser->yn, tpargs->takecall)) { if (!strcmp(tmpuser->yn, tpargs->takecall)) {
ast_debug(1, "Match to take the call!\n"); ast_debug(1, "Match to take the call!\n");
ast_frfree(f); ast_frfree(f);
return tmpuser->ochan; return tmpuser->ochan;
} }
if (!strcmp(tmpuser->yn, tpargs->nextindp)) { if (!strcmp(tmpuser->yn, tpargs->nextindp)) {
ast_debug(1, "Next in dial plan step requested.\n"); ast_debug(1, "Next in dial plan step requested.\n");
*status = 1; *status = 1;
ast_frfree(f); ast_frfree(f);
return NULL; return NULL;
} }
} }
} }
ast_frfree(f); ast_frfree(f);
} else { } else {
if (winner) { if (winner) {
@ -723,12 +720,12 @@ static struct ast_channel *wait_for_winner(struct findme_user_listptr *findme_us
} }
} }
} }
} }
} else } else
ast_debug(1, "timed out waiting for action\n"); ast_debug(1, "timed out waiting for action\n");
} }
/* --- WAIT FOR WINNER NUMBER END! -----------*/ /* --- WAIT FOR WINNER NUMBER END! -----------*/
return NULL; return NULL;
} }
@ -748,7 +745,7 @@ static void findmeexec(struct fm_args *tpargs)
struct findme_user_listptr *findme_user_list; struct findme_user_listptr *findme_user_list;
int status; int status;
findme_user_list = ast_calloc(1, sizeof(*findme_user_list)); findme_user_list = ast_calloc(1, sizeof(*findme_user_list));
AST_LIST_HEAD_INIT_NOLOCK(findme_user_list); AST_LIST_HEAD_INIT_NOLOCK(findme_user_list);
/* We're going to figure out what the longest possible string of digits to collect is */ /* We're going to figure out what the longest possible string of digits to collect is */
@ -782,14 +779,14 @@ static void findmeexec(struct fm_args *tpargs)
sprintf(dialarg, "%s", number); sprintf(dialarg, "%s", number);
else else
sprintf(dialarg, "%s@%s", number, tpargs->context); sprintf(dialarg, "%s@%s", number, tpargs->context);
tmpuser = ast_calloc(1, sizeof(*tmpuser)); tmpuser = ast_calloc(1, sizeof(*tmpuser));
if (!tmpuser) { if (!tmpuser) {
ast_log(LOG_WARNING, "Out of memory!\n"); ast_log(LOG_WARNING, "Out of memory!\n");
ast_free(findme_user_list); ast_free(findme_user_list);
return; return;
} }
outbound = ast_request("Local", ast_best_codec(caller->nativeformats), dialarg, &dg); outbound = ast_request("Local", ast_best_codec(caller->nativeformats), dialarg, &dg);
if (outbound) { if (outbound) {
ast_set_callerid(outbound, caller->cid.cid_num, caller->cid.cid_name, caller->cid.cid_num); ast_set_callerid(outbound, caller->cid.cid_num, caller->cid.cid_name, caller->cid.cid_num);
@ -824,19 +821,17 @@ static void findmeexec(struct fm_args *tpargs)
outbound = NULL; outbound = NULL;
} }
} }
} }
} else } else
ast_log(LOG_WARNING, "Unable to allocate a channel for Local/%s cause: %s\n", dialarg, ast_cause2str(dg)); ast_log(LOG_WARNING, "Unable to allocate a channel for Local/%s cause: %s\n", dialarg, ast_cause2str(dg));
number = rest; number = rest;
} while (number); } while (number);
status = 0; status = 0;
if (!AST_LIST_EMPTY(findme_user_list)) if (!AST_LIST_EMPTY(findme_user_list))
winner = wait_for_winner(findme_user_list, nm, caller, tpargs->namerecloc, &status, tpargs); winner = wait_for_winner(findme_user_list, nm, caller, tpargs->namerecloc, &status, tpargs);
while ((fmuser = AST_LIST_REMOVE_HEAD(findme_user_list, entry))) { while ((fmuser = AST_LIST_REMOVE_HEAD(findme_user_list, entry))) {
if (!fmuser->cleared && fmuser->ochan != winner) if (!fmuser->cleared && fmuser->ochan != winner)
clear_caller(fmuser); clear_caller(fmuser);
@ -845,21 +840,21 @@ static void findmeexec(struct fm_args *tpargs)
fmuser = NULL; fmuser = NULL;
tmpuser = NULL; tmpuser = NULL;
headuser = NULL; headuser = NULL;
if (winner) if (winner)
break; break;
if (!caller) { if (!caller) {
tpargs->status = 1; tpargs->status = 1;
ast_free(findme_user_list); ast_free(findme_user_list);
return; return;
} }
idx++; idx++;
AST_LIST_TRAVERSE(&tpargs->cnumbers, nm, entry) AST_LIST_TRAVERSE(&tpargs->cnumbers, nm, entry) {
if (nm->order == idx) if (nm->order == idx)
break; break;
}
} }
ast_free(findme_user_list); ast_free(findme_user_list);
if (!winner) if (!winner)
@ -869,9 +864,7 @@ static void findmeexec(struct fm_args *tpargs)
tpargs->outbound = winner; tpargs->outbound = winner;
} }
return; return;
} }
static int app_exec(struct ast_channel *chan, void *data) static int app_exec(struct ast_channel *chan, void *data)
@ -887,7 +880,6 @@ static int app_exec(struct ast_channel *chan, void *data)
struct ast_channel *caller; struct ast_channel *caller;
struct ast_channel *outbound; struct ast_channel *outbound;
static char toast[80]; static char toast[80];
AST_DECLARE_APP_ARGS(args, AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(followmeid); AST_APP_ARG(followmeid);
AST_APP_ARG(options); AST_APP_ARG(options);
@ -897,7 +889,7 @@ static int app_exec(struct ast_channel *chan, void *data)
ast_log(LOG_WARNING, "%s requires an argument (followmeid)\n", app); ast_log(LOG_WARNING, "%s requires an argument (followmeid)\n", app);
return -1; return -1;
} }
if (!(argstr = ast_strdupa((char *)data))) { if (!(argstr = ast_strdupa((char *)data))) {
ast_log(LOG_ERROR, "Out of memory!\n"); ast_log(LOG_ERROR, "Out of memory!\n");
return -1; return -1;
@ -916,7 +908,7 @@ static int app_exec(struct ast_channel *chan, void *data)
break; break;
} }
AST_RWLIST_UNLOCK(&followmes); AST_RWLIST_UNLOCK(&followmes);
ast_debug(1, "New profile %s.\n", args.followmeid); ast_debug(1, "New profile %s.\n", args.followmeid);
if (!f) { if (!f) {
@ -927,7 +919,7 @@ static int app_exec(struct ast_channel *chan, void *data)
/* XXX TODO: Reinsert the db check value to see whether or not follow-me is on or off */ /* XXX TODO: Reinsert the db check value to see whether or not follow-me is on or off */
if (args.options) if (args.options)
ast_app_parse_options(followme_opts, &targs.followmeflags, NULL, args.options); ast_app_parse_options(followme_opts, &targs.followmeflags, NULL, args.options);
/* Lock the profile lock and copy out everything we need to run with before unlocking it again */ /* Lock the profile lock and copy out everything we need to run with before unlocking it again */
ast_mutex_lock(&f->lock); ast_mutex_lock(&f->lock);
targs.mohclass = ast_strdupa(f->moh); targs.mohclass = ast_strdupa(f->moh);
@ -948,38 +940,38 @@ static int app_exec(struct ast_channel *chan, void *data)
AST_LIST_INSERT_TAIL(&targs.cnumbers, newnm, entry); AST_LIST_INSERT_TAIL(&targs.cnumbers, newnm, entry);
} }
ast_mutex_unlock(&f->lock); ast_mutex_unlock(&f->lock);
if (ast_test_flag(&targs.followmeflags, FOLLOWMEFLAG_STATUSMSG)) if (ast_test_flag(&targs.followmeflags, FOLLOWMEFLAG_STATUSMSG))
ast_stream_and_wait(chan, targs.statusprompt, ""); ast_stream_and_wait(chan, targs.statusprompt, "");
snprintf(namerecloc,sizeof(namerecloc),"%s/followme.%s",ast_config_AST_SPOOL_DIR,chan->uniqueid); snprintf(namerecloc,sizeof(namerecloc),"%s/followme.%s",ast_config_AST_SPOOL_DIR,chan->uniqueid);
duration = 5; duration = 5;
if (ast_test_flag(&targs.followmeflags, FOLLOWMEFLAG_RECORDNAME)) if (ast_test_flag(&targs.followmeflags, FOLLOWMEFLAG_RECORDNAME))
if (ast_play_and_record(chan, "vm-rec-name", namerecloc, 5, "sln", &duration, 128, 0, NULL) < 0) if (ast_play_and_record(chan, "vm-rec-name", namerecloc, 5, "sln", &duration, ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE), 0, NULL) < 0)
goto outrun; goto outrun;
if (!ast_fileexists(namerecloc, NULL, chan->language)) if (!ast_fileexists(namerecloc, NULL, chan->language))
ast_copy_string(namerecloc, "", sizeof(namerecloc)); ast_copy_string(namerecloc, "", sizeof(namerecloc));
if (ast_streamfile(chan, targs.plsholdprompt, chan->language)) if (ast_streamfile(chan, targs.plsholdprompt, chan->language))
goto outrun; goto outrun;
if (ast_waitstream(chan, "") < 0) if (ast_waitstream(chan, "") < 0)
goto outrun; goto outrun;
ast_moh_start(chan, S_OR(targs.mohclass, NULL), NULL); ast_moh_start(chan, S_OR(targs.mohclass, NULL), NULL);
targs.status = 0; targs.status = 0;
targs.chan = chan; targs.chan = chan;
ast_copy_string(targs.namerecloc, namerecloc, sizeof(targs.namerecloc)); ast_copy_string(targs.namerecloc, namerecloc, sizeof(targs.namerecloc));
findmeexec(&targs); findmeexec(&targs);
while ((nm = AST_LIST_REMOVE_HEAD(&targs.cnumbers, entry))) while ((nm = AST_LIST_REMOVE_HEAD(&targs.cnumbers, entry)))
ast_free(nm); ast_free(nm);
if (!ast_strlen_zero(namerecloc)) if (!ast_strlen_zero(namerecloc))
unlink(namerecloc); unlink(namerecloc);
if (targs.status != 100) { if (targs.status != 100) {
ast_moh_stop(chan); ast_moh_stop(chan);
if (ast_test_flag(&targs.followmeflags, FOLLOWMEFLAG_UNREACHABLEMSG)) if (ast_test_flag(&targs.followmeflags, FOLLOWMEFLAG_UNREACHABLEMSG))
@ -989,12 +981,12 @@ static int app_exec(struct ast_channel *chan, void *data)
caller = chan; caller = chan;
outbound = targs.outbound; outbound = targs.outbound;
/* Bridge the two channels. */ /* Bridge the two channels. */
memset(&config,0,sizeof(struct ast_bridge_config)); memset(&config, 0, sizeof(config));
ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT); ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON); ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON); ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
ast_moh_stop(caller); ast_moh_stop(caller);
/* Be sure no generators are left on it */ /* Be sure no generators are left on it */
ast_deactivate_generator(caller); ast_deactivate_generator(caller);
@ -1006,7 +998,7 @@ static int app_exec(struct ast_channel *chan, void *data)
goto outrun; goto outrun;
} }
time(&answer_time); time(&answer_time);
res = ast_bridge_call(caller,outbound,&config); res = ast_bridge_call(caller, outbound, &config);
time(&end_time); time(&end_time);
snprintf(toast, sizeof(toast), "%ld", (long)(end_time - start_time)); snprintf(toast, sizeof(toast), "%ld", (long)(end_time - start_time));
pbx_builtin_setvar_helper(caller, "DIALEDTIME", toast); pbx_builtin_setvar_helper(caller, "DIALEDTIME", toast);
@ -1017,7 +1009,7 @@ static int app_exec(struct ast_channel *chan, void *data)
} }
outrun: outrun:
return res; return res;
} }
@ -1051,7 +1043,7 @@ static int reload(void)
{ {
reload_followme(1); reload_followme(1);
return 0; return 0;
} }
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Find-Me/Follow-Me Application", AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Find-Me/Follow-Me Application",

View File

@ -1699,7 +1699,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int c
"%s/meetme/meetme-username-%s-%d", ast_config_AST_SPOOL_DIR, "%s/meetme/meetme-username-%s-%d", ast_config_AST_SPOOL_DIR,
conf->confno, user->user_no); conf->confno, user->user_no);
if (confflags & CONFFLAG_INTROUSERNOREVIEW) if (confflags & CONFFLAG_INTROUSERNOREVIEW)
res = ast_play_and_record(chan, "vm-rec-name", user->namerecloc, 10, "sln", &duration, 128, 0, NULL); res = ast_play_and_record(chan, "vm-rec-name", user->namerecloc, 10, "sln", &duration, ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE), 0, NULL);
else else
res = ast_record_review(chan, "vm-rec-name", user->namerecloc, 10, "sln", &duration, NULL); res = ast_record_review(chan, "vm-rec-name", user->namerecloc, 10, "sln", &duration, NULL);
if (res == -1) if (res == -1)

View File

@ -2360,7 +2360,6 @@ static int load_config(int reload)
/* First, set some default settings */ /* First, set some default settings */
global_externnotify[0] = '\0'; global_externnotify[0] = '\0';
global_logfile[0] = '\0'; global_logfile[0] = '\0';
global_silencethreshold = 256;
global_vmmaxmessage = 2000; global_vmmaxmessage = 2000;
global_maxgreet = 2000; global_maxgreet = 2000;
global_vmminmessage = 0; global_vmminmessage = 0;
@ -2375,6 +2374,8 @@ static int load_config(int reload)
memset(&global_stats, 0, sizeof(global_stats)); memset(&global_stats, 0, sizeof(global_stats));
global_stats.reset = ast_tvnow(); global_stats.reset = ast_tvnow();
global_silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE);
/* Make sure we could load configuration file */ /* Make sure we could load configuration file */
if (!cfg) { if (!cfg) {
ast_log(LOG_WARNING, "Failed to load configuration file. Module activated with default settings.\n"); ast_log(LOG_WARNING, "Failed to load configuration file. Module activated with default settings.\n");
@ -2640,7 +2641,7 @@ static char *handle_minivm_show_settings(struct ast_cli_entry *e, int cmd, struc
ast_cli(a->fd, "\n"); ast_cli(a->fd, "\n");
ast_cli(a->fd, " Mail command (shell): %s\n", global_mailcmd); ast_cli(a->fd, " Mail command (shell): %s\n", global_mailcmd);
ast_cli(a->fd, " Max silence: %d\n", global_maxsilence); ast_cli(a->fd, " Max silence: %d\n", global_maxsilence);
ast_cli(a->fd, " Silence treshold: %d\n", global_silencethreshold); ast_cli(a->fd, " Silence threshold: %d\n", global_silencethreshold);
ast_cli(a->fd, " Max message length (secs): %d\n", global_vmmaxmessage); ast_cli(a->fd, " Max message length (secs): %d\n", global_vmmaxmessage);
ast_cli(a->fd, " Min message length (secs): %d\n", global_vmminmessage); ast_cli(a->fd, " Min message length (secs): %d\n", global_vmminmessage);
ast_cli(a->fd, " Default format: %s\n", default_vmformat); ast_cli(a->fd, " Default format: %s\n", default_vmformat);

View File

@ -243,7 +243,7 @@ static int record_exec(struct ast_channel *chan, void *data)
ast_log(LOG_WARNING, "Unable to create silence detector :(\n"); ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
return -1; return -1;
} }
ast_dsp_set_threshold(sildet, 256); ast_dsp_set_threshold(sildet, ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE));
} }
/* Create the directory if it does not exist. */ /* Create the directory if it does not exist. */

View File

@ -8399,7 +8399,7 @@ static int load_config(int reload)
} }
/* Silence treshold */ /* Silence treshold */
silencethreshold = 256; silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE);
if ((val = ast_variable_retrieve(cfg, "general", "silencethreshold"))) if ((val = ast_variable_retrieve(cfg, "general", "silencethreshold")))
silencethreshold = atoi(val); silencethreshold = atoi(val);

View File

@ -29,6 +29,12 @@
* *
* \author David C. Troy <dave@popvox.com> * \author David C. Troy <dave@popvox.com>
* *
* \brief Wait For Noise
* The same as Wait For Silence but listenes noise on the chennel that is above \n
* the pre-configured silence threshold from dsp.conf
*
* \author Philipp Skadorov <skadorov@yahoo.com>
*
* \ingroup applications * \ingroup applications
*/ */
@ -42,9 +48,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/dsp.h" #include "asterisk/dsp.h"
#include "asterisk/module.h" #include "asterisk/module.h"
static char *app = "WaitForSilence"; static char *app_silence = "WaitForSilence";
static char *synopsis = "Waits for a specified amount of silence"; static char *synopsis_silence = "Waits for a specified amount of silence";
static char *descrip = static char *descrip_silence =
" WaitForSilence(silencerequired[,iterations][,timeout]):\n" " WaitForSilence(silencerequired[,iterations][,timeout]):\n"
"Wait for Silence: Waits for up to 'silencerequired' \n" "Wait for Silence: Waits for up to 'silencerequired' \n"
"milliseconds of silence, 'iterations' times or once if omitted.\n" "milliseconds of silence, 'iterations' times or once if omitted.\n"
@ -68,15 +74,24 @@ static char *descrip =
"SILENCE - if exited with silence detected\n" "SILENCE - if exited with silence detected\n"
"TIMEOUT - if exited without silence detected after timeout\n"; "TIMEOUT - if exited without silence detected after timeout\n";
static int do_waiting(struct ast_channel *chan, int silencereqd, time_t waitstart, int timeout) { static char *app_noise = "WaitForNoise";
static char *synopsis_noise = "Waits for a specified amount of noise";
static char *descrip_noise =
"WaitForNoise(noiserequired[,iterations][,timeout]) \n"
"Wait for Noise: The same as Wait for Silance but waits for noise that is above the threshold specified\n";
static int do_waiting(struct ast_channel *chan, int timereqd, time_t waitstart, int timeout, int wait_for_silence) {
struct ast_frame *f; struct ast_frame *f;
int dspsilence = 0; int dsptime = 0;
static int silencethreshold = 128;
int rfmt = 0; int rfmt = 0;
int res = 0; int res = 0;
struct ast_dsp *sildet; /* silence detector dsp */ struct ast_dsp *sildet; /* silence detector dsp */
time_t now; time_t now;
/*Either silence or noise calc depending on wait_for_silence flag*/
int (*ast_dsp_func)(struct ast_dsp*, struct ast_frame*, int*) =
wait_for_silence ? ast_dsp_silence : ast_dsp_noise;
rfmt = chan->readformat; /* Set to linear mode */ rfmt = chan->readformat; /* Set to linear mode */
res = ast_set_read_format(chan, AST_FORMAT_SLINEAR); res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
if (res < 0) { if (res < 0) {
@ -89,15 +104,15 @@ static int do_waiting(struct ast_channel *chan, int silencereqd, time_t waitstar
ast_log(LOG_WARNING, "Unable to create silence detector :(\n"); ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
return -1; return -1;
} }
ast_dsp_set_threshold(sildet, silencethreshold); ast_dsp_set_threshold(sildet, ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE));
/* Await silence... */ /* Await silence... */
f = NULL; f = NULL;
for(;;) { for(;;) {
/* Start with no silence received */ /* Start with no silence received */
dspsilence = 0; dsptime = 0;
res = ast_waitfor(chan, silencereqd); res = ast_waitfor(chan, timereqd);
/* Must have gotten a hangup; let's exit */ /* Must have gotten a hangup; let's exit */
if (res <= 0) { if (res <= 0) {
@ -107,30 +122,36 @@ static int do_waiting(struct ast_channel *chan, int silencereqd, time_t waitstar
/* We waited and got no frame; sounds like digital silence or a muted digital channel */ /* We waited and got no frame; sounds like digital silence or a muted digital channel */
if (!res) { if (!res) {
dspsilence = silencereqd; dsptime = timereqd;
} else { } else {
/* Looks like we did get a frame, so let's check it out */ /* Looks like we did get a frame, so let's check it out */
f = ast_read(chan); f = ast_read(chan);
if (!f) if (!f)
break; break;
if (f && f->frametype == AST_FRAME_VOICE) { if (f && f->frametype == AST_FRAME_VOICE) {
ast_dsp_silence(sildet, f, &dspsilence); ast_dsp_func(sildet, f, &dsptime);
ast_frfree(f); ast_frfree(f);
} }
} }
ast_verb(3, "Got %dms silence< %dms required\n", dspsilence, silencereqd); if (wait_for_silence)
ast_verb(6, "Got %dms silence < %dms required\n", dsptime, timereqd);
else
ast_verb(6, "Got %dms noise < %dms required\n", dsptime, timereqd);
if (dspsilence >= silencereqd) { if (dsptime >= timereqd) {
ast_verb(3, "Exiting with %dms silence >= %dms required\n", dspsilence, silencereqd); if (wait_for_silence)
ast_verb(3, "Exiting with %dms silence >= %dms required\n", dsptime, timereqd);
else
ast_verb(3, "Exiting with %dms noise >= %dms required\n", dsptime, timereqd);
/* Ended happily with silence */ /* Ended happily with silence */
res = 1; res = 1;
pbx_builtin_setvar_helper(chan, "WAITSTATUS", "SILENCE"); pbx_builtin_setvar_helper(chan, "WAITSTATUS", wait_for_silence ? "SILENCE" : "NOISE");
ast_debug(1, "WAITSTATUS was set to SILENCE\n"); ast_debug(1, "WAITSTATUS was set to %s\n", wait_for_silence ? "SILENCE" : "NOISE");
break; break;
} }
if ( timeout && (difftime(time(&now),waitstart) >= timeout) ) { if (timeout && (difftime(time(&now), waitstart) >= timeout)) {
pbx_builtin_setvar_helper(chan, "WAITSTATUS", "TIMEOUT"); pbx_builtin_setvar_helper(chan, "WAITSTATUS", "TIMEOUT");
ast_debug(1, "WAITSTATUS was set to TIMEOUT\n"); ast_debug(1, "WAITSTATUS was set to TIMEOUT\n");
res = 0; res = 0;
@ -146,43 +167,60 @@ static int do_waiting(struct ast_channel *chan, int silencereqd, time_t waitstar
return res; return res;
} }
static int waitforsilence_exec(struct ast_channel *chan, void *data) static int waitfor_exec(struct ast_channel *chan, void *data, int wait_for_silence)
{ {
int res = 1; int res = 1;
int silencereqd = 1000; int timereqd = 1000;
int timeout = 0; int timeout = 0;
int iterations = 1, i; int iterations = 1, i;
time_t waitstart; time_t waitstart;
res = ast_answer(chan); /* Answer the channel */ res = ast_answer(chan); /* Answer the channel */
if (!data || ( (sscanf(data, "%d,%d,%d", &silencereqd, &iterations, &timeout) != 3) && if (!data || ( (sscanf(data, "%d,%d,%d", &timereqd, &iterations, &timeout) != 3) &&
(sscanf(data, "%d|%d", &silencereqd, &iterations) != 2) && (sscanf(data, "%d,%d", &timereqd, &iterations) != 2) &&
(sscanf(data, "%d", &silencereqd) != 1) ) ) { (sscanf(data, "%d", &timereqd) != 1) ) ) {
ast_log(LOG_WARNING, "Using default value of 1000ms, 1 iteration, no timeout\n"); ast_log(LOG_WARNING, "Using default value of 1000ms, 1 iteration, no timeout\n");
} }
ast_verb(3, "Waiting %d time(s) for %d ms silence with %d timeout\n", iterations, silencereqd, timeout); ast_verb(3, "Waiting %d time(s) for %d ms silence with %d timeout\n", iterations, timereqd, timeout);
time(&waitstart); time(&waitstart);
res = 1; res = 1;
for (i=0; (i<iterations) && (res == 1); i++) { for (i=0; (i<iterations) && (res == 1); i++) {
res = do_waiting(chan, silencereqd, waitstart, timeout); res = do_waiting(chan, timereqd, waitstart, timeout, wait_for_silence);
} }
if (res > 0) if (res > 0)
res = 0; res = 0;
return res; return res;
} }
static int waitforsilence_exec(struct ast_channel *chan, void *data)
{
return waitfor_exec(chan, data, 1);
}
static int waitfornoise_exec(struct ast_channel *chan, void *data)
{
return waitfor_exec(chan, data, 0);
}
static int unload_module(void) static int unload_module(void)
{ {
return ast_unregister_application(app); int res;
res = ast_unregister_application(app_silence);
res |= ast_unregister_application(app_noise);
return res;
} }
static int load_module(void) static int load_module(void)
{ {
return ast_register_application(app, waitforsilence_exec, synopsis, descrip); int res;
res = ast_register_application(app_silence, waitforsilence_exec, synopsis_silence, descrip_silence);
res |= ast_register_application(app_noise, waitfornoise_exec, synopsis_noise, descrip_noise);
return res;
} }
AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Wait For Silence"); AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Wait For Silence");

7
configs/dsp.conf.sample Normal file
View File

@ -0,0 +1,7 @@
[default]
;
; Length of sound (in milliseconds) before a period of silence is considered
; to be a change from talking to silence or a period of noise converts silence
; to talking. [default=256]
;
;silencethreshold=256

View File

@ -58,6 +58,13 @@
struct ast_dsp; struct ast_dsp;
enum threshold {
/* Array offsets */
THRESHOLD_SILENCE = 0,
/* Always the last */
THRESHOLD_MAX = 1,
};
struct ast_dsp *ast_dsp_new(void); struct ast_dsp *ast_dsp_new(void);
void ast_dsp_free(struct ast_dsp *dsp); void ast_dsp_free(struct ast_dsp *dsp);
@ -84,6 +91,10 @@ struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp,
number of seconds of silence */ number of seconds of silence */
int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence); int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence);
/*! \brief Return non-zero if this is noise. Updates "totalnoise" with the total
number of seconds of noise */
int ast_dsp_noise(struct ast_dsp *dsp, struct ast_frame *f, int *totalnoise);
/*! \brief Return non-zero if historically this should be a busy, request that /*! \brief Return non-zero if historically this should be a busy, request that
ast_dsp_silence has already been called */ ast_dsp_silence has already been called */
int ast_dsp_busydetect(struct ast_dsp *dsp); int ast_dsp_busydetect(struct ast_dsp *dsp);
@ -115,4 +126,12 @@ int ast_dsp_get_tstate(struct ast_dsp *dsp);
/*! \brief Get tcount (Threshold counter) */ /*! \brief Get tcount (Threshold counter) */
int ast_dsp_get_tcount(struct ast_dsp *dsp); int ast_dsp_get_tcount(struct ast_dsp *dsp);
/*! \brief Get silence threshold from dsp.conf*/
int ast_dsp_get_threshold_from_settings(enum threshold which);
/* \brief Reloads dsp settings from dsp.conf*/
int ast_dsp_reload(void);
int ast_dsp_init(void);
#endif /* _ASTERISK_DSP_H */ #endif /* _ASTERISK_DSP_H */

View File

@ -1268,7 +1268,7 @@ int ast_unlock_path(const char *path)
int ast_record_review(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, const char *path) int ast_record_review(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, const char *path)
{ {
int silencethreshold = 128; int silencethreshold;
int maxsilence = 0; int maxsilence = 0;
int res = 0; int res = 0;
int cmd = 0; int cmd = 0;
@ -1286,6 +1286,8 @@ int ast_record_review(struct ast_channel *chan, const char *playfile, const char
cmd = '3'; /* Want to start by recording */ cmd = '3'; /* Want to start by recording */
silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE);
while ((cmd >= 0) && (cmd != 't')) { while ((cmd >= 0) && (cmd != 't')) {
switch (cmd) { switch (cmd) {
case '1': case '1':

View File

@ -121,6 +121,7 @@ int daemon(int, int); /* defined in libresolv of all places */
#include "asterisk/linkedlists.h" #include "asterisk/linkedlists.h"
#include "asterisk/devicestate.h" #include "asterisk/devicestate.h"
#include "asterisk/module.h" #include "asterisk/module.h"
#include "asterisk/dsp.h"
#include "asterisk/doxyref.h" /* Doxygen documentation */ #include "asterisk/doxyref.h" /* Doxygen documentation */
@ -3218,7 +3219,7 @@ int main(int argc, char *argv[])
} }
ast_rtp_init(); ast_rtp_init();
ast_dsp_init();
ast_udptl_init(); ast_udptl_init();
if (ast_image_init()) { if (ast_image_init()) {

View File

@ -53,6 +53,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/alaw.h" #include "asterisk/alaw.h"
#include "asterisk/utils.h" #include "asterisk/utils.h"
#include "asterisk/options.h" #include "asterisk/options.h"
#include "asterisk/config.h"
/*! Number of goertzels for progress detect */ /*! Number of goertzels for progress detect */
enum gsamp_size { enum gsamp_size {
@ -193,6 +194,8 @@ enum gsamp_thresh {
#define SAMPLES_IN_FRAME 160 #define SAMPLES_IN_FRAME 160
#define CONFIG_FILE_NAME "dsp.conf"
typedef struct { typedef struct {
int v2; int v2;
int v3; int v3;
@ -272,6 +275,8 @@ static char dtmf_positions[] = "123A" "456B" "789C" "*0#D";
static char bell_mf_positions[] = "1247C-358A--69*---0B----#"; static char bell_mf_positions[] = "1247C-358A--69*---0B----#";
static int thresholds[THRESHOLD_MAX];
static inline void goertzel_sample(goertzel_state_t *s, short sample) static inline void goertzel_sample(goertzel_state_t *s, short sample)
{ {
int v1; int v1;
@ -1021,7 +1026,7 @@ int ast_dsp_call_progress(struct ast_dsp *dsp, struct ast_frame *inf)
return __ast_dsp_call_progress(dsp, inf->data, inf->datalen / 2); return __ast_dsp_call_progress(dsp, inf->data, inf->datalen / 2);
} }
static int __ast_dsp_silence(struct ast_dsp *dsp, short *s, int len, int *totalsilence) static int __ast_dsp_silence_noise(struct ast_dsp *dsp, short *s, int len, int *totalsilence, int *totalnoise)
{ {
int accum; int accum;
int x; int x;
@ -1073,6 +1078,8 @@ static int __ast_dsp_silence(struct ast_dsp *dsp, short *s, int len, int *totals
} }
if (totalsilence) if (totalsilence)
*totalsilence = dsp->totalsilence; *totalsilence = dsp->totalsilence;
if (totalnoise)
*totalnoise = dsp->totalnoise;
return res; return res;
} }
@ -1179,9 +1186,28 @@ int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
} }
s = f->data; s = f->data;
len = f->datalen/2; len = f->datalen/2;
return __ast_dsp_silence(dsp, s, len, totalsilence); return __ast_dsp_silence_noise(dsp, s, len, totalsilence, NULL);
} }
int ast_dsp_noise(struct ast_dsp *dsp, struct ast_frame *f, int *totalnoise)
{
short *s;
int len;
if (f->frametype != AST_FRAME_VOICE) {
ast_log(LOG_WARNING, "Can't calculate noise on a non-voice frame\n");
return 0;
}
if (f->subclass != AST_FORMAT_SLINEAR) {
ast_log(LOG_WARNING, "Can only calculate noise on signed-linear frames :(\n");
return 0;
}
s = f->data;
len = f->datalen/2;
return __ast_dsp_silence_noise(dsp, s, len, NULL, totalnoise);
}
struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *af) struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *af)
{ {
int silence; int silence;
@ -1236,7 +1262,7 @@ struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp,
ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass)); ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass));
return af; return af;
} }
silence = __ast_dsp_silence(dsp, shortdata, len, NULL); res = __ast_dsp_silence_noise(dsp, shortdata, len, &silence, NULL);
if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) { if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
memset(&dsp->f, 0, sizeof(dsp->f)); memset(&dsp->f, 0, sizeof(dsp->f));
dsp->f.frametype = AST_FRAME_NULL; dsp->f.frametype = AST_FRAME_NULL;
@ -1516,3 +1542,42 @@ int ast_dsp_get_tcount(struct ast_dsp *dsp)
{ {
return dsp->tcount; return dsp->tcount;
} }
static int _dsp_init(int reload)
{
struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
struct ast_config *cfg;
struct ast_variable *var;
cfg = ast_config_load(CONFIG_FILE_NAME, config_flags);
if (cfg && cfg != CONFIG_STATUS_FILEUNCHANGED) {
const char *value;
value = ast_variable_retrieve(cfg, "default", "silencethreshold");
if (value && sscanf(value, "%d", &thresholds[THRESHOLD_SILENCE]) != 1) {
ast_log(LOG_WARNING, "%s: '%s' is not a valid silencethreshold value\n", CONFIG_FILE_NAME, var->value);
thresholds[THRESHOLD_SILENCE] = 256;
} else if (!value)
thresholds[THRESHOLD_SILENCE] = 256;
ast_config_destroy(cfg);
}
return 0;
}
int ast_dsp_get_threshold_from_settings(enum threshold which)
{
return thresholds[which];
}
int ast_dsp_init(void)
{
return _dsp_init(0);
}
int ast_dsp_reload(void)
{
return _dsp_init(1);
}

View File

@ -47,6 +47,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/http.h" #include "asterisk/http.h"
#include "asterisk/lock.h" #include "asterisk/lock.h"
#include "asterisk/features.h" #include "asterisk/features.h"
#include "asterisk/dsp.h"
#ifdef DLFCNCOMPAT #ifdef DLFCNCOMPAT
#include "asterisk/dlfcn-compat.h" #include "asterisk/dlfcn-compat.h"
@ -249,6 +250,7 @@ static struct reload_classes {
{ "http", ast_http_reload }, { "http", ast_http_reload },
{ "logger", logger_reload }, { "logger", logger_reload },
{ "features", ast_features_reload }, { "features", ast_features_reload },
{ "dsp", ast_dsp_reload},
{ NULL, NULL } { NULL, NULL }
}; };

View File

@ -1296,7 +1296,7 @@ static int handle_recordfile(struct ast_channel *chan, AGI *agi, int argc, char
ast_log(LOG_WARNING, "Unable to create silence detector :(\n"); ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
return -1; return -1;
} }
ast_dsp_set_threshold(sildet, 256); ast_dsp_set_threshold(sildet, ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE));
} }
/* backward compatibility, if no offset given, arg[6] would have been /* backward compatibility, if no offset given, arg[6] would have been