[asterisk-commits] dvossel: branch dvossel/hd_confbridge r310284 - /team/dvossel/hd_confbridge/b...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Mar 10 12:25:49 CST 2011


Author: dvossel
Date: Thu Mar 10 12:25:47 2011
New Revision: 310284

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=310284
Log:
Experimental change to how softmix mixes out a channel's own audio.

Modified:
    team/dvossel/hd_confbridge/bridges/bridge_softmix.c

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=310284&r1=310283&r2=310284
==============================================================================
--- team/dvossel/hd_confbridge/bridges/bridge_softmix.c (original)
+++ team/dvossel/hd_confbridge/bridges/bridge_softmix.c Thu Mar 10 12:25:47 2011
@@ -60,12 +60,12 @@
 /*! \brief Number of samples we are dealing with */
 #define SOFTMIX_SAMPLES(rate) (SOFTMIX_DATALEN(rate) / 2)
 
-/*! \brief Number of mixing iterations to perform between
- * gathering statistics. */
-#define SOFTMIX_STAT_INTERVAL 50
-
-/*! \brief Define used to turn on 16 kHz audio support */
-/* #define SOFTMIX_16_SUPPORT */
+/*! \brief Number of mixing iterations to perform between gathering statistics. */
+#define SOFTMIX_STAT_INTERVAL 100
+
+/* 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 4000
 
 /*! \brief Structure which contains per-channel mixing information */
 struct softmix_channel {
@@ -74,7 +74,13 @@
 	/*! Factory which contains audio read in from the channel */
 	struct ast_slinfactory factory;
 	/*! Frame that contains mixed audio to be written out to the channel */
-	struct ast_frame frame;
+	struct ast_frame write_frame;
+	/*! Frame that contains mixed audio read from the channel */
+	struct ast_frame read_frame;
+	/*! DSP for detecting silence */
+	struct ast_dsp *dsp;
+	/*! The total amount of silence up until the last audio frame */
+	int totalsilence;
 	/*! Bit used to indicate that the channel provided audio for this mixing interval */
 	int have_audio:1;
 	/*! Bit used to indicate that a frame is available to be written out to the channel */
@@ -179,10 +185,33 @@
 	AST_LIST_TRAVERSE_SAFE_END;
 }
 
-
 /*!
  * \internal
- * \brief Process a softmix channels write audio
+ * \brief Get the next available audio on the softmix channel's read stream
+ * and determine if it should be mixed out or not on the write stream. 
+ *
+ * \retval pointer to buffer containing the exact number of samples requested on success.
+ * \retval NULL if no samples are present
+ */
+static int16_t *softmix_process_read_audio(struct softmix_channel *sc, unsigned int num_samples)
+{
+	sc->have_audio = 0;
+	if ((ast_slinfactory_available(&sc->factory) >= num_samples) &&
+		ast_slinfactory_read(&sc->factory, sc->our_buf, num_samples)) {
+		sc->totalsilence = 0;
+		ast_dsp_silence(sc->dsp, &sc->read_frame, &sc->totalsilence);
+		if (sc->totalsilence < SILENCE_THRESHOLD) {
+			sc->have_audio = 1; /* tell the write process we have audio to be mixed out */
+		}
+		ast_mutex_unlock(&sc->lock);
+		return sc->our_buf;
+	}
+	return NULL;
+}
+
+/*!
+ * \internal
+ * \brief Process a softmix channel's write audio
  *
  * \details This function will remove the channel's talking from its own audio if present and
  * possibly even do the channel's write translation for it depending on how many other
@@ -195,9 +224,10 @@
 	struct softmix_translate_helper_entry *entry = NULL;
 	int i;
 
-	/* If we provided audio then take it out while in slinear format. */
+	/* If we provided audio that was not determined to be silence,
+	 * then take it out while in slinear format. */
 	if (sc->have_audio) {
-		for (i = 0; i < sc->frame.samples; i++) {
+		for (i = 0; i < sc->write_frame.samples; i++) {
 			ast_slinear_saturated_subtract(&sc->final_buf[i], &sc->our_buf[i]);
 		}
 		/* do not do any special write translate optimization if we had to make
@@ -215,13 +245,13 @@
 			entry->trans_pvt = ast_translator_build_path(&entry->dst_format, &trans_helper->slin_src);
 		}
 		if (entry->trans_pvt && !entry->out_frame) {
-			entry->out_frame = ast_translate(entry->trans_pvt, &sc->frame, 0);
+			entry->out_frame = ast_translate(entry->trans_pvt, &sc->write_frame, 0);
 		}
 		if (entry->out_frame && (entry->out_frame->datalen < MAX_DATALEN)) {
-			ast_format_copy(&sc->frame.subclass.format, &entry->out_frame->subclass.format);
+			ast_format_copy(&sc->write_frame.subclass.format, &entry->out_frame->subclass.format);
 			memcpy(sc->final_buf, entry->out_frame->data.ptr, entry->out_frame->datalen);
-			sc->frame.datalen = entry->out_frame->datalen;
-			sc->frame.samples = entry->out_frame->samples;
+			sc->write_frame.datalen = entry->out_frame->datalen;
+			sc->write_frame.samples = entry->out_frame->samples;
 		}
 		break;
 	}
@@ -240,6 +270,7 @@
 			ast_frfree(entry->out_frame);
 			entry->out_frame = NULL;
 		}
+		entry->num_times_requested = 0;
 	}
 }
 
@@ -287,20 +318,32 @@
 	ast_mutex_lock(&sc->lock);
 	if (reset) {
 		ast_slinfactory_destroy(&sc->factory);
-	}
-	/* Setup frame parameters */
-	sc->frame.frametype = AST_FRAME_VOICE;
-
-	ast_format_set(&sc->frame.subclass.format, ast_format_slin_by_rate(rate), 0);
-	sc->frame.data.ptr = sc->final_buf;
-	sc->frame.datalen = SOFTMIX_DATALEN(rate);
-	sc->frame.samples = SOFTMIX_SAMPLES(rate);
+		ast_dsp_free(sc->dsp);
+	}
+	/* Setup read/write frame parameters */
+	sc->write_frame.frametype = AST_FRAME_VOICE;
+	ast_format_set(&sc->write_frame.subclass.format, ast_format_slin_by_rate(rate), 0);
+	sc->write_frame.data.ptr = sc->final_buf;
+	sc->write_frame.datalen = SOFTMIX_DATALEN(rate);
+	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);
+	sc->read_frame.data.ptr = sc->our_buf;
+	sc->read_frame.datalen = SOFTMIX_DATALEN(rate);
+	sc->read_frame.samples = SOFTMIX_SAMPLES(rate);
+
 
 	/* Setup smoother */
-	ast_slinfactory_init_with_format(&sc->factory, &sc->frame.subclass.format);
-
-	ast_set_read_format(bridge_channel->chan, &sc->frame.subclass.format);
-	ast_set_write_format(bridge_channel->chan, &sc->frame.subclass.format);
+	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_write_format(bridge_channel->chan, &sc->write_frame.subclass.format);
+
+	/* set up new DSP */
+	sc->dsp = ast_dsp_new_with_rate(rate);
+
 	ast_mutex_unlock(&sc->lock);
 }
 
@@ -341,6 +384,9 @@
 
 	/* Drop the factory */
 	ast_slinfactory_destroy(&sc->factory);
+
+	/* Drop the DSP */
+	ast_dsp_free(sc->dsp);
 
 	/* Eep! drop ourselves */
 	ast_free(sc);
@@ -375,7 +421,7 @@
 
 	/* If a frame is ready to be written out, do so */
 	if (sc->have_frame) {
-		ast_write(bridge_channel->chan, &sc->frame);
+		ast_write(bridge_channel->chan, &sc->write_frame);
 		sc->have_frame = 0;
 	}
 
@@ -393,7 +439,7 @@
 	ast_mutex_lock(&sc->lock);
 
 	if (sc->have_frame) {
-		ast_write(bridge_channel->chan, &sc->frame);
+		ast_write(bridge_channel->chan, &sc->write_frame);
 		sc->have_frame = 0;
 	}
 
@@ -621,12 +667,8 @@
 
 			/* Try to get audio from the factory if available */
 			ast_mutex_lock(&sc->lock);
-			sc->have_audio = 0;
-			if ((ast_slinfactory_available(&sc->factory) >= softmix_samples) &&
-				ast_slinfactory_read(&sc->factory, sc->our_buf, softmix_samples)) {
-				mixing_array.buffers[mixing_array.used_entries] = sc->our_buf;
+			if ((mixing_array.buffers[mixing_array.used_entries] = softmix_process_read_audio(sc, softmix_samples))) {
 				mixing_array.used_entries++;
-				sc->have_audio = 1;
 			}
 			ast_mutex_unlock(&sc->lock);
 		}
@@ -650,11 +692,11 @@
 			ast_mutex_lock(&sc->lock);
 
 			/* Make SLINEAR write frame from local buffer */
-			if (sc->frame.subclass.format.id != cur_slin_id) {
-				ast_format_set(&sc->frame.subclass.format, cur_slin_id, 0);
-			}
-			sc->frame.datalen = softmix_datalen;
-			sc->frame.samples = softmix_samples;
+			if (sc->write_frame.subclass.format.id != cur_slin_id) {
+				ast_format_set(&sc->write_frame.subclass.format, cur_slin_id, 0);
+			}
+			sc->write_frame.datalen = softmix_datalen;
+			sc->write_frame.samples = softmix_samples;
 			memcpy(sc->final_buf, buf, softmix_datalen);
 
 			/* process the softmix channel's new write audio */
@@ -721,11 +763,7 @@
 	if (!(softmix_bridge.format_capabilities = ast_format_cap_alloc())) {
 		return AST_MODULE_LOAD_DECLINE;
 	}
-#ifdef SOFTMIX_16_SUPPORT
-	ast_format_cap_add(softmix_bridge.format_capabilities, ast_format_set(&tmp, AST_FORMAT_SLINEAR16, 0));
-#else
 	ast_format_cap_add(softmix_bridge.format_capabilities, ast_format_set(&tmp, AST_FORMAT_SLINEAR, 0));
-#endif
 	return ast_bridge_technology_register(&softmix_bridge);
 }
 




More information about the asterisk-commits mailing list