mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-16 06:48:25 +00:00
Add silence detection to voicemail
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@955 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -23,6 +23,7 @@
|
|||||||
#include <asterisk/adsi.h>
|
#include <asterisk/adsi.h>
|
||||||
#include <asterisk/app.h>
|
#include <asterisk/app.h>
|
||||||
#include <asterisk/manager.h>
|
#include <asterisk/manager.h>
|
||||||
|
#include <asterisk/dsp.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -496,12 +497,29 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
|
|||||||
char *s;
|
char *s;
|
||||||
time_t start;
|
time_t start;
|
||||||
time_t end;
|
time_t end;
|
||||||
|
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;
|
||||||
|
char *thresholdstr;
|
||||||
|
int rfmt;
|
||||||
|
int threshold = 128;
|
||||||
|
|
||||||
cfg = ast_load(VOICEMAIL_CONFIG);
|
cfg = ast_load(VOICEMAIL_CONFIG);
|
||||||
if (!cfg) {
|
if (!cfg) {
|
||||||
ast_log(LOG_WARNING, "No such configuration file %s\n", VOICEMAIL_CONFIG);
|
ast_log(LOG_WARNING, "No such configuration file %s\n", VOICEMAIL_CONFIG);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if ((silencestr = ast_variable_retrieve(cfg, "general", "maxsilence"))) {
|
||||||
|
silence = atoi(silencestr);
|
||||||
|
if (silence > 0)
|
||||||
|
silence *= 1000;
|
||||||
|
}
|
||||||
|
if ((thresholdstr = ast_variable_retrieve(cfg, "general", "silencethreshold")))
|
||||||
|
threshold = atoi(thresholdstr);
|
||||||
|
|
||||||
if (!(astemail = ast_variable_retrieve(cfg, "general", "serveremail")))
|
if (!(astemail = ast_variable_retrieve(cfg, "general", "serveremail")))
|
||||||
astemail = ASTERISK_USERNAME;
|
astemail = ASTERISK_USERNAME;
|
||||||
if ((s = ast_variable_retrieve(cfg, "general", "maxmessage"))) {
|
if ((s = ast_variable_retrieve(cfg, "general", "maxmessage"))) {
|
||||||
@@ -657,6 +675,22 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
|
|||||||
wavother++;
|
wavother++;
|
||||||
free(sfmt[x]);
|
free(sfmt[x]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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, 50);
|
||||||
|
}
|
||||||
|
|
||||||
if (x == fmtcnt) {
|
if (x == fmtcnt) {
|
||||||
/* Loop forever, writing the packets we read to the writer(s), until
|
/* Loop forever, writing the packets we read to the writer(s), until
|
||||||
we read a # or get a hangup */
|
we read a # or get a hangup */
|
||||||
@@ -700,6 +734,25 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
|
|||||||
ast_frfree(f);
|
ast_frfree(f);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/* Silence Detection */
|
||||||
|
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 */
|
||||||
|
outmsg=2;
|
||||||
|
ast_frfree(f);
|
||||||
|
gotsilence = 1;
|
||||||
|
res = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else if (f->frametype == AST_FRAME_DTMF) {
|
} else if (f->frametype == AST_FRAME_DTMF) {
|
||||||
if (f->subclass == '#') {
|
if (f->subclass == '#') {
|
||||||
if (option_verbose > 2)
|
if (option_verbose > 2)
|
||||||
@@ -726,6 +779,16 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
|
|||||||
res = -1;
|
res = -1;
|
||||||
outmsg=1;
|
outmsg=1;
|
||||||
}
|
}
|
||||||
|
if (gotsilence) {
|
||||||
|
ast_stream_rewind(writer, silence-1000);
|
||||||
|
ast_truncstream(writer);
|
||||||
|
|
||||||
|
/* And each of the others */
|
||||||
|
for (x=0;x<fmtcnt;x++) {
|
||||||
|
ast_stream_rewind(others[x], silence-1000);
|
||||||
|
ast_truncstream(others[x]);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ast_log(LOG_WARNING, "Error creating writestream '%s', format '%s'\n", fn, sfmt[x]);
|
ast_log(LOG_WARNING, "Error creating writestream '%s', format '%s'\n", fn, sfmt[x]);
|
||||||
free(sfmt[x]);
|
free(sfmt[x]);
|
||||||
|
|||||||
@@ -16,6 +16,10 @@ attach=yes
|
|||||||
;maxgreet=60
|
;maxgreet=60
|
||||||
; How many miliseconds to skip forward/back when rew/ff in message playback
|
; How many miliseconds to skip forward/back when rew/ff in message playback
|
||||||
skipms=3000
|
skipms=3000
|
||||||
|
; How many seconds of silence before we end the recording
|
||||||
|
maxsilence=10
|
||||||
|
; Silence threshold (what we consider silence, the lower, the more sensitive)
|
||||||
|
silencethreshold=128
|
||||||
|
|
||||||
;
|
;
|
||||||
; Each mailbox is listed in the form <mailbox>=<password>,<name>,<email>,<pager_email>
|
; Each mailbox is listed in the form <mailbox>=<password>,<name>,<email>,<pager_email>
|
||||||
|
|||||||
Reference in New Issue
Block a user