No subject


Thu Jul 12 09:23:04 CDT 2007


(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


Modified:
    branches/1.4/apps/app_amd.c

Modified: branches/1.4/apps/app_amd.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/apps/app_amd.c?view=diff&rev=101649&r1=101648&r2=101649
==============================================================================
--- branches/1.4/apps/app_amd.c (original)
+++ branches/1.4/apps/app_amd.c Thu Jan 31 18:06:37 2008
@@ -86,19 +86,22 @@
 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 @@
 	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 @@
 	} 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 @@
 	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 @@
 			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 @@
 			}
 
 			/* 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 @@
 					ast_frfree(f);
 					strcpy(amdStatus , "MACHINE");
 					sprintf(amdCause , "INITIALSILENCE-%d-%d", silenceDuration, initialSilence);
+					res = 1;
 					break;
 				}
 				
@@ -239,6 +268,7 @@
 					ast_frfree(f);
 					strcpy(amdStatus , "HUMAN");
 					sprintf(amdCause , "HUMAN-%d-%d", silenceDuration, afterGreetingSilence);
+					res = 1;
 					break;
 				}
 				
@@ -262,6 +292,7 @@
 					ast_frfree(f);
 					strcpy(amdStatus , "MACHINE");
 					sprintf(amdCause , "MAXWORDS-%d-%d", iWordsCount, maximumNumberOfWords);
+					res = 1;
 					break;
 				}
 				
@@ -271,6 +302,7 @@
 					ast_frfree(f);
 					strcpy(amdStatus , "MACHINE");
 					sprintf(amdCause , "LONGGREETING-%d-%d", voiceDuration, greeting);
+					res = 1;
 					break;
 				}
 				




More information about the asterisk-commits mailing list