aboutsummaryrefslogtreecommitdiffstats
path: root/apps/app_amd.c
diff options
context:
space:
mode:
authormmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b>2007-12-28 16:12:06 +0000
committermmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b>2007-12-28 16:12:06 +0000
commita0cbc07523ca73034553d2a5b87505e782d1252c (patch)
tree038205fd77c870a128535f67db3af599eb8da47c /apps/app_amd.c
parent02ba3674218cfdf369142e23949ab22733ec0654 (diff)
Some changes to app_amd.
The channel name is printed in verbose messages maximumWordLength option added. Duration of words that do not meet the minimum word duration will be logged The duration of pre-greeting silence will be logged Only consider us in the greeting if we actually detected a valid word duration. (closes issue #11650, reported and patched by davevg) git-svn-id: http://svn.digium.com/svn/asterisk/trunk@95167 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'apps/app_amd.c')
-rw-r--r--apps/app_amd.c59
1 files changed, 43 insertions, 16 deletions
diff --git a/apps/app_amd.c b/apps/app_amd.c
index 556fceec6..4e440d388 100644
--- a/apps/app_amd.c
+++ b/apps/app_amd.c
@@ -45,7 +45,7 @@ static char *synopsis = "Attempts to detect answering machines";
static char *descrip =
" AMD([initialSilence],[greeting],[afterGreetingSilence],[totalAnalysisTime]\n"
" ,[minimumWordLength],[betweenWordsSilence],[maximumNumberOfWords]\n"
-" ,[silenceThreshold])\n"
+" ,[silenceThreshold],[|maximumWordLength])\n"
" This application attempts to detect answering machines at the beginning\n"
" of outbound calls. Simply call this application after the call\n"
" has been answered (outbound only, of course).\n"
@@ -65,6 +65,7 @@ static char *descrip =
"- 'maximumNumberOfWords'is the maximum number of words in the greeting. \n"
" If exceeded then MACHINE.\n"
"- 'silenceThreshold' is the silence threshold.\n"
+"- 'maximumWordLength' is the maximum duration of a word to accept. If exceeded then MACHINE\n"
"This application sets the following channel variables upon completion:\n"
" AMDSTATUS - This is the status of the answering machine detection.\n"
" Possible values are:\n"
@@ -75,7 +76,8 @@ static char *descrip =
" INITIALSILENCE-<%d silenceDuration>-<%d initialSilence>\n"
" HUMAN-<%d silenceDuration>-<%d afterGreetingSilence>\n"
" MAXWORDS-<%d wordsCount>-<%d maximumNumberOfWords>\n"
-" LONGGREETING-<%d voiceDuration>-<%d greeting>\n";
+" LONGGREETING-<%d voiceDuration>-<%d greeting>\n"
+" MAXWORDLENGTH-<%d consecutiveVoiceDuration>\n";
#define STATE_IN_WORD 1
#define STATE_IN_SILENCE 2
@@ -89,6 +91,7 @@ static int dfltMinimumWordLength = 100;
static int dfltBetweenWordsSilence = 50;
static int dfltMaximumNumberOfWords = 3;
static int dfltSilenceThreshold = 256;
+static int dfltMaximumWordLength = 5000; /* Setting this to a large default so it is not used unless specify it in the configs or command line */
static void isAnsweringMachine(struct ast_channel *chan, void *data)
{
@@ -120,6 +123,7 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data)
int betweenWordsSilence = dfltBetweenWordsSilence;
int maximumNumberOfWords = dfltMaximumNumberOfWords;
int silenceThreshold = dfltSilenceThreshold;
+ int maximumWordLength = dfltMaximumWordLength;
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(argInitialSilence);
@@ -130,6 +134,7 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data)
AST_APP_ARG(argBetweenWordsSilence);
AST_APP_ARG(argMaximumNumberOfWords);
AST_APP_ARG(argSilenceThreshold);
+ AST_APP_ARG(argMaximumWordLength);
);
ast_verb(3, "AMD: %s %s %s (Fmt: %d)\n", chan->name ,chan->cid.cid_ani, chan->cid.cid_rdnis, chan->readformat);
@@ -154,15 +159,17 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data)
maximumNumberOfWords = atoi(args.argMaximumNumberOfWords);
if (!ast_strlen_zero(args.argSilenceThreshold))
silenceThreshold = atoi(args.argSilenceThreshold);
+ if (!ast_strlen_zero(args.argMaximumWordLength))
+ maximumWordLength = atoi(args.argMaximumWordLength);
} else {
ast_debug(1, "AMD using the default parameters.\n");
}
/* Now we're ready to roll! */
ast_verb(3, "AMD: initialSilence [%d] greeting [%d] afterGreetingSilence [%d] "
- "totalAnalysisTime [%d] minimumWordLength [%d] betweenWordsSilence [%d] maximumNumberOfWords [%d] silenceThreshold [%d] \n",
+ "totalAnalysisTime [%d] minimumWordLength [%d] betweenWordsSilence [%d] maximumNumberOfWords [%d] silenceThreshold [%d] maximumWordLength [%d] \n",
initialSilence, greeting, afterGreetingSilence, totalAnalysisTime,
- minimumWordLength, betweenWordsSilence, maximumNumberOfWords, silenceThreshold );
+ minimumWordLength, betweenWordsSilence, maximumNumberOfWords, silenceThreshold, maximumWordLength);
/* Set read format to signed linear so we get signed linear frames in */
readFormat = chan->readformat;
@@ -188,7 +195,7 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data)
while ((res = ast_waitfor(chan, totalAnalysisTime)) > -1) {
/* If we fail to read in a frame, that means they hung up */
if (!(f = ast_read(chan))) {
- ast_verb(3, "AMD: HANGUP\n");
+ ast_verb(3, "AMD: Channel [%s]. HANGUP\n", chan->name);
ast_debug(1, "Got hangup\n");
strcpy(amdStatus, "HANGUP");
break;
@@ -215,15 +222,19 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data)
if (silenceDuration >= betweenWordsSilence) {
if (currentState != STATE_IN_SILENCE ) {
previousState = currentState;
- ast_verb(3, "AMD: Changed state to STATE_IN_SILENCE\n");
+ ast_verb(3, "AMD: Channel [%s]. Changed state to STATE_IN_SILENCE\n", chan->name);
}
+ /* Find words less than word duration */
+ if (consecutiveVoiceDuration < minimumWordLength && consecutiveVoiceDuration > 0){
+ ast_verb(3, "AMD: Channel [%s]. Short Word Duration: %d\n", chan->name, consecutiveVoiceDuration);
+ }
currentState = STATE_IN_SILENCE;
consecutiveVoiceDuration = 0;
}
if (inInitialSilence == 1 && silenceDuration >= initialSilence) {
- ast_verb(3, "AMD: ANSWERING MACHINE: silenceDuration:%d initialSilence:%d\n",
- silenceDuration, initialSilence);
+ ast_verb(3, "AMD: Channel [%s]. ANSWERING MACHINE: silenceDuration:%d initialSilence:%d\n",
+ chan->name, silenceDuration, initialSilence);
ast_frfree(f);
strcpy(amdStatus , "MACHINE");
sprintf(amdCause , "INITIALSILENCE-%d-%d", silenceDuration, initialSilence);
@@ -231,8 +242,8 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data)
}
if (silenceDuration >= afterGreetingSilence && inGreeting == 1) {
- ast_verb(3, "AMD: HUMAN: silenceDuration:%d afterGreetingSilence:%d\n",
- silenceDuration, afterGreetingSilence);
+ ast_verb(3, "AMD: Channel [%s]. HUMAN: silenceDuration:%d afterGreetingSilence:%d\n",
+ chan->name, silenceDuration, afterGreetingSilence);
ast_frfree(f);
strcpy(amdStatus , "HUMAN");
sprintf(amdCause , "HUMAN-%d-%d", silenceDuration, afterGreetingSilence);
@@ -247,13 +258,19 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data)
number of words if my previous state was Silence, which means that I moved into a word. */
if (consecutiveVoiceDuration >= minimumWordLength && currentState == STATE_IN_SILENCE) {
iWordsCount++;
- ast_verb(3, "AMD: Word detected. iWordsCount:%d\n", iWordsCount);
+ ast_verb(3, "AMD: Channel [%s]. Word detected. iWordsCount:%d\n", chan->name, iWordsCount);
previousState = currentState;
currentState = STATE_IN_WORD;
}
-
+ if (consecutiveVoiceDuration >= maximumWordLength){
+ ast_verb(3, "AMD: Channel [%s]. Maximum Word Length detected. [%d]\n", chan->name, consecutiveVoiceDuration);
+ ast_frfree(f);
+ strcpy(amdStatus , "MACHINE");
+ sprintf(amdCause , "MAXWORDLENGTH-%d", consecutiveVoiceDuration);
+ break;
+ }
if (iWordsCount >= maximumNumberOfWords) {
- ast_verb(3, "AMD: ANSWERING MACHINE: iWordsCount:%d\n", iWordsCount);
+ ast_verb(3, "AMD: Channel [%s]. ANSWERING MACHINE: iWordsCount:%d\n", chan->name, iWordsCount);
ast_frfree(f);
strcpy(amdStatus , "MACHINE");
sprintf(amdCause , "MAXWORDS-%d-%d", iWordsCount, maximumNumberOfWords);
@@ -261,7 +278,7 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data)
}
if (inGreeting == 1 && voiceDuration >= greeting) {
- ast_verb(3, "AMD: ANSWERING MACHINE: voiceDuration:%d greeting:%d\n", voiceDuration, greeting);
+ ast_verb(3, "AMD: Channel [%s]. ANSWERING MACHINE: voiceDuration:%d greeting:%d\n", chan->name, voiceDuration, greeting);
ast_frfree(f);
strcpy(amdStatus , "MACHINE");
sprintf(amdCause , "LONGGREETING-%d-%d", voiceDuration, greeting);
@@ -269,7 +286,14 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data)
}
if (voiceDuration >= minimumWordLength ) {
+ if (silenceDuration > 0)
+ ast_verb(3, "AMD: Channel [%s]. Detected Talk, previous silence duration: %d\n", chan->name, silenceDuration);
silenceDuration = 0;
+ }
+ if (consecutiveVoiceDuration >= minimumWordLength && inGreeting == 0){
+ /* Only go in here once to change the greeting flag when we detect the 1st word */
+ if (silenceDuration > 0)
+ ast_verb(3, "AMD: Channel [%s]. Before Greeting Time: silenceDuration: %d voiceDuration: %d\n", chan->name, silenceDuration, voiceDuration);
inInitialSilence = 0;
inGreeting = 1;
}
@@ -343,6 +367,9 @@ static int load_config(int reload)
dfltBetweenWordsSilence = atoi(var->value);
} else if (!strcasecmp(var->name, "maximum_number_of_words")) {
dfltMaximumNumberOfWords = atoi(var->value);
+ } else if (!strcasecmp(var->name, "maximum_word_length")) {
+ dfltMaximumWordLength = atoi(var->value);
+
} else {
ast_log(LOG_WARNING, "%s: Cat:%s. Unknown keyword %s at line %d of amd.conf\n",
app, cat, var->name, var->lineno);
@@ -356,9 +383,9 @@ static int load_config(int reload)
ast_config_destroy(cfg);
ast_verb(3, "AMD defaults: initialSilence [%d] greeting [%d] afterGreetingSilence [%d] "
- "totalAnalysisTime [%d] minimumWordLength [%d] betweenWordsSilence [%d] maximumNumberOfWords [%d] silenceThreshold [%d] \n",
+ "totalAnalysisTime [%d] minimumWordLength [%d] betweenWordsSilence [%d] maximumNumberOfWords [%d] silenceThreshold [%d] maximumWordLength [%d]\n",
dfltInitialSilence, dfltGreeting, dfltAfterGreetingSilence, dfltTotalAnalysisTime,
- dfltMinimumWordLength, dfltBetweenWordsSilence, dfltMaximumNumberOfWords, dfltSilenceThreshold );
+ dfltMinimumWordLength, dfltBetweenWordsSilence, dfltMaximumNumberOfWords, dfltSilenceThreshold, dfltMaximumWordLength);
return 0;
}