Make this module fit the guidelines better
authorJoshua Colp <jcolp@digium.com>
Wed, 6 Sep 2006 17:05:48 +0000 (17:05 +0000)
committerJoshua Colp <jcolp@digium.com>
Wed, 6 Sep 2006 17:05:48 +0000 (17:05 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@42109 65c4cc65-6c06-0410-ace0-fbb531ad65f3

apps/app_amd.c

index 2f7148b..21e9b90 100644 (file)
@@ -88,26 +88,21 @@ static int dfltSilenceThreshold     = 256;
 
 static void isAnsweringMachine(struct ast_channel *chan, void *data)
 {
-       int res = 0, ret = 0;
-
+       int res = 0;
        struct ast_frame *f = NULL;
-
-       struct ast_dsp *silenceDetector;         /* silence detector dsp */
-       int dspsilence = 0;
-       int readFormat;
-       int framelength;
-
-       int inInitialSilence         = 1;
-       int inGreeting               = 0;
-       int voiceDuration            = 0;
-       int silenceDuration          = 0;
-       int iTotalTime               = 0;
-       int iWordsCount              = 0;
-       int currentState             = STATE_IN_SILENCE;
-       int previousState            = STATE_IN_SILENCE;
+       struct ast_dsp *silenceDetector = NULL;
+       int dspsilence = 0, readFormat, framelength;
+       int inInitialSilence = 1;
+       int inGreeting = 0;
+       int voiceDuration = 0;
+       int silenceDuration = 0;
+       int iTotalTime = 0;
+       int iWordsCount = 0;
+       int currentState = STATE_IN_SILENCE;
+       int previousState = STATE_IN_SILENCE;
        int consecutiveVoiceDuration = 0;
-       char amdCause[256]           = "";
-       char amdStatus[256]          = "";
+       char amdCause[256] = "", amdStatus[256] = "";
+       char *parse = ast_strdupa(data);
 
        /* Lets set the initial values of the variables that will control the algorithm.
           The initial values are the default ones. If they are passed as arguments
@@ -122,7 +117,6 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data)
        int maximumNumberOfWords = dfltMaximumNumberOfWords;
        int silenceThreshold     = dfltSilenceThreshold;
 
-       char *parse;
        AST_DECLARE_APP_ARGS(args,
                             AST_APP_ARG(argInitialSilence);
                             AST_APP_ARG(argGreeting);
@@ -133,98 +127,92 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data)
                             AST_APP_ARG(argMaximumNumberOfWords);
                             AST_APP_ARG(argSilenceThreshold);
        );
+
        if (option_verbose > 2)
                ast_verbose(VERBOSE_PREFIX_3 "AMD: %s %s %s (Fmt: %d)\n", chan->name ,chan->cid.cid_ani, chan->cid.cid_rdnis, chan->readformat);
 
        /* Lets parse the arguments. */
-       if (ast_strlen_zero(data)) {
-               ast_log(LOG_NOTICE, "AMD using the default parameters.\n");
-       } else {
+       if (!ast_strlen_zero(parse)) {
                /* Some arguments have been passed. Lets parse them and overwrite the defaults. */
-               parse = ast_strdupa(data);
-
                AST_STANDARD_APP_ARGS(args, parse);
-
-               if (!ast_strlen_zero(args.argInitialSilence)) {
+               if (!ast_strlen_zero(args.argInitialSilence))
                        initialSilence = atoi(args.argInitialSilence);
-               }
-               if (!ast_strlen_zero(args.argGreeting)) {
+               if (!ast_strlen_zero(args.argGreeting))
                        greeting = atoi(args.argGreeting);
-               }
-               if (!ast_strlen_zero(args.argAfterGreetingSilence)) {
+               if (!ast_strlen_zero(args.argAfterGreetingSilence))
                        afterGreetingSilence = atoi(args.argAfterGreetingSilence);
-               }
-               if (!ast_strlen_zero(args.argTotalAnalysisTime)) {
+               if (!ast_strlen_zero(args.argTotalAnalysisTime))
                        totalAnalysisTime = atoi(args.argTotalAnalysisTime);
-               }
-               if (!ast_strlen_zero(args.argMinimumWordLength)) {
+               if (!ast_strlen_zero(args.argMinimumWordLength))
                        minimumWordLength = atoi(args.argMinimumWordLength);
-               }
-               if (!ast_strlen_zero(args.argBetweenWordsSilence)) {
+               if (!ast_strlen_zero(args.argBetweenWordsSilence))
                        betweenWordsSilence = atoi(args.argBetweenWordsSilence);
-               }
-               if (!ast_strlen_zero(args.argMaximumNumberOfWords)) {
+               if (!ast_strlen_zero(args.argMaximumNumberOfWords))
                        maximumNumberOfWords = atoi(args.argMaximumNumberOfWords);
-               }
-               if (!ast_strlen_zero(args.argSilenceThreshold)) {
+               if (!ast_strlen_zero(args.argSilenceThreshold))
                        silenceThreshold = atoi(args.argSilenceThreshold);
-               }
-       }
+       } else
+               ast_log(LOG_NOTICE, "AMD using the default parameters.\n");
 
        /* Now we're ready to roll! */
-       
        if (option_verbose > 2)
                ast_verbose(VERBOSE_PREFIX_3 "AMD: initialSilence [%d] greeting [%d] afterGreetingSilence [%d] "
                "totalAnalysisTime [%d] minimumWordLength [%d] betweenWordsSilence [%d] maximumNumberOfWords [%d] silenceThreshold [%d] \n",
                                initialSilence, greeting, afterGreetingSilence, totalAnalysisTime,
                                minimumWordLength, betweenWordsSilence, maximumNumberOfWords, silenceThreshold );
 
+       /* Set read format to signed linear so we get signed linear frames in */
        readFormat = chan->readformat;
-       res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
-       if (res < 0 ) {
+       if (ast_set_read_format(chan, AST_FORMAT_SLINEAR) < 0 ) {
                ast_log(LOG_WARNING, "AMD: Channel [%s]. Unable to set to linear mode, giving up\n", chan->name );
-               pbx_builtin_setvar_helper(chan , "AMDSTATUS" , "" );
-               pbx_builtin_setvar_helper(chan , "AMDCAUSE" , "" );
+               pbx_builtin_setvar_helper(chan , "AMDSTATUS", "");
+               pbx_builtin_setvar_helper(chan , "AMDCAUSE", "");
                return;
        }
 
-       silenceDetector = ast_dsp_new();
-       if (!silenceDetector ) {
+       /* Create a new DSP that will detect the silence */
+       if (!(silenceDetector = ast_dsp_new())) {
                ast_log(LOG_WARNING, "AMD: Channel [%s]. Unable to create silence detector :(\n", chan->name );
-               pbx_builtin_setvar_helper(chan , "AMDSTATUS" , "" );
-               pbx_builtin_setvar_helper(chan , "AMDCAUSE" , "" );
+               pbx_builtin_setvar_helper(chan , "AMDSTATUS", "");
+               pbx_builtin_setvar_helper(chan , "AMDCAUSE", "");
                return;
        }
-       ast_dsp_set_threshold(silenceDetector, silenceThreshold );
 
-       while ((ret = ast_waitfor(chan, totalAnalysisTime)))
-       {
-               if (ret < 0 || !(f = ast_read(chan))) {
-                       /* No Frame OR Error on ast_waitfor : Called Party Must Have Dropped */
+       /* Set silence threshold to specified value */
+       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) {
+               /* If we fail to read in a frame, that means they hung up */
+               if (!(f = ast_read(chan))) {
                        if (option_verbose > 2)
                                ast_verbose(VERBOSE_PREFIX_3 "AMD: HANGUP\n");
                        if (option_debug)
                                ast_log(LOG_DEBUG, "Got hangup\n");
-                       strcpy(amdStatus , "HANGUP" );
-                       strcpy(amdCause , "" );
+                       strcpy(amdStatus, "HANGUP");
                        break;
                }
-               if (f->frametype == AST_FRAME_VOICE ) {
+
+               if (f->frametype == AST_FRAME_VOICE) {
+                       /* 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);
                        iTotalTime += framelength;
-                       if (iTotalTime >= totalAnalysisTime ) {
+                       if (iTotalTime >= totalAnalysisTime) {
                                if (option_verbose > 2) 
                                        ast_verbose(VERBOSE_PREFIX_3 "AMD: Channel [%s]. Too long...\n", chan->name );
                                ast_frfree(f);
-                               strcpy(amdStatus , "NOTSURE" );
-                               sprintf(amdCause , "TOOLONG-%d", iTotalTime );
+                               strcpy(amdStatus , "NOTSURE");
+                               sprintf(amdCause , "TOOLONG-%d", iTotalTime);
                                break;
                        }
+
+                       /* 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 (dspsilence) {
                                silenceDuration = dspsilence;
-                               if (silenceDuration >= betweenWordsSilence ) {
+                               
+                               if (silenceDuration >= betweenWordsSilence) {
                                        if (currentState != STATE_IN_SILENCE ) {
                                                previousState = currentState;
                                                if (option_verbose > 2)
@@ -233,87 +221,88 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data)
                                        currentState  = STATE_IN_SILENCE;
                                        consecutiveVoiceDuration = 0;
                                }
-                               if (inInitialSilence == 1  && silenceDuration >= initialSilence ) {
+                               
+                               if (inInitialSilence == 1  && silenceDuration >= initialSilence) {
                                        if (option_verbose > 2)
                                                ast_verbose(VERBOSE_PREFIX_3 "AMD: ANSWERING MACHINE: silenceDuration:%d initialSilence:%d\n",
-                                                       silenceDuration, initialSilence );
+                                                           silenceDuration, initialSilence);
                                        ast_frfree(f);
-                                       strcpy(amdStatus , "MACHINE" );
-                                       sprintf(amdCause , "INITIALSILENCE-%d-%d", silenceDuration, initialSilence );
+                                       strcpy(amdStatus , "MACHINE");
+                                       sprintf(amdCause , "INITIALSILENCE-%d-%d", silenceDuration, initialSilence);
                                        break;
                                }
-
-                               if (silenceDuration >= afterGreetingSilence  &&  inGreeting == 1 ) {
+                               
+                               if (silenceDuration >= afterGreetingSilence  &&  inGreeting == 1) {
                                        if (option_verbose > 2)
                                                ast_verbose(VERBOSE_PREFIX_3 "AMD: HUMAN: silenceDuration:%d afterGreetingSilence:%d\n",
-                                                       silenceDuration, afterGreetingSilence );
+                                                           silenceDuration, afterGreetingSilence);
                                        ast_frfree(f);
-                                       strcpy(amdStatus , "HUMAN" );
-                                       sprintf(amdCause , "HUMAN-%d-%d", silenceDuration, afterGreetingSilence );
+                                       strcpy(amdStatus , "HUMAN");
+                                       sprintf(amdCause , "HUMAN-%d-%d", silenceDuration, afterGreetingSilence);
                                        break;
                                }
+                               
                        } else {
                                consecutiveVoiceDuration += framelength;
                                voiceDuration += framelength;
-
+                               
                                /* If I have enough consecutive voice to say that I am in a Word, I can only increment the
-                                       number of words if my previous state was Silence, which means that I moved into a word. */
-                               if (consecutiveVoiceDuration >= minimumWordLength ) {
-                                       if (currentState == STATE_IN_SILENCE ) {
-                                               iWordsCount++;
-                                               if (option_verbose > 2)
-                                                       ast_verbose(VERBOSE_PREFIX_3 "AMD: Word detected. iWordsCount:%d\n", iWordsCount );
-                                               previousState = currentState;
-                                               currentState = STATE_IN_WORD;
-                                       }
+                                  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++;
+                                       if (option_verbose > 2)
+                                               ast_verbose(VERBOSE_PREFIX_3 "AMD: Word detected. iWordsCount:%d\n", iWordsCount);
+                                       previousState = currentState;
+                                       currentState = STATE_IN_WORD;
                                }
-
-                               if (iWordsCount >= maximumNumberOfWords ) {
+                               
+                               if (iWordsCount >= maximumNumberOfWords) {
                                        if (option_verbose > 2)
-                                               ast_verbose(VERBOSE_PREFIX_3 "AMD: ANSWERING MACHINE: iWordsCount:%d\n", iWordsCount );
+                                               ast_verbose(VERBOSE_PREFIX_3 "AMD: ANSWERING MACHINE: iWordsCount:%d\n", iWordsCount);
                                        ast_frfree(f);
-                                       strcpy(amdStatus , "MACHINE" );
-                                       sprintf(amdCause , "MAXWORDS-%d-%d", iWordsCount, maximumNumberOfWords );
+                                       strcpy(amdStatus , "MACHINE");
+                                       sprintf(amdCause , "MAXWORDS-%d-%d", iWordsCount, maximumNumberOfWords);
                                        break;
                                }
-
-                               if (inGreeting == 1  &&  voiceDuration >= greeting ) {
+                               
+                               if (inGreeting == 1 && voiceDuration >= greeting) {
                                        if (option_verbose > 2)
-                                       ast_verbose(VERBOSE_PREFIX_3 "AMD: ANSWERING MACHINE: voiceDuration:%d greeting:%d\n", voiceDuration, greeting);
-                                        ast_frfree(f);
-                                       strcpy(amdStatus , "MACHINE" );
-                                       sprintf(amdCause , "LONGGREETING-%d-%d", voiceDuration, greeting );
+                                               ast_verbose(VERBOSE_PREFIX_3 "AMD: ANSWERING MACHINE: voiceDuration:%d greeting:%d\n", voiceDuration, greeting);
+                                       ast_frfree(f);
+                                       strcpy(amdStatus , "MACHINE");
+                                       sprintf(amdCause , "LONGGREETING-%d-%d", voiceDuration, greeting);
                                        break;
                                }
+                               
                                if (voiceDuration >= minimumWordLength ) {
                                        silenceDuration = 0;
                                        inInitialSilence = 0;
                                        inGreeting = 1;
                                }
+                               
                        }
                }
                ast_frfree(f);
        }
-       if (!ret) {
+       
+       if (!res) {
                /* It took too long to get a frame back. Giving up. */
                if (option_verbose > 2)
-                       ast_verbose(VERBOSE_PREFIX_3 "AMD: Channel [%s]. Too long...\n", chan->name );
-               strcpy(amdStatus , "NOTSURE" );
-               sprintf(amdCause , "TOOLONG-%d", iTotalTime );
+                       ast_verbose(VERBOSE_PREFIX_3 "AMD: Channel [%s]. Too long...\n", chan->name);
+               strcpy(amdStatus , "NOTSURE");
+               sprintf(amdCause , "TOOLONG-%d", iTotalTime);
        }
 
-       pbx_builtin_setvar_helper(chan , "AMDSTATUS" , amdStatus );
-       pbx_builtin_setvar_helper(chan , "AMDCAUSE" , amdCause );
+       /* Set the status and cause on the channel */
+       pbx_builtin_setvar_helper(chan , "AMDSTATUS" , amdStatus);
+       pbx_builtin_setvar_helper(chan , "AMDCAUSE" , amdCause);
 
-       /* If We Started With A Valid Read Format, Return To It... */
-       if (readFormat && chan->_state == AST_STATE_UP) {
-               res = ast_set_read_format(chan, readFormat );
-               if (res)
-                       ast_log(LOG_WARNING, "AMD: Unable to restore read format on '%s'\n", chan->name);
-       }
+       /* Restore channel read format */
+       if (readFormat && ast_set_read_format(chan, readFormat))
+               ast_log(LOG_WARNING, "AMD: Unable to restore read format on '%s'\n", chan->name);
 
-       /* Free The Silence Detector DSP */
-       ast_dsp_free(silenceDetector );
+       /* Free the DSP used to detect silence */
+       ast_dsp_free(silenceDetector);
 
        return;
 }
@@ -321,7 +310,7 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data)
 
 static int amd_exec(struct ast_channel *chan, void *data)
 {
-       struct ast_module_user *u;
+       struct ast_module_user *u = NULL;
 
        u = ast_module_user_add(chan);
        isAnsweringMachine(chan, data);
@@ -332,13 +321,11 @@ static int amd_exec(struct ast_channel *chan, void *data)
 
 static void load_config(void)
 {
-       struct ast_config *cfg;
-       char *cat;
-       struct ast_variable *var;
+       struct ast_config *cfg = NULL;
+       char *cat = NULL;
+       struct ast_variable *var = NULL;
 
-       cfg = ast_config_load("amd.conf");
-
-       if (!cfg) {
+       if (!(cfg = ast_config_load("amd.conf"))) {
                ast_log(LOG_ERROR, "Configuration file amd.conf missing.\n");
                return;
        }
@@ -374,6 +361,7 @@ static void load_config(void)
                }
                cat = ast_category_browse(cfg, cat);
        }
+
        ast_config_destroy(cfg);
 
        if (option_verbose > 2)