diff options
author | mmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b> | 2008-02-01 00:06:37 +0000 |
---|---|---|
committer | mmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b> | 2008-02-01 00:06:37 +0000 |
commit | ece4b1195387d81ba0aea1a381450ad4d5aa53f0 (patch) | |
tree | 8cef5babcbc721e146cf57201bf1b3faeeb5b5c4 /apps | |
parent | ea2e6eb3487d7c9439bb3ce6e09df803f3caa4c0 (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.c | 48 |
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; } |