From 5ce66989b6ae3e5370e05a5170091d48b799dc08 Mon Sep 17 00:00:00 2001
From: Anthony Minessale <anthony.minessale@gmail.com>
Date: Sat, 9 Jun 2007 23:02:38 +0000
Subject: [PATCH] add adjustable buffering to mod_shout (see example in config
 file)

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5302 d0543943-73ff-0310-b7d9-9358b9ac24b2
---
 conf/default_context.xml               | 10 ++++++++++
 src/include/switch_module_interfaces.h |  2 ++
 src/mod/formats/mod_shout/mod_shout.c  |  9 ++++++++-
 src/switch_ivr_play_say.c              | 11 +++++++++++
 4 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/conf/default_context.xml b/conf/default_context.xml
index 19d65a7d9d..2efe1bc827 100644
--- a/conf/default_context.xml
+++ b/conf/default_context.xml
@@ -19,6 +19,16 @@
     </condition>
   </extension>
 
+  <extension name="9192">
+    <condition field="destination_number" expression="^9192$">
+      <!-- Maintain Buffer of 128k of audio (default is 64k) -->
+      <action application="set" data="stream_prebuffer=131072"/>
+      <!-- Play a stream -->
+      <action application="playback" data="shout://mp3.ihets.org/wfyihd132"/>
+    </condition>
+  </extension>
+
+
   <!-- Example extension for require auth per-call. -->
   <extension name="9191">
     <!-- Match the destination digits of 9191 -->
diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h
index 34392f077e..a8967536e9 100644
--- a/src/include/switch_module_interfaces.h
+++ b/src/include/switch_module_interfaces.h
@@ -221,6 +221,8 @@ struct switch_file_handle {
 	int speed;
 	/*! the handle's memory pool */
 	switch_memory_pool_t *memory_pool;
+	/*! pre-buffer x bytes for streams */
+	uint32_t prebuf;
 	/*! private data for the format module to store handle specific info */
 	void *private_info;
 	char *handler;
diff --git a/src/mod/formats/mod_shout/mod_shout.c b/src/mod/formats/mod_shout/mod_shout.c
index 40bac015a1..d7b91cd317 100644
--- a/src/mod/formats/mod_shout/mod_shout.c
+++ b/src/mod/formats/mod_shout/mod_shout.c
@@ -65,6 +65,7 @@ struct shout_context {
 	int samplerate;
 	uint8_t thread_running;
 	uint8_t shout_init;
+    uint32_t prebuf;
 };
 
 typedef struct shout_context shout_context_t;
@@ -336,6 +337,10 @@ static size_t stream_callback(void *ptr, size_t size, size_t nmemb, void *data)
 
 	error_check();
 
+    if (context->prebuf) {
+        buf_size = context->prebuf;
+    }
+
 	/* make sure we aren't over zealous by slowing down the stream when the buffer is too full */
 	for (;;) {
 		error_check();
@@ -350,10 +355,11 @@ static size_t stream_callback(void *ptr, size_t size, size_t nmemb, void *data)
 		switch_mutex_unlock(context->audio_mutex);
 
 		if (used < buf_size) {
+            //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Buffered %u/%u!\n", used, buf_size);
 			break;
 		}
 
-		switch_yield(1000000);
+		switch_yield(500000);
 	}
 
 	error_check();
@@ -556,6 +562,7 @@ static switch_status_t shout_file_open(switch_file_handle_t *handle, char *path)
 		InitMP3(&context->mp, OUTSCALE, context->samplerate);
 		if (handle->handler) {
 			context->stream_url = switch_core_sprintf(context->memory_pool, "http://%s", path);
+            context->prebuf = handle->prebuf;
 			launch_read_stream_thread(context);
 		} else {
 			if (switch_file_open(&context->fd, path, SWITCH_FOPEN_READ, SWITCH_FPROT_UREAD | SWITCH_FPROT_UWRITE, handle->memory_pool) !=
diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c
index 339e7fa592..ea33923c44 100644
--- a/src/switch_ivr_play_say.c
+++ b/src/switch_ivr_play_say.c
@@ -505,6 +505,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
 	char *ext;
 	char *prefix;
 	char *timer_name;
+	char *prebuf;
 
 	channel = switch_core_session_get_channel(session);
 	assert(channel != NULL);
@@ -512,6 +513,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
 	prefix = switch_channel_get_variable(channel, "sound_prefix");
 	timer_name = switch_channel_get_variable(channel, "timer_name");
 
+
 	if (!file) {
 		return SWITCH_STATUS_FALSE;
 	}
@@ -552,6 +554,15 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
 		fh->samples = 0;
 	}
 
+	if ((prebuf = switch_channel_get_variable(channel, "stream_prebuffer"))) {
+		int maybe = atoi(prebuf);
+		if (maybe > 0) {
+			fh->prebuf = maybe;
+		}
+	}
+	
+
+
 	if (switch_core_file_open(fh,
 							  file,
 							  read_codec->implementation->number_of_channels,