From 16c0bc115efb1abe6bd62f0d3060e6e5c052c7b6 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 18 Jan 2017 15:12:08 -0600 Subject: [PATCH] FS-9958 --- src/include/switch_resample.h | 4 ++- .../mod_local_stream/mod_local_stream.c | 35 ++++++++++++++++--- src/switch_resample.c | 14 ++++++-- 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/include/switch_resample.h b/src/include/switch_resample.h index 252f156ed7..4dd0e2c5e3 100644 --- a/src/include/switch_resample.h +++ b/src/include/switch_resample.h @@ -177,10 +177,12 @@ SWITCH_DECLARE(void) switch_mux_channels(int16_t *data, switch_size_t samples, u #define switch_resample_calc_buffer_size(_to, _from, _srclen) ((uint32_t)(((float)_to / (float)_from) * (float)_srclen) * 2) -SWITCH_DECLARE(switch_status_t) switch_agc_create(switch_agc_t **agcP, uint32_t energy_avg, uint32_t margin, uint32_t change_factor, uint32_t period_len); +SWITCH_DECLARE(switch_status_t) switch_agc_create(switch_agc_t **agcP, uint32_t energy_avg, + uint32_t low_energy_point, uint32_t margin, uint32_t change_factor, uint32_t period_len); SWITCH_DECLARE(void) switch_agc_destroy(switch_agc_t **agcP); SWITCH_DECLARE(switch_status_t) switch_agc_feed(switch_agc_t *agc, int16_t *data, uint32_t samples, uint32_t channels); SWITCH_DECLARE(void) switch_agc_set_energy_avg(switch_agc_t *agc, uint32_t energy_avg); +SWITCH_DECLARE(void) switch_agc_set_energy_low(switch_agc_t *agc, uint32_t low_energy_point); SWITCH_END_EXTERN_C #endif /* For Emacs: diff --git a/src/mod/formats/mod_local_stream/mod_local_stream.c b/src/mod/formats/mod_local_stream/mod_local_stream.c index 5ab74f4950..accbb8d460 100644 --- a/src/mod/formats/mod_local_stream/mod_local_stream.c +++ b/src/mod/formats/mod_local_stream/mod_local_stream.c @@ -96,6 +96,7 @@ struct local_stream_source { int vol; switch_agc_t *agc; int energy_avg; + int energy_low; int first; switch_dir_t *dir_handle; switch_mutex_t *mutex; @@ -739,6 +740,12 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void if (!(source->energy_avg > -1 && source->energy_avg <= 20000)) { source->energy_avg = 0; } + } else if (!strcasecmp(var, "auto-volume-low-point")) { + source->energy_low = atoi(val); + + if (!(source->energy_low > -1 && source->energy_avg <= 20000)) { + source->energy_low = 0; + } } if (source->chime_max) { source->chime_max *= source->rate; @@ -1279,7 +1286,12 @@ static void launch_thread(const char *name, const char *path, switch_xml_t direc if (!(source->energy_avg > -1 && source->energy_avg <= 20000)) { source->energy_avg = 0; } - + } else if (!strcasecmp(var, "auto-volume-low-point")) { + source->energy_low = atoi(val); + + if (!(source->energy_low > -1 && source->energy_avg <= 20000)) { + source->energy_low = 0; + } } } @@ -1367,15 +1379,30 @@ SWITCH_STANDARD_API(local_stream_function) if ((source = get_source(local_stream_name))) { if (argv[2]) { if (!strncasecmp(argv[2], "auto:", 5)) { + char *p; source->energy_avg = atoi(argv[2] + 5); + + if ((p = strchr(argv[2] + 5, ':'))) { + int tmp = 0; + p++; + tmp = atoi(p); + + if ((tmp > -1 && tmp <= 20000)) { + source->energy_low = tmp; + } else { + stream->write_function(stream, "-ERR invalid auto-volume low-energy level for stream: %s\n", source->name); + } + } + if (!(source->energy_avg > -1 && source->energy_avg <= 20000)) { source->energy_avg = 0; - stream->write_function(stream, "-ERR invalid auto-volume level for stream: %s\n", source->name); + stream->write_function(stream, "-ERR invalid auto-volume level for stream: %s\n", source->name); } else { if (!source->agc) { - switch_agc_create(&source->agc, source->energy_avg, 500, 3, (1000 / source->interval) * 2); + switch_agc_create(&source->agc, source->energy_avg, source->energy_low, 500, 3, (1000 / source->interval) * 2); } else { switch_agc_set_energy_avg(source->agc, source->energy_avg); + switch_agc_set_energy_low(source->agc, source->energy_low); } } } else { @@ -1385,7 +1412,7 @@ SWITCH_STANDARD_API(local_stream_function) } if (source->energy_avg) { - stream->write_function(stream, "+OK Auto-Volume stream: %s is %d", source->name, source->energy_avg); + stream->write_function(stream, "+OK Auto-Volume stream: %s is %d/%d", source->name, source->energy_avg, source->energy_low); } else { stream->write_function(stream, "+OK vol stream: %s is %d", source->name, source->vol); } diff --git a/src/switch_resample.c b/src/switch_resample.c index db099cd264..4a1bebedfd 100644 --- a/src/switch_resample.c +++ b/src/switch_resample.c @@ -413,11 +413,13 @@ struct switch_agc_s { uint32_t score_over; uint32_t score_under; uint32_t period_len; + uint32_t low_energy_point; }; -SWITCH_DECLARE(switch_status_t) switch_agc_create(switch_agc_t **agcP, uint32_t energy_avg, uint32_t margin, uint32_t change_factor, uint32_t period_len) +SWITCH_DECLARE(switch_status_t) switch_agc_create(switch_agc_t **agcP, uint32_t energy_avg, + uint32_t low_energy_point, uint32_t margin, uint32_t change_factor, uint32_t period_len) { switch_agc_t *agc; switch_memory_pool_t *pool; @@ -432,6 +434,7 @@ SWITCH_DECLARE(switch_status_t) switch_agc_create(switch_agc_t **agcP, uint32_t agc->margin = margin; agc->change_factor = change_factor; agc->period_len = period_len; + agc->low_energy_point = low_energy_point; *agcP = agc; @@ -460,6 +463,13 @@ SWITCH_DECLARE(void) switch_agc_set_energy_avg(switch_agc_t *agc, uint32_t energ agc->energy_avg = energy_avg; } +SWITCH_DECLARE(void) switch_agc_set_energy_low(switch_agc_t *agc, uint32_t low_energy_point) +{ + switch_assert(agc); + + agc->low_energy_point = low_energy_point; +} + SWITCH_DECLARE(switch_status_t) switch_agc_feed(switch_agc_t *agc, int16_t *data, uint32_t samples, uint32_t channels) { @@ -493,7 +503,7 @@ SWITCH_DECLARE(switch_status_t) switch_agc_feed(switch_agc_t *agc, int16_t *data agc->score_over = 0; } - if (agc->score_avg < agc->energy_avg - agc->margin) { + if (agc->score_avg < agc->energy_avg - agc->margin && agc->score_avg > agc->low_energy_point) { agc->score_under++; } else { agc->score_under = 0;