summaryrefslogtreecommitdiff
path: root/pjmedia
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2006-08-06 14:15:47 +0000
committerBenny Prijono <bennylp@teluu.com>2006-08-06 14:15:47 +0000
commit5f8a7295e220373097ab73658d853dda2643b84e (patch)
treef635550128747c283768557ecc14346bd532ec04 /pjmedia
parentec75ca7ab04302c9145ad6bf3023dd7359832f60 (diff)
Change the silence suppressor to use the adaptive silence detector.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@655 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjmedia')
-rw-r--r--pjmedia/include/pjmedia/conference.h10
-rw-r--r--pjmedia/include/pjmedia/silencedet.h19
-rw-r--r--pjmedia/src/pjmedia/conference.c13
-rw-r--r--pjmedia/src/pjmedia/echo_common.c2
-rw-r--r--pjmedia/src/pjmedia/echo_suppress.c44
-rw-r--r--pjmedia/src/pjmedia/silencedet.c32
6 files changed, 90 insertions, 30 deletions
diff --git a/pjmedia/include/pjmedia/conference.h b/pjmedia/include/pjmedia/conference.h
index 8b1f2e35..936d2294 100644
--- a/pjmedia/include/pjmedia/conference.h
+++ b/pjmedia/include/pjmedia/conference.h
@@ -293,6 +293,16 @@ PJ_DECL(pj_status_t) pjmedia_conf_disconnect_port( pjmedia_conf *conf,
/**
+ * Get total number of ports connections currently set up in the bridge.
+ *
+ * @param conf The conference bridge.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(unsigned) pjmedia_conf_get_connect_count(pjmedia_conf *conf);
+
+
+/**
* Remove the specified port from the conference bridge.
*
* @param conf The conference bridge.
diff --git a/pjmedia/include/pjmedia/silencedet.h b/pjmedia/include/pjmedia/silencedet.h
index a4958cc5..15cb8460 100644
--- a/pjmedia/include/pjmedia/silencedet.h
+++ b/pjmedia/include/pjmedia/silencedet.h
@@ -73,6 +73,19 @@ PJ_DECL(pj_status_t) pjmedia_silence_det_create( pj_pool_t *pool,
/**
+ * Set silence detector name to identify the particular silence detector
+ * instance in the log.
+ *
+ * @param sd The silence detector.
+ * @param name Name.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_silence_det_set_name(pjmedia_silence_det *sd,
+ const char *name);
+
+
+/**
* Set the sd to operate in fixed threshold mode. With fixed threshold mode,
* the threshold will not be changed adaptively.
*
@@ -109,7 +122,7 @@ PJ_DECL(pj_status_t) pjmedia_silence_det_set_adaptive(pjmedia_silence_det *sd,
* @param min_signal Minimum duration of signal (in msec) before
* signal is reported. If -1 is specified, then
* the default value will be used. The default is
- * one frame.
+ * equal to one frame.
* @param recalc_time The interval to recalculate signal and silence
* proportion and to readjust the silence threshold
* when adaptive silence detection is set. If -1
@@ -144,7 +157,7 @@ PJ_DECL(pj_status_t) pjmedia_silence_det_disable( pjmedia_silence_det *sd );
* @param p_level Optional pointer to receive average signal level
* of the input samples.
*
- * @return PJ_SUCCESS on success.
+ * @return Non zero if signal is silence.
*/
PJ_DECL(pj_bool_t) pjmedia_silence_det_detect( pjmedia_silence_det *sd,
const pj_int16_t samples[],
@@ -173,7 +186,7 @@ PJ_DECL(pj_int32_t) pjmedia_calc_avg_signal( const pj_int16_t samples[],
* @param sd The silence detector instance.
* @param level Signal level.
*
- * @return PJ_SUCCESS on success.
+ * @return Non zero if signal is silence.
*/
PJ_DECL(pj_bool_t) pjmedia_silence_det_apply( pjmedia_silence_det *sd,
pj_uint32_t level);
diff --git a/pjmedia/src/pjmedia/conference.c b/pjmedia/src/pjmedia/conference.c
index b888573d..a0743b6a 100644
--- a/pjmedia/src/pjmedia/conference.c
+++ b/pjmedia/src/pjmedia/conference.c
@@ -221,7 +221,7 @@ static pj_status_t create_conf_port( pj_pool_t *pool,
PJ_ASSERT_RETURN(conf_port, PJ_ENOMEM);
/* Set name */
- pj_strdup(pool, &conf_port->name, name);
+ pj_strdup_with_null(pool, &conf_port->name, name);
/* Default has tx and rx enabled. */
conf_port->rx_setting = PJMEDIA_PORT_ENABLE;
@@ -258,6 +258,8 @@ static pj_status_t create_conf_port( pj_pool_t *pool,
/* Set fixed */
pjmedia_silence_det_set_fixed(conf_port->vad, 2);
+ /* Set VAD name */
+ pjmedia_silence_det_set_name(conf_port->vad, conf_port->name.ptr);
/* If port's clock rate is different than conference's clock rate,
* create a resample sessions.
@@ -898,6 +900,15 @@ PJ_DEF(pj_status_t) pjmedia_conf_disconnect_port( pjmedia_conf *conf,
/*
+ * Get total number of ports connections currently set up in the bridge.
+ */
+PJ_DECL(unsigned) pjmedia_conf_get_connect_count(pjmedia_conf *conf)
+{
+ return conf->connect_cnt;
+}
+
+
+/*
* Remove the specified port.
*/
PJ_DEF(pj_status_t) pjmedia_conf_remove_port( pjmedia_conf *conf,
diff --git a/pjmedia/src/pjmedia/echo_common.c b/pjmedia/src/pjmedia/echo_common.c
index b84fa953..7dad3037 100644
--- a/pjmedia/src/pjmedia/echo_common.c
+++ b/pjmedia/src/pjmedia/echo_common.c
@@ -118,7 +118,7 @@ static struct ec_operations aec_op =
};
#else
-static struct ec_operations aec_op = echo_supp_op;
+#define aec_op echo_supp_op
#endif
diff --git a/pjmedia/src/pjmedia/echo_suppress.c b/pjmedia/src/pjmedia/echo_suppress.c
index 8cc6ab7b..199324cb 100644
--- a/pjmedia/src/pjmedia/echo_suppress.c
+++ b/pjmedia/src/pjmedia/echo_suppress.c
@@ -27,7 +27,7 @@
#define THIS_FILE "echo_suppress.c"
-#define PJMEDIA_ECHO_SUPPRESS_THRESHOLD 20
+#define PJMEDIA_ECHO_SUPPRESS_THRESHOLD PJMEDIA_SILENCE_DET_THRESHOLD
/*
@@ -35,11 +35,11 @@
*/
typedef struct echo_supp
{
- unsigned threshold;
- pj_bool_t suppressing;
- pj_time_val last_signal;
- unsigned samples_per_frame;
- unsigned tail_ms;
+ pj_bool_t suppressing;
+ pjmedia_silence_det *sd;
+ pj_time_val last_signal;
+ unsigned samples_per_frame;
+ unsigned tail_ms;
} echo_supp;
@@ -78,15 +78,24 @@ PJ_DEF(pj_status_t) echo_supp_create( pj_pool_t *pool,
void **p_state )
{
echo_supp *ec;
+ pj_status_t status;
PJ_UNUSED_ARG(clock_rate);
PJ_UNUSED_ARG(options);
ec = pj_pool_zalloc(pool, sizeof(struct echo_supp));
- ec->threshold = PJMEDIA_ECHO_SUPPRESS_THRESHOLD;
ec->samples_per_frame = samples_per_frame;
ec->tail_ms = tail_ms;
+ status = pjmedia_silence_det_create(pool, clock_rate, samples_per_frame,
+ &ec->sd);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ pjmedia_silence_det_set_name(ec->sd, "ecsu%p");
+ pjmedia_silence_det_set_adaptive(ec->sd, PJMEDIA_ECHO_SUPPRESS_THRESHOLD);
+ pjmedia_silence_det_set_params(ec->sd, 0, 500, 3000);
+
*p_state = ec;
return PJ_SUCCESS;
}
@@ -109,17 +118,16 @@ PJ_DEF(pj_status_t) echo_supp_playback( void *state,
pj_int16_t *play_frm )
{
echo_supp *ec = state;
+ pj_bool_t silence;
pj_bool_t last_suppressing = ec->suppressing;
- unsigned level;
- level = pjmedia_calc_avg_signal(play_frm, ec->samples_per_frame);
- level = linear2ulaw(level) ^ 0xff;
+ silence = pjmedia_silence_det_detect(ec->sd, play_frm,
+ ec->samples_per_frame, NULL);
+
+ ec->suppressing = !silence;
- if (level >= ec->threshold) {
+ if (ec->suppressing) {
pj_gettimeofday(&ec->last_signal);
- ec->suppressing = 1;
- } else {
- ec->suppressing = 0;
}
if (ec->suppressing!=0 && last_suppressing==0) {
@@ -168,15 +176,15 @@ PJ_DEF(pj_status_t) echo_supp_cancel_echo( void *state,
void *reserved )
{
echo_supp *ec = state;
- unsigned level;
+ pj_bool_t silence;
PJ_UNUSED_ARG(options);
PJ_UNUSED_ARG(reserved);
- level = pjmedia_calc_avg_signal(play_frm, ec->samples_per_frame);
- level = linear2ulaw(level) ^ 0xff;
+ silence = pjmedia_silence_det_detect(ec->sd, play_frm,
+ ec->samples_per_frame, NULL);
- if (level >= ec->threshold) {
+ if (!silence) {
pjmedia_zero_samples(rec_frm, ec->samples_per_frame);
}
diff --git a/pjmedia/src/pjmedia/silencedet.c b/pjmedia/src/pjmedia/silencedet.c
index e8f4952c..c0b5d2c3 100644
--- a/pjmedia/src/pjmedia/silencedet.c
+++ b/pjmedia/src/pjmedia/silencedet.c
@@ -38,6 +38,8 @@ typedef enum pjmedia_silence_det_mode {
*/
struct pjmedia_silence_det
{
+ char objname[PJ_MAX_OBJ_NAME]; /**< VAD name. */
+
int mode; /**< VAD mode. */
unsigned ptime; /**< Frame time, in msec. */
@@ -70,6 +72,9 @@ PJ_DEF(pj_status_t) pjmedia_silence_det_create( pj_pool_t *pool,
sd = pj_pool_zalloc(pool, sizeof(struct pjmedia_silence_det));
+ pj_ansi_strncpy(sd->objname, THIS_FILE, PJ_MAX_OBJ_NAME);
+ sd->objname[PJ_MAX_OBJ_NAME-1] = '\0';
+
sd->ptime = samples_per_frame * 1000 / clock_rate;
sd->signal_cnt = 0;
sd->silence_cnt = 0;
@@ -87,6 +92,18 @@ PJ_DEF(pj_status_t) pjmedia_silence_det_create( pj_pool_t *pool,
return PJ_SUCCESS;
}
+
+PJ_DEF(pj_status_t) pjmedia_silence_det_set_name( pjmedia_silence_det *sd,
+ const char *name)
+{
+ PJ_ASSERT_RETURN(sd && name, PJ_EINVAL);
+
+ pj_ansi_snprintf(sd->objname, PJ_MAX_OBJ_NAME, name, sd);
+ sd->objname[PJ_MAX_OBJ_NAME-1] = '\0';
+ return PJ_SUCCESS;
+}
+
+
PJ_DEF(pj_status_t) pjmedia_silence_det_set_adaptive(pjmedia_silence_det *sd,
int threshold)
{
@@ -233,7 +250,7 @@ PJ_DEF(pj_bool_t) pjmedia_silence_det_apply( pjmedia_silence_det *sd,
if (sd->mode == VAD_MODE_ADAPTIVE) {
pj_bool_t updated = PJ_TRUE;
- unsigned pct_signal;
+ unsigned pct_signal, new_threshold = sd->cur_threshold;
/* Get percentage of signal */
pct_signal = sd->signal_cnt * 100 /
@@ -241,19 +258,20 @@ PJ_DEF(pj_bool_t) pjmedia_silence_det_apply( pjmedia_silence_det *sd,
/* Adjust according to signal/silence proportions. */
if (pct_signal > 95) {
- sd->cur_threshold += (sd->weakest_signal - sd->cur_threshold)/4;
+ new_threshold += (sd->weakest_signal - sd->cur_threshold)/4;
} else if (pct_signal < 5) {
- sd->cur_threshold = (sd->cur_threshold+sd->loudest_silence)/2+1;
+ new_threshold = (sd->cur_threshold+sd->loudest_silence)/2+1;
} else if (pct_signal > 90) {
- sd->cur_threshold++;
+ new_threshold++;
} else if (pct_signal < 10) {
- sd->cur_threshold--;
+ new_threshold--;
} else {
updated = PJ_FALSE;
}
- if (updated) {
- PJ_LOG(5,(THIS_FILE, "Vad cur_threshold updated to %d",
+ if (updated && sd->cur_threshold != new_threshold) {
+ sd->cur_threshold = new_threshold;
+ PJ_LOG(5,(sd->objname, "Vad cur_threshold updated to %d",
sd->cur_threshold));
}
}