From c8c8164f13dfc18e0746776577c41c7762d8c5d3 Mon Sep 17 00:00:00 2001 From: BJ Weschke Date: Thu, 4 May 2006 20:29:13 +0000 Subject: ast_play_and_prepend and ast_play_and_record cleanup #6991 (casper) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@24745 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- app.c | 312 ++++++++++++++---------------------------------------------------- 1 file changed, 67 insertions(+), 245 deletions(-) diff --git a/app.c b/app.c index 00267296e..d8069c381 100644 --- a/app.c +++ b/app.c @@ -535,22 +535,21 @@ int ast_play_and_wait(struct ast_channel *chan, const char *fn) static int global_silence_threshold = 128; static int global_maxsilence = 0; -int ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int silencethreshold, int maxsilence, const char *path) +static int __ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int beep, int silencethreshold, int maxsilence, const char *path, int prepend) { - int d; + int d = 0; char *fmts; char comment[256]; int x, fmtcnt=1, res=-1,outmsg=0; - struct ast_frame *f; struct ast_filestream *others[MAX_OTHER_FORMATS]; char *sfmt[MAX_OTHER_FORMATS]; char *stringp=NULL; time_t start, end; struct ast_dsp *sildet=NULL; /* silence detector dsp */ int totalsilence = 0; - int dspsilence = 0; int rfmt=0; struct ast_silence_generator *silgen = NULL; + char prependfile[80]; if (silencethreshold < 0) silencethreshold = global_silence_threshold; @@ -567,14 +566,20 @@ int ast_play_and_record(struct ast_channel *chan, const char *playfile, const ch ast_log(LOG_DEBUG,"play_and_record: %s, %s, '%s'\n", playfile ? playfile : "", recordfile, fmt); snprintf(comment,sizeof(comment),"Playing %s, Recording to: %s on %s\n", playfile ? playfile : "", recordfile, chan->name); - if (playfile) { - d = ast_play_and_wait(chan, playfile); + if (playfile || beep) { + if (!beep) + d = ast_play_and_wait(chan, playfile); if (d > -1) d = ast_stream_and_wait(chan, "beep", chan->language, ""); if (d < 0) return -1; } + if (prepend) { + ast_copy_string(prependfile, recordfile, sizeof(prependfile)); + strncat(prependfile, "-prepend", sizeof(prependfile) - strlen(prependfile) - 1); + } + fmts = ast_strdupa(fmt); stringp=fmts; @@ -593,8 +598,9 @@ int ast_play_and_record(struct ast_channel *chan, const char *playfile, const ch time(&start); end=start; /* pre-initialize end to be same as start in case we never get into loop */ for (x=0;x 2) + ast_verbose(VERBOSE_PREFIX_3 "x=%d, open writing: %s format: %s, %p\n", x, prepend ? prependfile : recordfile, sfmt[x], others[x]); if (!others[x]) { break; @@ -620,16 +626,18 @@ int ast_play_and_record(struct ast_channel *chan, const char *playfile, const ch } } - /* Request a video update */ - ast_indicate(chan, AST_CONTROL_VIDUPDATE); + if (!prepend) { + /* Request a video update */ + ast_indicate(chan, AST_CONTROL_VIDUPDATE); - if (ast_opt_transmit_silence) - silgen = ast_channel_start_silence_generator(chan); + if (ast_opt_transmit_silence) + silgen = ast_channel_start_silence_generator(chan); + } if (x == fmtcnt) { - /* Loop forever, writing the packets we read to the writer(s), until - we read a # or get a hangup */ - f = NULL; + /* Loop forever, writing the packets we read to the writer(s), until + we read a digit or get a hangup */ + struct ast_frame *f; for(;;) { res = ast_waitfor(chan, 2000); if (!res) { @@ -652,12 +660,14 @@ int ast_play_and_record(struct ast_channel *chan, const char *playfile, const ch if (f->frametype == AST_FRAME_VOICE) { /* write each format */ for (x=0;x 0) { - dspsilence = 0; + int dspsilence = 0; ast_dsp_silence(sildet, f, &dspsilence); if (dspsilence) totalsilence = dspsilence; @@ -668,7 +678,6 @@ int ast_play_and_record(struct ast_channel *chan, const char *playfile, const ch /* Ended happily with silence */ if (option_verbose > 2) ast_verbose( VERBOSE_PREFIX_3 "Recording automatically stopped after a silence of %d seconds\n", totalsilence/1000); - ast_frfree(f); res = 'S'; outmsg=2; break; @@ -677,19 +686,25 @@ int ast_play_and_record(struct ast_channel *chan, const char *playfile, const ch /* Exit on any error */ if (res) { ast_log(LOG_WARNING, "Error writing frame\n"); - ast_frfree(f); break; } } else if (f->frametype == AST_FRAME_VIDEO) { /* Write only once */ ast_writestream(others[0], f); } else if (f->frametype == AST_FRAME_DTMF) { + if (prepend) { + /* stop recording with any digit */ + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "User ended message by pressing %c\n", f->subclass); + res = 't'; + outmsg = 2; + break; + } if (f->subclass == '#') { if (option_verbose > 2) ast_verbose( VERBOSE_PREFIX_3 "User ended message by pressing %c\n", f->subclass); res = '#'; outmsg = 2; - ast_frfree(f); break; } if (f->subclass == '0') { @@ -698,7 +713,6 @@ int ast_play_and_record(struct ast_channel *chan, const char *playfile, const ch ast_verbose(VERBOSE_PREFIX_3 "User cancelled by pressing %c\n", f->subclass); res = '0'; outmsg = 0; - ast_frfree(f); break; } } @@ -707,264 +721,60 @@ int ast_play_and_record(struct ast_channel *chan, const char *playfile, const ch if (maxtime < (end - start)) { if (option_verbose > 2) ast_verbose( VERBOSE_PREFIX_3 "Took too long, cutting it short...\n"); - outmsg = 2; res = 't'; - ast_frfree(f); + outmsg = 2; break; } } ast_frfree(f); } - if (end == start) time(&end); if (!f) { if (option_verbose > 2) ast_verbose( VERBOSE_PREFIX_3 "User hung up\n"); res = -1; outmsg=1; + } else { + ast_frfree(f); } + if (end == start) time(&end); } else { ast_log(LOG_WARNING, "Error creating writestream '%s', format '%s'\n", recordfile, sfmt[x]); } - - if (silgen) - ast_channel_stop_silence_generator(chan, silgen); - - *duration = end - start; - - for (x=0;x 0) - ast_stream_rewind(others[x], totalsilence ? totalsilence-200 : 200); - ast_truncstream(others[x]); - ast_closestream(others[x]); - } - if (rfmt && ast_set_read_format(chan, rfmt)) { - ast_log(LOG_WARNING, "Unable to restore format %s to channel '%s'\n", ast_getformatname(rfmt), chan->name); - } - if (outmsg > 1) { - /* Let them know recording is stopped */ - ast_stream_and_wait(chan, "auth-thankyou", chan->language, ""); - } - if (sildet) - ast_dsp_free(sildet); - return res; -} - -int ast_play_and_prepend(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int *duration, int beep, int silencethreshold, int maxsilence) -{ - int d = 0; - char *fmts; - char comment[256]; - int x, fmtcnt=1, res=-1,outmsg=0; - struct ast_frame *f; - struct ast_filestream *others[MAX_OTHER_FORMATS]; - struct ast_filestream *realfiles[MAX_OTHER_FORMATS]; - char *sfmt[MAX_OTHER_FORMATS]; - char *stringp=NULL; - time_t start, end; - struct ast_dsp *sildet; /* silence detector dsp */ - int totalsilence = 0; - int dspsilence = 0; - int rfmt=0; - char prependfile[80]; - - if (silencethreshold < 0) - silencethreshold = global_silence_threshold; - - if (maxsilence < 0) - maxsilence = global_maxsilence; - - /* barf if no pointer passed to store duration in */ - if (duration == NULL) { - ast_log(LOG_WARNING, "Error play_and_prepend called without duration pointer\n"); - return -1; - } - - ast_log(LOG_DEBUG,"play_and_prepend: %s, %s, '%s'\n", playfile ? playfile : "", recordfile, fmt); - snprintf(comment,sizeof(comment),"Playing %s, Recording to: %s on %s\n", playfile ? playfile : "", recordfile, chan->name); - - if (playfile || beep) { - if (!beep) - d = ast_play_and_wait(chan, playfile); - if (d > -1) - d = ast_stream_and_wait(chan, "beep",chan->language, ""); - if (d < 0) - return -1; - } - ast_copy_string(prependfile, recordfile, sizeof(prependfile)); - strncat(prependfile, "-prepend", sizeof(prependfile) - strlen(prependfile) - 1); - - fmts = ast_strdupa(fmt); - - stringp=fmts; - strsep(&stringp, "|"); - ast_log(LOG_DEBUG,"Recording Formats: sfmts=%s\n", fmts); - sfmt[0] = ast_strdupa(fmts); - - while((fmt = strsep(&stringp, "|"))) { - if (fmtcnt > MAX_OTHER_FORMATS - 1) { - ast_log(LOG_WARNING, "Please increase MAX_OTHER_FORMATS in app.c\n"); - break; - } - sfmt[fmtcnt++] = ast_strdupa(fmt); - } - - time(&start); - end=start; /* pre-initialize end to be same as start in case we never get into loop */ - for (x=0;x 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"); - ast_dsp_free(sildet); - return -1; - } - } - - if (x == fmtcnt) { - /* Loop forever, writing the packets we read to the writer(s), until - we read a # or get a hangup */ - f = NULL; - for(;;) { - res = ast_waitfor(chan, 2000); - if (!res) { - ast_log(LOG_DEBUG, "One waitfor failed, trying another\n"); - /* Try one more time in case of masq */ - res = ast_waitfor(chan, 2000); - if (!res) { - ast_log(LOG_WARNING, "No audio available on %s??\n", chan->name); - res = -1; - } - } - - if (res < 0) { - f = NULL; - break; - } - f = ast_read(chan); - if (!f) - break; - if (f->frametype == AST_FRAME_VOICE) { - /* write each format */ - for (x=0;x 0) { - dspsilence = 0; - ast_dsp_silence(sildet, f, &dspsilence); - if (dspsilence) - totalsilence = dspsilence; - else - totalsilence = 0; - - if (totalsilence > maxsilence) { - /* Ended happily with silence */ - if (option_verbose > 2) - ast_verbose( VERBOSE_PREFIX_3 "Recording automatically stopped after a silence of %d seconds\n", totalsilence/1000); - ast_frfree(f); - res = 'S'; - outmsg=2; - break; - } - } - /* Exit on any error */ - if (res) { - ast_log(LOG_WARNING, "Error writing frame\n"); - ast_frfree(f); - break; - } - } else if (f->frametype == AST_FRAME_VIDEO) { - /* Write only once */ - ast_writestream(others[0], f); - } else if (f->frametype == AST_FRAME_DTMF) { - /* stop recording with any digit */ - if (option_verbose > 2) - ast_verbose( VERBOSE_PREFIX_3 "User ended message by pressing %c\n", f->subclass); - res = 't'; - outmsg = 2; - ast_frfree(f); + *duration = end - start; + if (!prepend) { + for (x=0;x 2) - ast_verbose( VERBOSE_PREFIX_3 "Took too long, cutting it short...\n"); - res = 't'; - outmsg=2; - ast_frfree(f); - break; - } - } - ast_frfree(f); - } - if (end == start) time(&end); - if (!f) { - if (option_verbose > 2) - ast_verbose( VERBOSE_PREFIX_3 "User hung up\n"); - res = -1; - outmsg=1; -#if 0 - /* delete all the prepend files */ - for (x=0;x 0) + ast_stream_rewind(others[x], totalsilence ? totalsilence-200 : 200); + ast_truncstream(others[x]); + ast_closestream(others[x]); } - } else { - ast_log(LOG_WARNING, "Error creating writestream '%s', format '%s'\n", prependfile, sfmt[x]); } - ast_dsp_free(sildet); - *duration = end - start; -#if 0 - if (outmsg > 1) { -#else - if (outmsg) { -#endif + if (prepend && outmsg) { + struct ast_filestream *realfiles[MAX_OTHER_FORMATS]; struct ast_frame *fr; for (x=0;x 3) + ast_verbose(VERBOSE_PREFIX_4 "Recording Format: sfmts=%s, prependfile %s, recordfile %s\n", sfmt[x], prependfile, recordfile); ast_filedelete(prependfile, sfmt[x]); } } @@ -975,9 +785,21 @@ int ast_play_and_prepend(struct ast_channel *chan, char *playfile, char *recordf /* Let them know it worked */ ast_stream_and_wait(chan, "auth-thankyou", chan->language, ""); } + if (sildet) + ast_dsp_free(sildet); return res; } +int ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int silencethreshold, int maxsilence, const char *path) +{ + return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, 0, silencethreshold, maxsilence, path, 0); +} + +int ast_play_and_prepend(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int *duration, int beep, int silencethreshold, int maxsilence) +{ + return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, beep, silencethreshold, maxsilence, NULL, 1); +} + /* Channel group core functions */ int ast_app_group_split_group(const char *data, char *group, int group_max, char *category, int category_max) -- cgit v1.2.3