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

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Mar 8 10:46:20 CST 2011


Author: dvossel
Date: Tue Mar  8 10:46:15 2011
New Revision: 309995

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=309995
Log:
Store samples from each channel in softmix into array to avoid mixing while locking/unlocking

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=309995&r1=309994&r2=309995
==============================================================================
--- team/dvossel/hd_confbridge/bridges/bridge_softmix.c (original)
+++ team/dvossel/hd_confbridge/bridges/bridge_softmix.c Tue Mar  8 10:46:15 2011
@@ -345,20 +345,46 @@
 	struct mixing_stats stats;
 	struct softmix_bridge_data *bridge_data = bridge->bridge_pvt;
 	struct ast_timer *timer = bridge_data->timer;
-	short *data1, *data2;
 	int timingfd = ast_timer_fd(timer);
 	int update_all_rates = 0; /* set this when the internal sample rate has changed */
 	unsigned int stat_iteration_counter = SOFTMIX_STAT_INTERVAL; /* counts down, gather stats at zero and reset. */
-	int i;
+	int i, x;
+	struct {
+		int max_num_entries;
+		int used_entries;
+		int16_t **buffers;
+	} mixing_array = {
+		.max_num_entries = bridge->num + 10, /* give it room to grow, memory is cheap but allocations are expensive */
+	};
+
+	if (!(mixing_array.buffers = ast_calloc(mixing_array.max_num_entries, sizeof(int16_t *)))) {
+		ast_log(LOG_NOTICE, "Failed to allocate softmix mixing structure. \n");
+		return -1;
+	}
 
 	ast_timer_set_rate(timer, (1000 / SOFTMIX_INTERVAL));
 
 	while (!bridge->stop && !bridge->refresh && bridge->array_num) {
 		struct ast_bridge_channel *bridge_channel = NULL;
-		short buf[MAX_DATALEN] = {0, };
+		int16_t buf[MAX_DATALEN] = {0, };
 		int timeout = -1;
 		unsigned int softmix_samples = SOFTMIX_SAMPLES(bridge_data->internal_rate);
 		unsigned int softmix_datalen = SOFTMIX_DATALEN(bridge_data->internal_rate);
+
+		/* If the number of participants in the bridge has changed, the mixing array
+		 * buffer must realloc */
+		if (mixing_array.max_num_entries < bridge->num) {
+			int16_t **tmp;
+			/* give it some room to grow since memory is cheap but allocations can be expensive */
+			mixing_array.max_num_entries = bridge->num + 5;
+			if (!(tmp = ast_realloc(mixing_array.buffers, (mixing_array.max_num_entries * sizeof(int16_t *))))) {
+				ast_log(LOG_NOTICE, "Failed to re-allocate softmix mixing structure. \n");
+				ast_free(mixing_array.buffers);
+				return -1;
+			}
+			mixing_array.buffers = tmp;
+		}
+		mixing_array.used_entries = 0;
 
 		/* these variables help determine if a rate change is required */
 		if (!stat_iteration_counter) {
@@ -389,15 +415,19 @@
 			/* Try to get audio from the factory if available */
 			if ((ast_slinfactory_available(&sc->factory) >= softmix_samples) &&
 				ast_slinfactory_read(&sc->factory, sc->our_buf, softmix_samples)) {
-
-				/* Put into the local final buffer */
-				for (i = 0, data1 = buf, data2 = sc->our_buf; i < softmix_datalen; i++, data1++, data2++) {
-					ast_slinear_saturated_add(data1, data2);
-				}
+				mixing_array.buffers[mixing_array.used_entries] = sc->our_buf;
+				mixing_array.used_entries++;
 				/* Yay we have our own audio */
 				sc->have_audio = 1;
 			}
 			ast_mutex_unlock(&sc->lock);
+		}
+
+		/* mix it like crazy */
+		for (i = 0; i < mixing_array.used_entries; i++) {
+			for (x = 0; x < softmix_datalen; x++) {
+				ast_slinear_saturated_add(buf + x, mixing_array.buffers[i] + x);
+			}
 		}
 
 		/* Next step go through removing the channel's own audio and creating a good frame... */
@@ -441,6 +471,7 @@
 		ao2_lock(bridge);
 	}
 
+	ast_free(mixing_array.buffers);
 	return 0;
 }
 




More information about the asterisk-commits mailing list