aboutsummaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authormmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b>2008-02-01 00:06:37 +0000
committermmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b>2008-02-01 00:06:37 +0000
commitece4b1195387d81ba0aea1a381450ad4d5aa53f0 (patch)
tree8cef5babcbc721e146cf57201bf1b3faeeb5b5c4 /apps
parentea2e6eb3487d7c9439bb3ce6e09df803f3caa4c0 (diff)
From bugtracker: "fix totalAnalysisTime to handle periods of no channel activity"
(closes issue #9256) Reported by: cmaj Patches: amd-dont-wait-too-long-for-frames-take3.diff.txt uploaded by cmaj (license 111) Tested by: cmaj, skygreg, ZX81, rjain git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.4@101649 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'apps')
-rw-r--r--apps/app_amd.c48
1 files changed, 40 insertions, 8 deletions
diff --git a/apps/app_amd.c b/apps/app_amd.c
index e5dee1efc..52f474048 100644
--- a/apps/app_amd.c
+++ b/apps/app_amd.c
@@ -86,19 +86,22 @@ static int dfltBetweenWordsSilence = 50;
static int dfltMaximumNumberOfWords = 3;
static int dfltSilenceThreshold = 256;
+/* Set to the lowest ms value provided in amd.conf or application parameters */
+static int dfltMaxWaitTimeForFrame = 50;
+
static void isAnsweringMachine(struct ast_channel *chan, void *data)
{
int res = 0;
struct ast_frame *f = NULL;
struct ast_dsp *silenceDetector = NULL;
- int dspsilence = 0, readFormat, framelength;
+ int dspsilence = 0, readFormat, framelength = 0;
int inInitialSilence = 1;
int inGreeting = 0;
int voiceDuration = 0;
int silenceDuration = 0;
int iTotalTime = 0;
int iWordsCount = 0;
- int currentState = STATE_IN_SILENCE;
+ int currentState = STATE_IN_WORD;
int previousState = STATE_IN_SILENCE;
int consecutiveVoiceDuration = 0;
char amdCause[256] = "", amdStatus[256] = "";
@@ -116,6 +119,7 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data)
int betweenWordsSilence = dfltBetweenWordsSilence;
int maximumNumberOfWords = dfltMaximumNumberOfWords;
int silenceThreshold = dfltSilenceThreshold;
+ int maxWaitTimeForFrame = dfltMaxWaitTimeForFrame;
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(argInitialSilence);
@@ -154,6 +158,20 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data)
} else if (option_debug)
ast_log(LOG_DEBUG, "AMD using the default parameters.\n");
+ /* Find lowest ms value, that will be max wait time for a frame */
+ if (maxWaitTimeForFrame > initialSilence)
+ maxWaitTimeForFrame = initialSilence;
+ if (maxWaitTimeForFrame > greeting)
+ maxWaitTimeForFrame = greeting;
+ if (maxWaitTimeForFrame > afterGreetingSilence)
+ maxWaitTimeForFrame = afterGreetingSilence;
+ if (maxWaitTimeForFrame > totalAnalysisTime)
+ maxWaitTimeForFrame = totalAnalysisTime;
+ if (maxWaitTimeForFrame > minimumWordLength)
+ maxWaitTimeForFrame = minimumWordLength;
+ if (maxWaitTimeForFrame > betweenWordsSilence)
+ maxWaitTimeForFrame = betweenWordsSilence;
+
/* Now we're ready to roll! */
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "AMD: initialSilence [%d] greeting [%d] afterGreetingSilence [%d] "
@@ -182,7 +200,8 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data)
ast_dsp_set_threshold(silenceDetector, silenceThreshold);
/* Now we go into a loop waiting for frames from the channel */
- while ((res = ast_waitfor(chan, totalAnalysisTime)) > -1) {
+ while ((res = ast_waitfor(chan, 2 * maxWaitTimeForFrame)) > -1) {
+
/* If we fail to read in a frame, that means they hung up */
if (!(f = ast_read(chan))) {
if (option_verbose > 2)
@@ -193,9 +212,13 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data)
break;
}
- if (f->frametype == AST_FRAME_VOICE) {
+ if (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_NULL || f->frametype == AST_FRAME_CNG) {
/* If the total time exceeds the analysis time then give up as we are not too sure */
- framelength = (ast_codec_get_samples(f) / DEFAULT_SAMPLES_PER_MS);
+ if (f->frametype == AST_FRAME_VOICE)
+ framelength = (ast_codec_get_samples(f) / DEFAULT_SAMPLES_PER_MS);
+ else
+ framelength += 2 * maxWaitTimeForFrame;
+
iTotalTime += framelength;
if (iTotalTime >= totalAnalysisTime) {
if (option_verbose > 2)
@@ -207,9 +230,14 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data)
}
/* Feed the frame of audio into the silence detector and see if we get a result */
- dspsilence = 0;
- ast_dsp_silence(silenceDetector, f, &dspsilence);
- if (dspsilence) {
+ if (f->frametype != AST_FRAME_VOICE)
+ dspsilence += 2 * maxWaitTimeForFrame;
+ else {
+ dspsilence = 0;
+ ast_dsp_silence(silenceDetector, f, &dspsilence);
+ }
+
+ if (dspsilence > 0) {
silenceDuration = dspsilence;
if (silenceDuration >= betweenWordsSilence) {
@@ -229,6 +257,7 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data)
ast_frfree(f);
strcpy(amdStatus , "MACHINE");
sprintf(amdCause , "INITIALSILENCE-%d-%d", silenceDuration, initialSilence);
+ res = 1;
break;
}
@@ -239,6 +268,7 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data)
ast_frfree(f);
strcpy(amdStatus , "HUMAN");
sprintf(amdCause , "HUMAN-%d-%d", silenceDuration, afterGreetingSilence);
+ res = 1;
break;
}
@@ -262,6 +292,7 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data)
ast_frfree(f);
strcpy(amdStatus , "MACHINE");
sprintf(amdCause , "MAXWORDS-%d-%d", iWordsCount, maximumNumberOfWords);
+ res = 1;
break;
}
@@ -271,6 +302,7 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data)
ast_frfree(f);
strcpy(amdStatus , "MACHINE");
sprintf(amdCause , "LONGGREETING-%d-%d", voiceDuration, greeting);
+ res = 1;
break;
}