From 198829f2db3d8dcaa76188dc4fe6db06e7b8cbb8 Mon Sep 17 00:00:00 2001 From: tilghman Date: Wed, 5 Mar 2008 16:23:44 +0000 Subject: Create a centralized configuration option for silencethreshold (closes issue #11236) Reported by: philipps Patches: 20080218__bug11236.diff.txt uploaded by Corydon76 (license 14) Tested by: philipps git-svn-id: http://svn.digium.com/svn/asterisk/trunk@106072 f38db490-d61c-443f-a65b-d21fe96a405b --- main/app.c | 4 +++- main/asterisk.c | 3 ++- main/dsp.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- main/loader.c | 2 ++ 4 files changed, 75 insertions(+), 5 deletions(-) (limited to 'main') diff --git a/main/app.c b/main/app.c index 5c3f8a444..7a2227fb9 100644 --- a/main/app.c +++ b/main/app.c @@ -1268,7 +1268,7 @@ int ast_unlock_path(const char *path) int ast_record_review(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, const char *path) { - int silencethreshold = 128; + int silencethreshold; int maxsilence = 0; int res = 0; int cmd = 0; @@ -1286,6 +1286,8 @@ int ast_record_review(struct ast_channel *chan, const char *playfile, const char cmd = '3'; /* Want to start by recording */ + silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE); + while ((cmd >= 0) && (cmd != 't')) { switch (cmd) { case '1': diff --git a/main/asterisk.c b/main/asterisk.c index 287b6ccd0..21aee3b6e 100644 --- a/main/asterisk.c +++ b/main/asterisk.c @@ -121,6 +121,7 @@ int daemon(int, int); /* defined in libresolv of all places */ #include "asterisk/linkedlists.h" #include "asterisk/devicestate.h" #include "asterisk/module.h" +#include "asterisk/dsp.h" #include "asterisk/doxyref.h" /* Doxygen documentation */ @@ -3218,7 +3219,7 @@ int main(int argc, char *argv[]) } ast_rtp_init(); - + ast_dsp_init(); ast_udptl_init(); if (ast_image_init()) { diff --git a/main/dsp.c b/main/dsp.c index 6945464d4..a9a787459 100644 --- a/main/dsp.c +++ b/main/dsp.c @@ -53,6 +53,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/alaw.h" #include "asterisk/utils.h" #include "asterisk/options.h" +#include "asterisk/config.h" /*! Number of goertzels for progress detect */ enum gsamp_size { @@ -193,6 +194,8 @@ enum gsamp_thresh { #define SAMPLES_IN_FRAME 160 +#define CONFIG_FILE_NAME "dsp.conf" + typedef struct { int v2; int v3; @@ -272,6 +275,8 @@ static char dtmf_positions[] = "123A" "456B" "789C" "*0#D"; static char bell_mf_positions[] = "1247C-358A--69*---0B----#"; +static int thresholds[THRESHOLD_MAX]; + static inline void goertzel_sample(goertzel_state_t *s, short sample) { int v1; @@ -1021,7 +1026,7 @@ int ast_dsp_call_progress(struct ast_dsp *dsp, struct ast_frame *inf) return __ast_dsp_call_progress(dsp, inf->data, inf->datalen / 2); } -static int __ast_dsp_silence(struct ast_dsp *dsp, short *s, int len, int *totalsilence) +static int __ast_dsp_silence_noise(struct ast_dsp *dsp, short *s, int len, int *totalsilence, int *totalnoise) { int accum; int x; @@ -1073,6 +1078,8 @@ static int __ast_dsp_silence(struct ast_dsp *dsp, short *s, int len, int *totals } if (totalsilence) *totalsilence = dsp->totalsilence; + if (totalnoise) + *totalnoise = dsp->totalnoise; return res; } @@ -1179,9 +1186,28 @@ int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence) } s = f->data; len = f->datalen/2; - return __ast_dsp_silence(dsp, s, len, totalsilence); + return __ast_dsp_silence_noise(dsp, s, len, totalsilence, NULL); } +int ast_dsp_noise(struct ast_dsp *dsp, struct ast_frame *f, int *totalnoise) +{ + short *s; + int len; + + if (f->frametype != AST_FRAME_VOICE) { + ast_log(LOG_WARNING, "Can't calculate noise on a non-voice frame\n"); + return 0; + } + if (f->subclass != AST_FORMAT_SLINEAR) { + ast_log(LOG_WARNING, "Can only calculate noise on signed-linear frames :(\n"); + return 0; + } + s = f->data; + len = f->datalen/2; + return __ast_dsp_silence_noise(dsp, s, len, NULL, totalnoise); +} + + struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *af) { int silence; @@ -1236,7 +1262,7 @@ struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass)); return af; } - silence = __ast_dsp_silence(dsp, shortdata, len, NULL); + res = __ast_dsp_silence_noise(dsp, shortdata, len, &silence, NULL); if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) { memset(&dsp->f, 0, sizeof(dsp->f)); dsp->f.frametype = AST_FRAME_NULL; @@ -1516,3 +1542,42 @@ int ast_dsp_get_tcount(struct ast_dsp *dsp) { return dsp->tcount; } + +static int _dsp_init(int reload) +{ + struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; + struct ast_config *cfg; + struct ast_variable *var; + + cfg = ast_config_load(CONFIG_FILE_NAME, config_flags); + + if (cfg && cfg != CONFIG_STATUS_FILEUNCHANGED) { + const char *value; + + value = ast_variable_retrieve(cfg, "default", "silencethreshold"); + if (value && sscanf(value, "%d", &thresholds[THRESHOLD_SILENCE]) != 1) { + ast_log(LOG_WARNING, "%s: '%s' is not a valid silencethreshold value\n", CONFIG_FILE_NAME, var->value); + thresholds[THRESHOLD_SILENCE] = 256; + } else if (!value) + thresholds[THRESHOLD_SILENCE] = 256; + + ast_config_destroy(cfg); + } + return 0; +} + +int ast_dsp_get_threshold_from_settings(enum threshold which) +{ + return thresholds[which]; +} + +int ast_dsp_init(void) +{ + return _dsp_init(0); +} + +int ast_dsp_reload(void) +{ + return _dsp_init(1); +} + diff --git a/main/loader.c b/main/loader.c index 43d254c6f..d34da9f7d 100644 --- a/main/loader.c +++ b/main/loader.c @@ -47,6 +47,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/http.h" #include "asterisk/lock.h" #include "asterisk/features.h" +#include "asterisk/dsp.h" #ifdef DLFCNCOMPAT #include "asterisk/dlfcn-compat.h" @@ -249,6 +250,7 @@ static struct reload_classes { { "http", ast_http_reload }, { "logger", logger_reload }, { "features", ast_features_reload }, + { "dsp", ast_dsp_reload}, { NULL, NULL } }; -- cgit v1.2.3