[asterisk-commits] dvossel: branch dvossel/hd_confbridge r311293 - in /team/dvossel/hd_confbridg...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Mar 17 17:10:54 CDT 2011


Author: dvossel
Date: Thu Mar 17 17:10:49 2011
New Revision: 311293

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=311293
Log:
Ability to pass talking detection arguments from the application layer to the bridge tech layer

Modified:
    team/dvossel/hd_confbridge/apps/app_confbridge.c
    team/dvossel/hd_confbridge/apps/confbridge/include/confbridge.h
    team/dvossel/hd_confbridge/bridges/bridge_builtin_features.c
    team/dvossel/hd_confbridge/bridges/bridge_softmix.c
    team/dvossel/hd_confbridge/include/asterisk/bridging.h
    team/dvossel/hd_confbridge/main/bridging.c

Modified: team/dvossel/hd_confbridge/apps/app_confbridge.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/apps/app_confbridge.c?view=diff&rev=311293&r1=311292&r2=311293
==============================================================================
--- team/dvossel/hd_confbridge/apps/app_confbridge.c (original)
+++ team/dvossel/hd_confbridge/apps/app_confbridge.c Thu Mar 17 17:10:49 2011
@@ -94,6 +94,9 @@
 /* Number of buckets our conference bridges container can have */
 #define CONFERENCE_BRIDGE_BUCKETS 53
 
+#define DEFAULT_TALKING_THRESHOLD 160
+#define DEFAULT_SILENCE_THRESHOLD 2500
+
 /*! \brief Container to hold all conference bridges in progress */
 static struct ao2_container *conference_bridges;
 
@@ -184,7 +187,7 @@
 
 	ast_answer(chan);
 	pbx_exec(chan, mixmonapp, ast_str_buffer(filename));
-	ast_bridge_join(conference_bridge->bridge, chan, NULL, NULL);
+	ast_bridge_join(conference_bridge->bridge, chan, NULL, NULL, NULL);
 
 	chan = ast_channel_unref(chan);
 
@@ -517,7 +520,7 @@
 		memcpy(&conference_bridge->b_profile, &conference_bridge_user->b_profile, sizeof(conference_bridge->b_profile));
 
 		/* Create an actual bridge that will do the audio mixing */
-		if (!(conference_bridge->bridge = ast_bridge_new(AST_BRIDGE_CAPABILITY_1TO1MIX, AST_BRIDGE_FLAG_SMART))) {
+		if (!(conference_bridge->bridge = ast_bridge_new(AST_BRIDGE_CAPABILITY_MULTIMIX, 0))) {
 			ao2_ref(conference_bridge, -1);
 			conference_bridge = NULL;
 			ao2_unlock(conference_bridges);
@@ -813,6 +816,9 @@
 	struct conference_bridge *conference_bridge = NULL;
 	struct conference_bridge_user conference_bridge_user = {
 		.chan = chan,
+		.tech_args.talking_threshold = DEFAULT_TALKING_THRESHOLD,
+		.tech_args.silence_threshold = DEFAULT_SILENCE_THRESHOLD,
+		.tech_args.drop_silence = 0,
 	};
 	const char *tmp, *join_sound = NULL, *leave_sound = NULL;
 	int quiet = 0;
@@ -936,7 +942,11 @@
 	}
 
 	/* Join our conference bridge for real */
-	ast_bridge_join(conference_bridge->bridge, chan, NULL, &conference_bridge_user.features);
+	ast_bridge_join(conference_bridge->bridge,
+		chan,
+		NULL,
+		&conference_bridge_user.features,
+		&conference_bridge_user.tech_args);
 
 	/* if this user has a intro, play it when leaving */
 	if (!quiet && !ast_strlen_zero(conference_bridge_user.name_rec_location)) {

Modified: team/dvossel/hd_confbridge/apps/confbridge/include/confbridge.h
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/apps/confbridge/include/confbridge.h?view=diff&rev=311293&r1=311292&r2=311293
==============================================================================
--- team/dvossel/hd_confbridge/apps/confbridge/include/confbridge.h (original)
+++ team/dvossel/hd_confbridge/apps/confbridge/include/confbridge.h Thu Mar 17 17:10:49 2011
@@ -141,6 +141,7 @@
 	char name_rec_location[PATH_MAX];            /*!< Location of the User's name recorded file if it exists */
 	struct ast_channel *chan;                    /*!< Asterisk channel participating */
 	struct ast_bridge_features features;         /*!< Bridge features structure */
+	struct ast_bridge_tech_optimizations tech_args; /*!< Bridge technology optimizations for talk detection */
 	unsigned int kicked:1;                       /*!< User has been kicked from the conference */
 	AST_LIST_ENTRY(conference_bridge_user) list; /*!< Linked list information */
 };

Modified: team/dvossel/hd_confbridge/bridges/bridge_builtin_features.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/bridges/bridge_builtin_features.c?view=diff&rev=311293&r1=311292&r2=311293
==============================================================================
--- team/dvossel/hd_confbridge/bridges/bridge_builtin_features.c (original)
+++ team/dvossel/hd_confbridge/bridges/bridge_builtin_features.c Thu Mar 17 17:10:49 2011
@@ -203,7 +203,7 @@
 				 attended_abort_transfer, NULL, NULL);
 
 	/* But for the caller we want to join the bridge in a blocking fashion so we don't spin around in this function doing nothing while waiting */
-	attended_bridge_result = ast_bridge_join(attended_bridge, bridge_channel->chan, NULL, &caller_features);
+	attended_bridge_result = ast_bridge_join(attended_bridge, bridge_channel->chan, NULL, &caller_features, NULL);
 
 	/* Since the above returned the caller features structure is of no more use */
 	ast_bridge_features_cleanup(&caller_features);

Modified: team/dvossel/hd_confbridge/bridges/bridge_softmix.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/bridges/bridge_softmix.c?view=diff&rev=311293&r1=311292&r2=311293
==============================================================================
--- team/dvossel/hd_confbridge/bridges/bridge_softmix.c (original)
+++ team/dvossel/hd_confbridge/bridges/bridge_softmix.c Thu Mar 17 17:10:49 2011
@@ -65,7 +65,8 @@
 
 /* This is the threshold in ms at which a channel's own audio will stop getting
  * mixed out its own write audio stream because it is not talking. */
-#define SILENCE_THRESHOLD 2500
+#define DEFAULT_SOFTMIX_SILENCE_THRESHOLD 2500
+#define DEFAULT_SOFTMIX_TALKING_THRESHOLD 160
 
 /*! \brief Structure which contains per-channel mixing information */
 struct softmix_channel {
@@ -311,6 +312,8 @@
 static void set_softmix_bridge_data(int rate, struct ast_bridge_channel *bridge_channel, int reset)
 {
 	struct softmix_channel *sc = bridge_channel->bridge_pvt;
+	unsigned int channel_read_rate = ast_format_rate(&bridge_channel->chan->rawreadformat);
+
 	ast_mutex_lock(&sc->lock);
 	if (reset) {
 		ast_slinfactory_destroy(&sc->factory);
@@ -324,23 +327,26 @@
 	sc->write_frame.samples = SOFTMIX_SAMPLES(rate);
 
 	sc->read_frame.frametype = AST_FRAME_VOICE;
-	ast_format_set(&sc->read_frame.subclass.format, ast_format_slin_by_rate(rate), 0);
+	ast_format_set(&sc->read_frame.subclass.format, ast_format_slin_by_rate(channel_read_rate), 0);
 	sc->read_frame.data.ptr = sc->our_buf;
-	sc->read_frame.datalen = SOFTMIX_DATALEN(rate);
-	sc->read_frame.samples = SOFTMIX_SAMPLES(rate);
-
+	sc->read_frame.datalen = SOFTMIX_DATALEN(channel_read_rate);
+	sc->read_frame.samples = SOFTMIX_SAMPLES(channel_read_rate);
 
 	/* Setup smoother */
 	ast_slinfactory_init_with_format(&sc->factory, &sc->write_frame.subclass.format);
 
 	/* set new read and write formats on channel. */
-	ast_set_read_format(bridge_channel->chan, &sc->write_frame.subclass.format);
+	ast_set_read_format(bridge_channel->chan, &sc->read_frame.subclass.format);
 	ast_set_write_format(bridge_channel->chan, &sc->write_frame.subclass.format);
 
-	/* set up new DSP */
-	sc->dsp = ast_dsp_new_with_rate(rate);
+	/* set up new DSP.  This is on the read side only right before the read frame enters the smoother.  */
+	sc->dsp = ast_dsp_new_with_rate(channel_read_rate);
 	/* we want to aggressively detect silence to avoid feedback */
-	ast_dsp_set_threshold(sc->dsp, 160);
+	if (bridge_channel->tech_args.talking_threshold) {
+		ast_dsp_set_threshold(sc->dsp, bridge_channel->tech_args.talking_threshold);
+	} else {
+		ast_dsp_set_threshold(sc->dsp, DEFAULT_SOFTMIX_TALKING_THRESHOLD);
+	}
 
 	ast_mutex_unlock(&sc->lock);
 }
@@ -398,7 +404,10 @@
 	struct softmix_channel *sc = bridge_channel->bridge_pvt;
 	struct softmix_bridge_data *bridge_data = bridge->bridge_pvt;
 	int totalsilence = 0;
-	int update_talking = -1;  /* if this is set to 0 or 1, tell the bridge that the channel has started or stopped talking. */
+	int silence_threshold = bridge_channel->tech_args.silence_threshold ?
+		bridge_channel->tech_args.silence_threshold :
+		DEFAULT_SOFTMIX_SILENCE_THRESHOLD;
+	char update_talking = -1;  /* if this is set to 0 or 1, tell the bridge that the channel has started or stopped talking. */
 
 	/* Only accept audio frames, all others are unsupported */
 	if (frame->frametype != AST_FRAME_VOICE) {
@@ -408,7 +417,7 @@
 	ast_mutex_lock(&sc->lock);
 
 	ast_dsp_silence(sc->dsp, frame, &totalsilence);
-	if (totalsilence < SILENCE_THRESHOLD) {
+	if (totalsilence < silence_threshold) {
 		if (!sc->talking) {
 			update_talking = 1;
 		}
@@ -427,8 +436,10 @@
 		ast_slinfactory_flush(&sc->factory);
 	}
 
-	/* If a frame was provided add it to the smoother */
-	if (frame->frametype == AST_FRAME_VOICE && ast_format_is_slinear(&frame->subclass.format)) {
+	/* If a frame was provided add it to the smoother, unless drop silence is enabled and this frame
+	 * is not determined to be talking. */
+	if (!(bridge_channel->tech_args.drop_silence && !sc->talking) &&
+		(frame->frametype == AST_FRAME_VOICE && ast_format_is_slinear(&frame->subclass.format))) {
 		ast_slinfactory_feed(&sc->factory, frame);
 	}
 
@@ -757,7 +768,7 @@
 
 static struct ast_bridge_technology softmix_bridge = {
 	.name = "softmix",
-	.capabilities = AST_BRIDGE_CAPABILITY_MULTIMIX | AST_BRIDGE_CAPABILITY_THREAD | AST_BRIDGE_CAPABILITY_MULTITHREADED,
+	.capabilities = AST_BRIDGE_CAPABILITY_MULTIMIX | AST_BRIDGE_CAPABILITY_THREAD | AST_BRIDGE_CAPABILITY_MULTITHREADED | AST_BRIDGE_CAPABILITY_OPTIMIZE,
 	.preference = AST_BRIDGE_PREFERENCE_LOW,
 	.create = softmix_bridge_create,
 	.destroy = softmix_bridge_destroy,

Modified: team/dvossel/hd_confbridge/include/asterisk/bridging.h
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/include/asterisk/bridging.h?view=diff&rev=311293&r1=311292&r2=311293
==============================================================================
--- team/dvossel/hd_confbridge/include/asterisk/bridging.h (original)
+++ team/dvossel/hd_confbridge/include/asterisk/bridging.h Thu Mar 17 17:10:49 2011
@@ -115,6 +115,22 @@
 
 struct ast_bridge_technology;
 struct ast_bridge;
+
+/*!
+ * \brief Structure specific to bridge technologies capable of
+ * performing talking optimizations.
+ */
+struct ast_bridge_tech_optimizations {
+	/*! The amount of time in ms that talking must be detected before
+	 *  the dsp determines that talking has occurred */
+	unsigned int talking_threshold;
+	/*! The amount of time in ms that silence must be detected before
+	 *  the dsp determines that talking has stopped */
+	unsigned int silence_threshold;
+	/*! Whether or not the bridging technology should drop audio
+	 *  detected as silence from the mix. */
+	unsigned int drop_silence:1;
+};
 
 /*!
  * \brief Structure that contains information regarding a channel in a bridge
@@ -142,10 +158,11 @@
 	unsigned int suspended:1;
 	/*! Features structure for features that are specific to this channel */
 	struct ast_bridge_features *features;
+	/*! Technology optimization parameters used by bridging technologies capable of
+	 *  optimizing based upon talk detection. */
+	struct ast_bridge_tech_optimizations tech_args;
 	/*! Queue of DTMF digits used for DTMF streaming */
 	char dtmf_stream_q[8];
-	/*! DSP used for silence and noise detection */
-	struct ast_dsp *dsp;
 	/*! Linked list information */
 	AST_LIST_ENTRY(ast_bridge_channel) entry;
 };
@@ -246,6 +263,7 @@
  * \param chan Channel to join
  * \param swap Channel to swap out if swapping
  * \param features Bridge features structure
+ * \param (Optional) Bridging tech optimization parameters for this channel.
  *
  * \retval state that channel exited the bridge with
  *
@@ -266,7 +284,11 @@
  * If channel specific features are enabled a pointer to the features structure
  * can be specified in the features parameter.
  */
-enum ast_bridge_channel_state ast_bridge_join(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features);
+enum ast_bridge_channel_state ast_bridge_join(struct ast_bridge *bridge,
+	struct ast_channel *chan,
+	struct ast_channel *swap,
+	struct ast_bridge_features *features,
+	struct ast_bridge_tech_optimizations *tech_args);
 
 /*! \brief Impart (non-blocking) a channel on a bridge
  *

Modified: team/dvossel/hd_confbridge/main/bridging.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/main/bridging.c?view=diff&rev=311293&r1=311292&r2=311293
==============================================================================
--- team/dvossel/hd_confbridge/main/bridging.c (original)
+++ team/dvossel/hd_confbridge/main/bridging.c Thu Mar 17 17:10:49 2011
@@ -1028,7 +1028,11 @@
 	return bridge_channel->state;
 }
 
-enum ast_bridge_channel_state ast_bridge_join(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features)
+enum ast_bridge_channel_state ast_bridge_join(struct ast_bridge *bridge,
+	struct ast_channel *chan,
+	struct ast_channel *swap,
+	struct ast_bridge_features *features,
+	struct ast_bridge_tech_optimizations *tech_args)
 {
 	struct ast_bridge_channel bridge_channel = {
 		.chan = chan,
@@ -1038,6 +1042,9 @@
 	};
 	enum ast_bridge_channel_state state;
 
+	if (tech_args) {
+		memcpy(&bridge_channel.tech_args, tech_args, sizeof(bridge_channel.tech_args));
+	}
 	/* Initialize various other elements of the bridge channel structure that we can't do above */
 	ast_mutex_init(&bridge_channel.lock);
 	ast_cond_init(&bridge_channel.cond, NULL);
@@ -1058,7 +1065,6 @@
 static struct ast_bridge_channel *free_bridge_channel(struct ast_bridge_channel *bridge_channel)
 {
 	/* Destroy elements of the bridge channel structure and the bridge channel structure itself */
-	ast_dsp_free(bridge_channel->dsp);
 	ast_mutex_destroy(&bridge_channel->lock);
 	ast_cond_destroy(&bridge_channel->cond);
 




More information about the asterisk-commits mailing list