Project "FreeSWITCH Source" received a push.

branch: master updated

       via: 180e3d4ab1943361610ca241d150565aad8d16fd (commit)
      from: 78472897cdf1432fd3ceb9814ebee6b8376fd6e7 (commit)


= COMMIT LOG ===========================================================
committer: Anthony Minessale
comments: 
agc tweaks

diff --git a/src/include/switch_resample.h b/src/include/switch_resample.h
index b38e094..3dff620 100644
--- a/src/include/switch_resample.h
+++ b/src/include/switch_resample.h
@@ -39,6 +39,7 @@
 	
 */
 #define switch_normalize_volume(x) if (x > 4) x = 4; if (x < -4) x = -4;
+#define switch_normalize_volume_granular(x) if (x > 12) x = 12; if (x < -12) x = -12;
 
 #ifndef SWITCH_RESAMPLE_H
 #define SWITCH_RESAMPLE_H
@@ -158,6 +159,14 @@ SWITCH_DECLARE(void) switch_generate_sln_silence(int16_t *data, uint32_t samples
   \param vol the volume factor -4 -> 4
  */
 SWITCH_DECLARE(void) switch_change_sln_volume(int16_t *data, uint32_t samples, int32_t vol);
+
+/*!
+  \brief Change the volume of a signed linear audio frame with more granularity
+  \param data the audio data
+  \param samples the number of 2 byte samples
+  \param vol the volume factor -12 -> 12
+ */
+SWITCH_DECLARE(void) switch_change_sln_volume_granular(int16_t *data, uint32_t samples, int32_t vol);
 ///\}
 
 SWITCH_DECLARE(uint32_t) switch_merge_sln(int16_t *data, uint32_t samples, int16_t *other_data, uint32_t other_samples);
diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c
index 5eeae5c..8a3f53e 100644
--- a/src/mod/applications/mod_conference/mod_conference.c
+++ b/src/mod/applications/mod_conference/mod_conference.c
@@ -318,6 +318,7 @@ struct conference_member {
 	switch_mutex_t *audio_in_mutex;
 	switch_mutex_t *audio_out_mutex;
 	switch_mutex_t *read_mutex;
+	switch_codec_implementation_t read_impl;
 	switch_codec_implementation_t orig_read_impl;
 	switch_codec_t read_codec;
 	switch_codec_t write_codec;
@@ -1942,14 +1943,37 @@ static void conference_loop_fn_hangup(conference_member_t *member, caller_contro
 	switch_clear_flag_locked(member, MFLAG_RUNNING);
 }
 
+static void check_agc_levels(conference_member_t *member)
+{
+	if (!member->avg_score) return;
+
+	if (member->avg_score < member->conference->agc_level - 200) {
+		member->agc_volume_in_level++;
+		switch_normalize_volume_granular(member->agc_volume_in_level);
+	} else if (member->avg_score > member->conference->agc_level + 200) {
+		member->agc_volume_in_level--;
+		switch_normalize_volume_granular(member->agc_volume_in_level);
+	}
+		//} else {
+		//member->vol_period = (member->read_impl.actual_samples_per_second / member->read_impl.samples_per_packet) * 5;
+		//}
+}
+
 static void clear_avg(conference_member_t *member)
 {
 
-	member->agc_volume_in_level = 0;
+	if (member->agc_volume_in_level < -5) {
+		member->agc_volume_in_level = 0;
+	}
+
+	if (member->conference->agc_level) {
+		check_agc_levels(member);
+	}
+
 	member->avg_score = 0;
 	member->avg_itt = 0;
 	member->avg_tally = 0;
-	member->nt_tally = 0;
+	member->agc_concur = 0;
 }
 
 
@@ -1962,7 +1986,6 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v
 	switch_status_t status;
 	switch_frame_t *read_frame = NULL;
 	uint32_t hangover = 40, hangunder = 5, hangover_hits = 0, hangunder_hits = 0, energy_level = 0, diff_level = 400;
-	switch_codec_implementation_t read_impl = { 0 };
 	switch_core_session_t *session = member->session;
 	int check_floor_change;
 
@@ -1972,7 +1995,7 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v
 
 	channel = switch_core_session_get_channel(session);
 
-	switch_core_session_get_read_impl(session, &read_impl);
+	switch_core_session_get_read_impl(session, &member->read_impl);
 
 	/* As long as we have a valid read, feed that data into an input buffer where the conference thread will take it 
 	   and mux it with any audio from other channels. */
@@ -1997,6 +2020,10 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v
 		}
 
 		if (switch_test_flag(read_frame, SFF_CNG)) {
+			if (member->conference->agc_level) {
+				member->nt_tally++;
+			}
+
 			if (hangunder_hits) {
 				hangunder_hits--;
 			}
@@ -2017,6 +2044,11 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v
 
 			goto do_continue;
 		}
+
+		if (member->nt_tally > (member->read_impl.actual_samples_per_second / member->read_impl.samples_per_packet) * 3) {
+			member->agc_volume_in_level = 0;
+			clear_avg(member);
+		}
 		
 		/* Check for input volume adjustments */
 		if (!member->conference->agc_level) {
@@ -2031,30 +2063,29 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v
 			uint32_t energy = 0, i = 0, samples = 0, j = 0;
 			int16_t *data;
 			int divisor = 0;
-			int agc_period = (read_impl.actual_samples_per_second / read_impl.samples_per_packet) / 2;
-			int combined_vol = 0;
+			int agc_period = (member->read_impl.actual_samples_per_second / member->read_impl.samples_per_packet) / 4;
+			
 
 			data = read_frame->data;
 
-			if (!(divisor = read_impl.actual_samples_per_second / 8000)) {
+			if (!(divisor = member->read_impl.actual_samples_per_second / 8000)) {
 				divisor = 1;
 			}
 
 			member->score = 0;
 
-			combined_vol = member->agc_volume_in_level;
-			if (member->conference->agc_level) {
-				combined_vol += member->agc_volume_in_level;
+			if (member->volume_in_level) {
+				switch_change_sln_volume(read_frame->data, read_frame->datalen / 2, member->volume_in_level);
 			}
 
-			if (combined_vol) {
-				switch_change_sln_volume(read_frame->data, read_frame->datalen / 2, combined_vol);
+			if (member->agc_volume_in_level) {
+				switch_change_sln_volume_granular(read_frame->data, read_frame->datalen / 2, member->agc_volume_in_level);
 			}
 			
 			if ((samples = read_frame->datalen / sizeof(*data))) {
 				for (i = 0; i < samples; i++) {
 					energy += abs(data[j]);
-					j += read_impl.number_of_channels;
+					j += member->read_impl.number_of_channels;
 				}
 				member->score = energy / (samples / divisor);
 			}
@@ -2082,22 +2113,14 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v
 
 
 				
-				if (++member->nt_tally >= agc_period) {
+				if (++member->agc_concur >= agc_period) {
 					if (!member->vol_period) {
-						if (member->avg_score < member->conference->agc_level) {
-							member->agc_volume_in_level++;
-							switch_normalize_volume(member->agc_volume_in_level);
-							member->vol_period = (read_impl.actual_samples_per_second / read_impl.samples_per_packet) * 2;
-						}
-					
-						if (member->avg_score > member->conference->agc_level) {
-							member->agc_volume_in_level--;
-							switch_normalize_volume(member->agc_volume_in_level);
-							member->vol_period = (read_impl.actual_samples_per_second / read_impl.samples_per_packet) * 2;
-						}
+						check_agc_levels(member);
 					}
-					member->nt_tally = 0;
+					member->agc_concur = 0;
 				}
+			} else {
+				member->nt_tally++;
 			}
 
 			member->score_iir = (int) (((1.0 - SCORE_DECAY) * (float) member->score) + (SCORE_DECAY * (float) member->score_iir));
@@ -2112,6 +2135,10 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v
 					hangover_hits--;
 				}
 
+				if (member->conference->agc_level) {
+					member->nt_tally = 0;
+				}
+
 				if (diff >= diff_level || ++hangunder_hits >= hangunder) { 
 					check_floor_change = 1;
 
@@ -2147,6 +2174,11 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v
 				if (hangunder_hits) {
 					hangunder_hits--;
 				}
+
+				if (member->conference->agc_level) {
+					member->nt_tally++;
+				}
+
 				if (switch_test_flag(member, MFLAG_TALKING) && switch_test_flag(member, MFLAG_CAN_SPEAK)) {
 					switch_event_t *event;
 					if (++hangover_hits >= hangover) {
diff --git a/src/switch_resample.c b/src/switch_resample.c
index 10c633c..64656b6 100644
--- a/src/switch_resample.c
+++ b/src/switch_resample.c
@@ -269,6 +269,43 @@ 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[12] = {1.25, 1.50, 1.75, 2.0, 2.25, 2.50, 2.75, 3.0, 3.25, 3.50, 3.75, 4.0};
+	double neg[12] = {.917, .834, .751, .668, .585, .502, .419, .336, .253, .017, .087, .004};
+	double *chart;
+	uint32_t i;
+
+	if (vol == 0) return;
+
+	switch_normalize_volume_granular(vol);
+
+	if (vol > 0) {
+		chart = pos;
+	} else {
+		chart = neg;
+	}
+	
+	i = abs(vol) - 1;
+	
+	switch_assert(i < 12);
+
+	newrate = chart[i];
+
+	if (newrate) {
+		int32_t tmp;
+		uint32_t x;
+		int16_t *fp = data;
+
+		for (x = 0; x < samples; x++) {
+			tmp = (int32_t) fp[x] * newrate;
+			switch_normalize_to_16bit(tmp);
+			fp[x] = (int16_t) tmp;
+		}
+	}
+}
+
 SWITCH_DECLARE(void) switch_change_sln_volume(int16_t *data, uint32_t samples, int32_t vol)
 {
 	double newrate = 0;
========================================================================

Summary of changes:
 src/include/switch_resample.h                      |    9 ++
 .../applications/mod_conference/mod_conference.c   |   84 ++++++++++++++------
 src/switch_resample.c                              |   37 +++++++++
 3 files changed, 104 insertions(+), 26 deletions(-)

this email was generated because of /git/your-repo.git/hooks/post-receive by the file /git-core/contrib/hooks/post-receive-email
For more info, see http://blog.chomperstomp.com/?p=630 --
FreeSWITCH Source