diff options
author | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2003-04-28 05:07:52 +0000 |
---|---|---|
committer | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2003-04-28 05:07:52 +0000 |
commit | 17d587b621e47b46e4a4d92ce2b3709e5255f3f4 (patch) | |
tree | 0eac0195595d8e903f56a977dcdfcb707789f186 /apps/app_record.c | |
parent | 078302117665eda70919ed413933f68b39e11b33 (diff) |
Add silence detection to app_record
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@926 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'apps/app_record.c')
-rwxr-xr-x | apps/app_record.c | 82 |
1 files changed, 75 insertions, 7 deletions
diff --git a/apps/app_record.c b/apps/app_record.c index 7b02be43b..30a1b97c0 100755 --- a/apps/app_record.c +++ b/apps/app_record.c @@ -18,6 +18,7 @@ #include <asterisk/pbx.h> #include <asterisk/module.h> #include <asterisk/translate.h> +#include <asterisk/dsp.h> #include <string.h> #include <stdlib.h> #include <pthread.h> @@ -29,9 +30,10 @@ static char *app = "Record"; static char *synopsis = "Record to a file"; static char *descrip = -" Record(filename:extension): Records from the channel into a given\n" +" Record(filename:extension|silence): Records from the channel into a given\n" "filename. If the file exists it will be overwritten. The 'extension'\n" "is the extension of the file type to be recorded (wav, gsm, etc).\n" +"'silence' is the number of seconds of silence to allow before returning.\n" "Returns -1 when the user hangs up.\n"; STANDARD_LOCAL_USER; @@ -49,13 +51,21 @@ static int record_exec(struct ast_channel *chan, void *data) char * vdata; /* Used so I don't have to typecast every use of *data */ int i = 0; int j = 0; - + struct ast_filestream *s = '\0'; struct localuser *u; struct ast_frame *f = NULL; + struct ast_dsp *sildet; /* silence detector dsp */ + int totalsilence = 0; + int dspsilence = 0; + int silence = 0; /* amount of silence to allow */ + int gotsilence = 0; /* did we timeout for silence? */ + char silencestr[5]; + int k = 0; + int rfmt; + vdata = data; /* explained above */ - /* The next few lines of code parse out the filename and header from the input string */ if (!vdata) { /* no data implies no filename or anything is present */ @@ -76,9 +86,21 @@ static int record_exec(struct ast_channel *chan, void *data) } fil[i++] = '\0'; - for (; j < 10 && i < strlen(data); i++, j++) + for (; j < 10 && i < strlen(data) && (vdata[i] != '|'); i++, j++) ext[j] = vdata[i]; ext[j] = '\0'; + + if (vdata[i] && (vdata[i] == '|')) i++; + for (; vdata[i] && (vdata[i] != '|') && (k < 3) && i < strlen(data); i++, k++) + silencestr[k] = vdata[i]; + silencestr[k] = '\0'; + + if (silencestr) { + silence = atoi(silencestr); + if (silence > 0) + silence *= 1000; + } + /* done parsing */ @@ -109,7 +131,25 @@ static int record_exec(struct ast_channel *chan, void *data) ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", chan->name); } ast_stopstream(chan); + /* The end of beep code. Now the recording starts */ + + + if (silence > 0) { + rfmt = chan->readformat; + res = ast_set_read_format(chan, AST_FORMAT_SLINEAR); + if (res < 0) { + ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n"); + return -1; + } + sildet = ast_dsp_new(); + if (!sildet) { + ast_log(LOG_WARNING, "Unable to create silence detector :(\n"); + return -1; + } + ast_dsp_set_threshold(sildet, 256); + } + s = ast_writefile( tmp, ext, NULL, O_CREAT|O_TRUNC|O_WRONLY , 0, 0644); if (s) { @@ -126,6 +166,22 @@ static int record_exec(struct ast_channel *chan, void *data) ast_log(LOG_WARNING, "Problem writing frame\n"); break; } + + if (silence > 0) { + dspsilence = 0; + ast_dsp_silence(sildet, f, &dspsilence); + if (dspsilence) { + totalsilence = dspsilence; + } else { + totalsilence = 0; + } + if (totalsilence > silence) { + /* Ended happily with silence */ + ast_frfree(f); + gotsilence = 1; + break; + } + } } if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '#')) { @@ -138,9 +194,15 @@ static int record_exec(struct ast_channel *chan, void *data) ast_log(LOG_DEBUG, "Got hangup\n"); res = -1; } - /* Strip off the last 1/4 second of it */ - ast_stream_rewind(s, 250); - ast_truncstream(s); + + if (gotsilence) { + ast_stream_rewind(s, silence-1000); + ast_truncstream(s); + } else { + /* Strip off the last 1/4 second of it */ + ast_stream_rewind(s, 250); + ast_truncstream(s); + } ast_closestream(s); } else ast_log(LOG_WARNING, "Could not create file %s\n", fil); @@ -148,6 +210,12 @@ static int record_exec(struct ast_channel *chan, void *data) ast_log(LOG_WARNING, "Could not answer channel '%s'\n", chan->name); LOCAL_USER_REMOVE(u); + if (silence > 0) { + res = ast_set_read_format(chan, rfmt); + if (res) + ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name); + ast_dsp_free(sildet); + } return res; } |