[Core, mod_conference] Fixed oscillation in conference AGC processing. Especially during volume reduction processing (#1064)
* Fixed oscillation in conference AGC processing. Especially during volume reduction processing * Re-scaled granular volume to +/- 50 dB level change. 10 = double loudness, -10 = half loudness, 0 = no change Co-authored-by: Chris Rienzo <chris@signalwire.com>
This commit is contained in:
parent
67cec5c3e8
commit
ec1a0215fe
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Copyright (C) 2005-2021, Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
|
@ -26,7 +26,7 @@
|
|||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
*
|
||||
* switch_caller.h -- Caller Identification
|
||||
* switch_resample.h
|
||||
*
|
||||
*/
|
||||
/*! \file switch_resample.h
|
||||
|
@ -39,7 +39,8 @@
|
|||
|
||||
*/
|
||||
#define switch_normalize_volume(x) if (x > 4) x = 4; if (x < -4) x = -4;
|
||||
#define switch_normalize_volume_granular(x) if (x > 13) x = 13; if (x < -13) x = -13;
|
||||
#define SWITCH_GRANULAR_VOLUME_MAX 50
|
||||
#define switch_normalize_volume_granular(x) if (x > SWITCH_GRANULAR_VOLUME_MAX) x = SWITCH_GRANULAR_VOLUME_MAX; if (x < -SWITCH_GRANULAR_VOLUME_MAX) x = -SWITCH_GRANULAR_VOLUME_MAX;
|
||||
|
||||
#ifndef SWITCH_RESAMPLE_H
|
||||
#define SWITCH_RESAMPLE_H
|
||||
|
|
|
@ -1276,15 +1276,6 @@ void conference_api_set_agc(conference_member_t *member, const char *data)
|
|||
}
|
||||
|
||||
|
||||
if (argv[0]) {
|
||||
tmp = atoi(argv[0]);
|
||||
|
||||
if (tmp > 0) {
|
||||
member->agc_period_len = (1000 / member->conference->interval) * tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!member->agc) {
|
||||
switch_agc_create(&member->agc, member->agc_level, member->agc_low_energy_level, member->agc_margin,
|
||||
member->agc_change_factor, member->agc_period_len);
|
||||
|
|
|
@ -3574,9 +3574,9 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co
|
|||
|
||||
conference->agc_level = 0;
|
||||
conference->agc_low_energy_level = 0;
|
||||
conference->agc_margin = 20;
|
||||
conference->agc_change_factor = 3;
|
||||
conference->agc_period_len = (1000 / conference->interval) * 2;
|
||||
conference->agc_margin = 100;
|
||||
conference->agc_change_factor = 2;
|
||||
conference->agc_period_len = 500 / conference->interval;
|
||||
|
||||
|
||||
if (agc_level) {
|
||||
|
@ -3610,7 +3610,7 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co
|
|||
if (agc_period_len) {
|
||||
tmp = atoi(agc_period_len);
|
||||
if (tmp > 0) {
|
||||
conference->agc_period_len = (1000 / conference->interval) * tmp;
|
||||
conference->agc_period_len = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -345,9 +345,23 @@ SWITCH_DECLARE(void) switch_mux_channels(int16_t *data, switch_size_t samples, u
|
|||
SWITCH_DECLARE(void) switch_change_sln_volume_granular(int16_t *data, uint32_t samples, int32_t vol)
|
||||
{
|
||||
double newrate = 0;
|
||||
double pos[13] = {1.25, 1.50, 1.75, 2.0, 2.25, 2.50, 2.75, 3.0, 3.25, 3.50, 3.75, 4.0, 4.5};
|
||||
double neg[13] = {.917, .834, .751, .668, .585, .502, .419, .336, .253, .087, .017, .004, 0.0};
|
||||
double *chart;
|
||||
// change in dB mapped to ratio for output sample
|
||||
// computed as (powf(10.0f, (float)(change_in_dB) / 20.0f))
|
||||
static const double pos[SWITCH_GRANULAR_VOLUME_MAX] = {
|
||||
1.122018, 1.258925, 1.412538, 1.584893, 1.778279, 1.995262, 2.238721, 2.511887, 2.818383, 3.162278,
|
||||
3.548134, 3.981072, 4.466835, 5.011872, 5.623413, 6.309574, 7.079458, 7.943282, 8.912509, 10.000000,
|
||||
11.220183, 12.589254, 14.125375, 15.848933, 17.782795, 19.952621, 22.387213, 25.118862, 28.183832, 31.622776,
|
||||
35.481335, 39.810719, 44.668358, 50.118729, 56.234131, 63.095726, 70.794586, 79.432816, 89.125107, 100.000000,
|
||||
112.201836, 125.892517, 141.253784, 158.489334, 177.827942, 199.526215, 223.872070, 251.188705, 281.838318, 316.227753
|
||||
};
|
||||
static const double neg[SWITCH_GRANULAR_VOLUME_MAX] = {
|
||||
0.891251, 0.794328, 0.707946, 0.630957, 0.562341, 0.501187, 0.446684, 0.398107, 0.354813, 0.316228,
|
||||
0.281838, 0.251189, 0.223872, 0.199526, 0.177828, 0.158489, 0.141254, 0.125893, 0.112202, 0.100000,
|
||||
0.089125, 0.079433, 0.070795, 0.063096, 0.056234, 0.050119, 0.044668, 0.039811, 0.035481, 0.031623,
|
||||
0.028184, 0.025119, 0.022387, 0.019953, 0.017783, 0.015849, 0.014125, 0.012589, 0.011220, 0.010000,
|
||||
0.008913, 0.007943, 0.007079, 0.006310, 0.005623, 0.005012, 0.004467, 0.003981, 0.003548, 0.000000 // NOTE mapped -50 dB ratio to total silence instead of 0.003162
|
||||
};
|
||||
const double *chart;
|
||||
uint32_t i;
|
||||
|
||||
if (vol == 0) return;
|
||||
|
@ -362,7 +376,7 @@ SWITCH_DECLARE(void) switch_change_sln_volume_granular(int16_t *data, uint32_t s
|
|||
|
||||
i = abs(vol) - 1;
|
||||
|
||||
switch_assert(i < 13);
|
||||
switch_assert(i < SWITCH_GRANULAR_VOLUME_MAX);
|
||||
|
||||
newrate = chart[i];
|
||||
|
||||
|
@ -444,6 +458,13 @@ SWITCH_DECLARE(void) switch_agc_set(switch_agc_t *agc, uint32_t energy_avg,
|
|||
agc->change_factor = change_factor;
|
||||
agc->period_len = period_len;
|
||||
agc->low_energy_point = low_energy_point;
|
||||
|
||||
agc->score = 0;
|
||||
agc->score_count = 0;
|
||||
agc->score_sum = 0;
|
||||
agc->score_avg = 0;
|
||||
agc->score_over = 0;
|
||||
agc->score_under = 0;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_agc_create(switch_agc_t **agcP, uint32_t energy_avg,
|
||||
|
@ -539,6 +560,8 @@ SWITCH_DECLARE(switch_status_t) switch_agc_feed(switch_agc_t *agc, int16_t *data
|
|||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "[%s] OVER++ SCORE AVG: %d ENERGY AVG: %d MARGIN: %d\n",
|
||||
agc->token, agc->score_avg, agc->energy_avg, agc->margin);
|
||||
agc->score_over++;
|
||||
} else {
|
||||
agc->score_over = 0;
|
||||
}
|
||||
} else {
|
||||
agc->score_over = 0;
|
||||
|
@ -549,8 +572,6 @@ SWITCH_DECLARE(switch_status_t) switch_agc_feed(switch_agc_t *agc, int16_t *data
|
|||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "[%s] BELOW LOW POINT, SCORE AVG: %d ENERGY AVG: %d MARGIN: %d\n",
|
||||
agc->token, agc->score_avg, agc->energy_avg, agc->margin);
|
||||
} else if (((agc->score_avg < agc->energy_avg) && (agc->energy_avg - agc->score_avg > agc->margin))) {
|
||||
//&& (agc->vol < 0 || agc->score_avg > agc->low_energy_point)) {
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "[%s] UNDER++ SCORE AVG: %d ENERGY AVG: %d MARGIN: %d\n",
|
||||
agc->token, agc->score_avg, agc->energy_avg, agc->margin);
|
||||
agc->score_under++;
|
||||
|
|
Loading…
Reference in New Issue