[Freeswitch-svn] [commit] r5591 - freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp

Freeswitch SVN greenlizard at freeswitch.org
Mon Aug 13 14:10:16 EDT 2007


Author: greenlizard
Date: Mon Aug 13 14:10:16 2007
New Revision: 5591

Modified:
   freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c

Log:
going to merge mod_openmrcp to trunk

Modified: freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c	(original)
+++ freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c	Mon Aug 13 14:10:16 2007
@@ -32,8 +32,29 @@
  *
  * Uses OpenMrcp (http://wiki.freeswitch.org/wiki/OpenMRCP) as the 
  * the client library.  
+ *
+ * TODO
+ * =======
+ *
+ * - MAJOR DESIGN ISSUE!!  It is way too expensive to be calling malloc on every audio frame,
+ * this needs to send the packet directly.  OpenMrcp will need a way to disable their own
+ * timer so that the fs timer is the only one driving the media.
+ * 
+ * - There are two memory pools in use.  One in asr_session which is managed
+ * by this module, and one in the switch_asr_handle_t, which is managed by freeswitch.
+ * These need to be consolidated into one.  (basically throw away the one in asr_session)
  * 
+ * - fs status codes (eg, SWITCH_STATUS_GENERR) and mrcp status codes (MRCP_STATUS_FAILURE)
+ * are intermixed badly.  this needs cleanup
+ * 
+ * - openmrcp_flush_tts, openmrcp_text_param_tts, openmrcp_numeric_param_tts, 
+ * openmrcp_float_param_tts need to have functionality added
+ *
+ * - fix audio problem with TTS, convert from using queue to using a switch_buffer
+ * (in progress)
+ *
  */
+
 #ifdef __ICC
 #pragma warning (disable:188)
 #endif
@@ -63,6 +84,8 @@
 #include <switch.h>
 	
 #define OPENMRCP_WAIT_TIMEOUT 5000
+#define MY_BUF_LEN 1024 * 32
+#define MY_BLOCK_SIZE MY_BUF_LEN
 
 SWITCH_MODULE_LOAD_FUNCTION(mod_openmrcp_load);
 SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_openmrcp_shutdown);
@@ -120,16 +143,16 @@
 struct tts_session_t {
 	mrcp_session_t        *client_session;
 	mrcp_client_channel_t *channel;
-	switch_queue_t        *audio_queue;
+	switch_queue_t        *audio_queue;  // TO BE REMOVED
 	switch_queue_t        *event_queue;
-	audio_sink_t        *sink;
+	switch_mutex_t        *audio_lock;
+	switch_buffer_t       *audio_buffer;
+	audio_sink_t          *sink;
 	apr_pool_t            *pool;
 	switch_speech_flag_t  flags;
 	switch_mutex_t        *flag_mutex;
 };
 
-long add_up_buffer(switch_byte_t *buffer, size_t len); // TEMP DEBUG
-
 static apr_status_t openmrcp_recognizer_read_frame(audio_source_t *source, media_frame_t *frame);
 static apr_status_t openmrcp_tts_write_frame(audio_sink_t *sink, media_frame_t *frame);
 
@@ -522,9 +545,6 @@
 
 	len = frame->codec_frame.size;
 
-	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "add_up frame: %li\n", 
-					  add_up_buffer(frame->codec_frame.buffer, len));
-
 	/* create new media frame */
 	media_frame = (media_frame_t *) switch_core_alloc(tts_session->pool, sizeof(media_frame_t));
 	if (!media_frame) {
@@ -547,10 +567,6 @@
 	media_frame->type = MEDIA_FRAME_TYPE_AUDIO;
 
 
-	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "add_up media_frame: %li\n", 
-					  add_up_buffer(media_frame->codec_frame.buffer, len));
-
-
 	/* push audio to queue */
 	if (switch_queue_trypush(tts_session->audio_queue, (void *) media_frame)) {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "could not push audio to queue\n");
@@ -561,15 +577,63 @@
 
 }
 
-long add_up_buffer(switch_byte_t *buffer, size_t len) {
-	// add up contents in buffer
-	long result = 0;
-	for (int i=0; i<len; i++) {
-		result =+ buffer[i];
+
+/**
+ * Called back by openmrcp client thread every time it receives audio 
+ * from the TTS server we are connected to.  Puts audio in a queueu
+ * and it will be pulled out from read_tts
+ */
+static apr_status_t openmrcp_tts_write_frame_NEW(audio_sink_t *sink, media_frame_t *frame)
+{
+	tts_session_t *tts_session = sink->object;	
+	media_frame_t *media_frame;
+	switch_byte_t *buffer;
+	size_t len;
+	apr_status_t status = 
+
+	len = frame->codec_frame.size;
+
+	/* create new media frame */
+	media_frame = (media_frame_t *) switch_core_alloc(tts_session->pool, sizeof(media_frame_t));
+	if (!media_frame) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "media_frame creation failed\n");
+		return SWITCH_STATUS_MEMERR;
 	}
-	return result;
+	
+	/**
+	 * since *frame might get freed by caller (true or false?), allocate a
+	 * new buffer and copy *data into it.
+	 **/
+	buffer = (switch_byte_t *) switch_core_alloc(tts_session->pool, sizeof(switch_byte_t)*len);
+	if (!buffer) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not allocate buffer\n");
+		return SWITCH_STATUS_MEMERR;
+	}
+	buffer = memcpy(buffer, frame->codec_frame.buffer, len);
+	media_frame->codec_frame.buffer = buffer;
+	media_frame->codec_frame.size = len;  
+	media_frame->type = MEDIA_FRAME_TYPE_AUDIO;
+
+
+	/* add audio to buffer */
+	switch_mutex_lock(tts_session->audio_lock);
+	if (switch_buffer_write(tts_session->audio_buffer, buffer, len) == 0) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Could not write to buffer\n");
+	}
+	switch_mutex_unlock(tts_session->audio_lock);
+
+	switch_mutex_unlock(tts_session->audio_lock);
+
+	if (switch_queue_trypush(tts_session->audio_queue, (void *) media_frame)) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "could not push audio to queue\n");
+		return MRCP_STATUS_FAILURE;
+	}
+
+	return MRCP_STATUS_SUCCESS;
+
 }
 
+
 /** 
  * Called back by openmcp client thread every time its ready for more audio to send
  * the recognition server we are connected to.  Reads data that was put into a 
@@ -1047,6 +1111,15 @@
 		return SWITCH_STATUS_MEMERR;
 	}
 
+	/* create mutex that will be used to lock audio buffer */
+	switch_mutex_init(&tts_session->audio_lock, SWITCH_MUTEX_NESTED, sh->memory_pool);
+
+	/* create audio buffer */
+	if (switch_buffer_create_dynamic(&tts_session->audio_buffer, MY_BLOCK_SIZE, MY_BUF_LEN, 0) != SWITCH_STATUS_SUCCESS) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Write Buffer Creation Failed!\n");
+		return SWITCH_STATUS_MEMERR;
+	}
+
 	
 	tts_session->flags = *flags;
 	switch_mutex_init(&tts_session->flag_mutex, SWITCH_MUTEX_NESTED, tts_session->pool);
@@ -1093,11 +1166,10 @@
 	/* wait for synthesizer channel creation */
 	if(wait_for_event(tts_session->event_queue,OPENMRCP_EVENT_CHANNEL_CREATE,5000) == MRCP_STATUS_SUCCESS) {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Got channel create event\n");
-		wait_for_event(tts_session->event_queue,OPENMRCP_EVENT_NONE,1000);
+		wait_for_event(tts_session->event_queue,OPENMRCP_EVENT_NONE,1000);  // XXX: what are we waiting for??
 		/* speak */
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Going to speak\n");
 		synth_speak(tts_client_context,tts_session, text); 
-		// wait_for_event(tts_session->event_queue,OPENMRCP_EVENT_CHANNEL_MODIFY,5000);
 
 	}
 	else {
@@ -1105,20 +1177,14 @@
 		return SWITCH_STATUS_FALSE;	
 	}
 
-
-
 	return SWITCH_STATUS_SUCCESS;	
 }
 
-static void openmrcp_flush_tts(switch_speech_handle_t *sh)
-{
-	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "flush_tts called\n");
-}
-
 /**
  * Freeswitch calls this when its ready to read datalen bytes of data.
  * 
- * TODO: check the blocking flag and act accordingly 
+ * TODO: check the blocking flag passed in flags and act accordingly  
+ *       (see mod_cepstral.c)
  */
 static switch_status_t openmrcp_read_tts(switch_speech_handle_t *sh, void *data, size_t *datalen, uint32_t *rate, switch_speech_flag_t *flags)
 {
@@ -1132,7 +1198,6 @@
 		return SWITCH_STATUS_SUCCESS;	
 	}
 	else {
-
 		memcpy(data, queue_frame->codec_frame.buffer, queue_frame->codec_frame.size);
 		*datalen = queue_frame->codec_frame.size;
 		*rate = 8000;
@@ -1141,6 +1206,12 @@
 
 }
 
+
+static void openmrcp_flush_tts(switch_speech_handle_t *sh)
+{
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "flush_tts called\n");
+}
+
 static void openmrcp_text_param_tts(switch_speech_handle_t *sh, char *param, char *val)
 {
 



More information about the Freeswitch-svn mailing list