summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2007-02-04 17:04:33 +0000
committerBenny Prijono <bennylp@teluu.com>2007-02-04 17:04:33 +0000
commit7a7a50ebbab0f58b354489e4f7cbedb73fabaa31 (patch)
treed68d575552a62018f3eed1f92bf48f4821f8d86a
parent97835cac4ce663beacec5c83aabbf07fb2b90d2f (diff)
Fixed ticket #78: Noise in conference bridge because of upsampling and changes in audio level
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@931 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjmedia/src/pjmedia/conference.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/pjmedia/src/pjmedia/conference.c b/pjmedia/src/pjmedia/conference.c
index cacd3a22..317c355a 100644
--- a/pjmedia/src/pjmedia/conference.c
+++ b/pjmedia/src/pjmedia/conference.c
@@ -67,6 +67,25 @@ static FILE *fhnd_rec;
#define INVALID_SLOT ((SLOT_TYPE)-1)
+/* These are settings to control the adaptivity of changes in the
+ * signal level of the ports, so that sudden change in signal level
+ * in the port does not cause misaligned signal (which causes noise).
+ */
+#if 1
+# define ATTACK_A 3
+# define ATTACK_B 2
+# define DECAY_A 3
+# define DECAY_B 2
+#else
+ /* To simulate old behavior */
+# define ATTACK_A 0
+# define ATTACK_B 1
+# define DECAY_A 0
+# define DECAY_B 1
+#endif
+
+
+
/*
* DON'T GET CONFUSED WITH TX/RX!!
*
@@ -95,6 +114,9 @@ struct conf_port
unsigned clock_rate; /**< Port's clock rate. */
unsigned samples_per_frame; /**< Port's samples per frame. */
+ /* Last level calculated from this port */
+ pj_int32_t last_level;
+
/* Calculated signal levels: */
unsigned tx_level; /**< Last tx level to this port. */
unsigned rx_level; /**< Last rx level from this port. */
@@ -1716,6 +1738,20 @@ static pj_status_t get_frame(pjmedia_port *this_port,
conf->samples_per_frame);
}
+ /* Apply simple AGC to the level, to avoid dramatic change in the
+ * level thus causing noise because the signal now is not aligned
+ * with the signal from the previous frame.
+ */
+ if (level >= conf_port->last_level) {
+ level = (conf_port->last_level * ATTACK_A + level * ATTACK_B) /
+ (ATTACK_A + ATTACK_B);
+ } else {
+ level = (conf_port->last_level * DECAY_A + level * DECAY_B) /
+ (DECAY_A + DECAY_B);
+ }
+ conf_port->last_level = level;
+
+
/* Convert level to 8bit complement ulaw */
level = pjmedia_linear2ulaw(level) ^ 0xff;