[Freeswitch-svn] [commit] r11200 - in freeswitch/trunk/src: . mod/formats/mod_shout

FreeSWITCH SVN anthm at freeswitch.org
Wed Jan 14 11:44:14 PST 2009


Author: anthm
Date: Wed Jan 14 13:44:14 2009
New Revision: 11200

Log:
fix buffering issue in mod_shout/core

Modified:
   freeswitch/trunk/src/mod/formats/mod_shout/mod_shout.c
   freeswitch/trunk/src/switch_core_file.c
   freeswitch/trunk/src/switch_ivr_play_say.c

Modified: freeswitch/trunk/src/mod/formats/mod_shout/mod_shout.c
==============================================================================
--- freeswitch/trunk/src/mod/formats/mod_shout/mod_shout.c	(original)
+++ freeswitch/trunk/src/mod/formats/mod_shout/mod_shout.c	Wed Jan 14 13:44:14 2009
@@ -116,6 +116,12 @@
 	int lame_ready;
 	int eof;
 	int channels;
+	int16_t *l;
+	switch_size_t llen;
+	int16_t *r;
+	switch_size_t rlen;
+	unsigned char *mp3buf;
+	switch_size_t mp3buflen;
 };
 
 typedef struct shout_context shout_context_t;
@@ -903,8 +909,7 @@
 static switch_status_t shout_file_write(switch_file_handle_t *handle, void *data, size_t *len)
 {
 	shout_context_t *context;
-	unsigned char mp3buf[8192] = "";
-	int rlen;
+	int rlen = 0;
 	int16_t *audio = data;
 	int nsamples = *len;
 
@@ -954,23 +959,32 @@
 		context->lame_ready = 1;
 	}
 
+	if (context->mp3buflen < nsamples * 4) {
+		context->mp3buflen = nsamples * 4;
+		context->mp3buf = switch_core_alloc(context->memory_pool, context->mp3buflen);
+	}
+
 	if (handle->channels == 2) {
-		int16_t l[4096] = { 0 };
-		int16_t r[4096] = { 0 };
 		int i, j = 0;
-
+		
+		if (context->llen < nsamples) {
+			context->l = switch_core_alloc(context->memory_pool, nsamples * 2);
+			context->r = switch_core_alloc(context->memory_pool, nsamples * 2);
+			context->llen = context->rlen = nsamples;
+		}
+		
 		for (i = 0; i < nsamples; i++) {
-			l[i] = audio[j++];
-			r[i] = audio[j++];
+			context->l[i] = audio[j++];
+			context->r[i] = audio[j++];
 		}
-
-		if ((rlen = lame_encode_buffer(context->gfp, l, r, nsamples, mp3buf, sizeof(mp3buf))) < 0) {
+		
+		if ((rlen = lame_encode_buffer(context->gfp, context->l, context->r, nsamples, context->mp3buf, context->mp3buflen)) < 0) {
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "MP3 encode error %d!\n", rlen);
 			return SWITCH_STATUS_FALSE;
 		}
 
 	} else if (handle->channels == 1) {
-		if ((rlen = lame_encode_buffer(context->gfp, audio, NULL, nsamples, mp3buf, sizeof(mp3buf))) < 0) {
+		if ((rlen = lame_encode_buffer(context->gfp, audio, NULL, nsamples, context->mp3buf, context->mp3buflen)) < 0) {
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "MP3 encode error %d!\n", rlen);
 			return SWITCH_STATUS_FALSE;
 		}
@@ -979,7 +993,7 @@
 	}
 
 	if (rlen) {
-		int ret = fwrite(mp3buf, 1, rlen, context->fp);
+		int ret = fwrite(context->mp3buf, 1, rlen, context->fp);
 		if (ret < 0) {
 			return SWITCH_STATUS_FALSE;
 		}
@@ -1445,7 +1459,7 @@
 		for (param = switch_xml_child(settings, "param"); param; param = param->next) {
 			char *var = (char *) switch_xml_attr_soft(param, "name");
 			char *val = (char *) switch_xml_attr_soft(param, "value");
-
+			
 			if (!strcmp(var, "decoder")) {
 				switch_set_string(globals.decoder, val);
 			} else if (!strcmp(var, "volume")) {

Modified: freeswitch/trunk/src/switch_core_file.c
==============================================================================
--- freeswitch/trunk/src/switch_core_file.c	(original)
+++ freeswitch/trunk/src/switch_core_file.c	Wed Jan 14 13:44:14 2009
@@ -119,7 +119,7 @@
 
 	if (fh->pre_buffer_datalen) {
 		//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Prebuffering %d bytes\n", (int)fh->pre_buffer_datalen);
-		switch_buffer_create_dynamic(&fh->pre_buffer, fh->pre_buffer_datalen, fh->pre_buffer_datalen / 2, 0);
+		switch_buffer_create_dynamic(&fh->pre_buffer, fh->pre_buffer_datalen * fh->channels, fh->pre_buffer_datalen * fh->channels / 2, 0);
 		fh->pre_buffer_data = switch_core_alloc(fh->memory_pool, fh->pre_buffer_datalen);
 	}
 
@@ -248,16 +248,20 @@
 	if (!switch_test_flag(fh, SWITCH_FILE_NATIVE) && fh->native_rate != fh->samplerate) {
 		if (!fh->resampler) {
 			if (switch_resample_create(&fh->resampler,
-									   fh->native_rate, orig_len, fh->samplerate, (uint32_t) orig_len, fh->memory_pool) != SWITCH_STATUS_SUCCESS) {
+									   fh->native_rate, 
+									   orig_len * fh->channels, 
+									   fh->samplerate, 
+									   (uint32_t) orig_len *fh->channels, 
+									   fh->memory_pool) != SWITCH_STATUS_SUCCESS) {
 				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unable to create resampler!\n");
 				return SWITCH_STATUS_GENERR;
 			}
 		}
 
-		fh->resampler->from_len = switch_short_to_float(data, fh->resampler->from, (int) *len);
+		fh->resampler->from_len = switch_short_to_float(data, fh->resampler->from, (int) *len * fh->channels);
 		fh->resampler->to_len =
 			switch_resample_process(fh->resampler, fh->resampler->from, fh->resampler->from_len, fh->resampler->to, fh->resampler->to_size, 0);
-		if (fh->resampler->to_len > orig_len) {
+		if (fh->resampler->to_len > orig_len * fh->channels) {
 			if (!fh->dbuf) {
 				fh->dbuflen = fh->resampler->to_len * 2;
 				fh->dbuf = switch_core_alloc(fh->memory_pool, fh->dbuflen);
@@ -269,7 +273,7 @@
 			switch_float_to_short(fh->resampler->to, data, fh->resampler->to_len);
 		}
 
-		*len = fh->resampler->to_len;
+		*len = fh->resampler->to_len / fh->channels;
 
 	}
 
@@ -282,13 +286,14 @@
 		switch_size_t rlen, blen;
 		switch_status_t status = SWITCH_STATUS_SUCCESS;
 		int asis = switch_test_flag(fh, SWITCH_FILE_NATIVE);
-
-		switch_buffer_write(fh->pre_buffer, data, asis ? *len : *len * 2);
+		
+		switch_buffer_write(fh->pre_buffer, data, (asis ? *len : *len * 2) * fh->channels);
 
 		rlen = switch_buffer_inuse(fh->pre_buffer);
 		if (rlen >= fh->pre_buffer_datalen) {
 			blen = switch_buffer_read(fh->pre_buffer, fh->pre_buffer_data, fh->pre_buffer_datalen);
 			if (!asis) blen /= 2;
+			if (fh->channels) blen /= fh->channels;
 			if ((status = fh->file_interface->file_write(fh, fh->pre_buffer_data, &blen)) != SWITCH_STATUS_SUCCESS) {
 				*len = 0;
 			}
@@ -354,9 +359,6 @@
 		return SWITCH_STATUS_FALSE;
 	}
 
-	switch_clear_flag(fh, SWITCH_FILE_OPEN);
-	status = fh->file_interface->file_close(fh);
-
 	if (fh->buffer) {
 		switch_buffer_destroy(&fh->buffer);
 	}
@@ -369,6 +371,7 @@
 			while((rlen = switch_buffer_inuse(fh->pre_buffer))) {
 				blen = switch_buffer_read(fh->pre_buffer, fh->pre_buffer_data, fh->pre_buffer_datalen);
 				if (asis) blen /= 2;
+				if (fh->channels) blen /= fh->channels;
 				if (fh->file_interface->file_write(fh, fh->pre_buffer_data, &blen) != SWITCH_STATUS_SUCCESS) {
 					break;
 				}
@@ -378,6 +381,9 @@
 		switch_buffer_destroy(&fh->pre_buffer);
 	}
 
+	switch_clear_flag(fh, SWITCH_FILE_OPEN);
+	status = fh->file_interface->file_close(fh);
+
 	switch_resample_destroy(&fh->resampler);
 
 	UNPROTECT_INTERFACE(fh->file_interface);

Modified: freeswitch/trunk/src/switch_ivr_play_say.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr_play_say.c	(original)
+++ freeswitch/trunk/src/switch_ivr_play_say.c	Wed Jan 14 13:44:14 2009
@@ -420,6 +420,7 @@
 		}
 	}
 
+	fh->pre_buffer_datalen = SWITCH_DEFAULT_FILE_BUFFER_LEN;
 
 	if (switch_core_file_open(fh,
 							  file,



More information about the Freeswitch-svn mailing list