[Freeswitch-svn] [commit] r5366 - in freeswitch/trunk/src: . include mod/applications/mod_commands mod/applications/mod_dptools mod/applications/mod_soundtouch

Freeswitch SVN anthm at freeswitch.org
Thu Jun 14 21:47:48 EDT 2007


Author: anthm
Date: Thu Jun 14 21:47:48 2007
New Revision: 5366

Modified:
   freeswitch/trunk/src/include/switch_ivr.h
   freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c
   freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c
   freeswitch/trunk/src/mod/applications/mod_soundtouch/mod_soundtouch.cpp
   freeswitch/trunk/src/switch_core_codec.c
   freeswitch/trunk/src/switch_core_io.c
   freeswitch/trunk/src/switch_ivr_async.c

Log:
add session_displace api and app

Modified: freeswitch/trunk/src/include/switch_ivr.h
==============================================================================
--- freeswitch/trunk/src/include/switch_ivr.h	(original)
+++ freeswitch/trunk/src/include/switch_ivr.h	Thu Jun 14 21:47:48 2007
@@ -200,6 +200,9 @@
 */
 SWITCH_DECLARE(switch_status_t) switch_ivr_record_session(switch_core_session_t *session, char *file, uint32_t limit, switch_file_handle_t *fh);
 
+SWITCH_DECLARE(switch_status_t) switch_ivr_displace_session(switch_core_session_t *session, char *file, uint32_t limit, const char *flags);
+SWITCH_DECLARE(switch_status_t) switch_ivr_stop_displace_session(switch_core_session_t *session, char *file);
+
 /*!
   \brief Stop Recording a session
   \param session the session to stop recording

Modified: freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c	(original)
+++ freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c	Thu Jun 14 21:47:48 2007
@@ -565,7 +565,7 @@
 		goto usage;
 	}
 
-	if ((argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) != 3) {
+	if ((argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) < 3) {
 		goto usage;
 	}
 
@@ -609,6 +609,73 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
+
+SWITCH_STANDARD_API(session_displace_function)
+{
+	switch_core_session_t *rsession = NULL;
+	char *mycmd = NULL, *argv[5] = { 0 };
+	char *uuid = NULL, *action = NULL, *path = NULL;
+	int argc = 0;
+	uint32_t limit = 0;
+	char *flags = NULL;
+
+	if (session) {
+		return SWITCH_STATUS_FALSE;
+	}
+
+	if (switch_strlen_zero(cmd)) {
+		goto usage;
+	}
+
+	if (!(mycmd = strdup(cmd))) {
+		goto usage;
+	}
+
+	if ((argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) < 3) {
+		goto usage;
+	}
+
+	uuid = argv[0];
+	action = argv[1];
+	path = argv[2];
+	limit = argv[3] ? atoi(argv[3]) : 0;
+	flags = argv[4];
+
+	if (!(rsession = switch_core_session_locate(uuid))) {
+		stream->write_function(stream, "-Error Cannot locate session!\n");
+		return SWITCH_STATUS_SUCCESS;
+	}
+	
+	if (switch_strlen_zero(action) || switch_strlen_zero(path)) {
+		goto usage;
+	}
+
+	if (!strcasecmp(action, "start")) {
+		switch_ivr_displace_session(rsession, path, limit, flags);
+	} else if (!strcasecmp(action, "stop")) {
+		switch_ivr_stop_displace_session(rsession, path);
+	} else {
+		goto usage;
+	}
+
+	goto done;
+
+  usage:
+
+	stream->write_function(stream, "INVALID SYNTAX\n");
+	switch_safe_free(mycmd);
+
+
+  done:
+
+	if (rsession) {
+		switch_core_session_rwunlock(rsession);
+	}
+
+	switch_safe_free(mycmd);
+	return SWITCH_STATUS_SUCCESS;
+}
+
 SWITCH_STANDARD_API(pause_function)
 {
 	switch_core_session_t *psession = NULL;
@@ -1237,12 +1304,20 @@
 	/*.next */ &broadcast_api_interface
 };
 
+static switch_api_interface_t session_displace_api_interface = {
+	/*.interface_name */ "session_displace",
+	/*.desc */ "session displace",
+	/*.function */ session_displace_function,
+	/*.syntax */ "<uuid> [start|stop] <path> [<limit>] [mux]",
+	/*.next */ &broadcast_api_interface
+};
+
 static switch_api_interface_t uuid_bridge_api_interface = {
 	/*.interface_name */ "uuid_bridge",
 	/*.desc */ "uuid_bridge",
 	/*.function */ uuid_bridge_function,
 	/*.syntax */ "<uuid> <other_uuid>",
-	/*.next */ &session_record_api_interface
+	/*.next */ &session_displace_api_interface
 };
 
 static switch_api_interface_t status_api_interface = {

Modified: freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c	(original)
+++ freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c	Thu Jun 14 21:47:48 2007
@@ -789,6 +789,43 @@
 
 }
 
+static void displace_session_function(switch_core_session_t *session, char *data)
+{
+	switch_channel_t *channel;
+	char *path = NULL;
+	uint32_t limit = 0;
+    char *argv[6];
+	int x, argc;
+	char *lbuf = NULL;
+	char *flags = NULL;
+
+	channel = switch_core_session_get_channel(session);
+	assert(channel != NULL);
+
+	if (data && (lbuf = switch_core_session_strdup(session, data))
+		&& (argc = switch_separate_string(lbuf, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
+		path = argv[0];
+		for(x = 0; x < argc; x++) {
+			if (strchr(argv[x], '+')) {
+				limit = atoi(argv[x]);
+			} else if (!switch_strlen_zero(argv[x])) {
+				flags = argv[x];
+			}
+		}
+		switch_ivr_displace_session(session, path, limit, flags);
+	}
+}
+
+
+static void stop_displace_session_function(switch_core_session_t *session, char *data)
+{
+	switch_channel_t *channel;
+	channel = switch_core_session_get_channel(session);
+	assert(channel != NULL);
+
+	switch_ivr_stop_displace_session(session, data);
+}
+
 
 static void record_function(switch_core_session_t *session, char *data)
 {
@@ -995,6 +1032,26 @@
 	&bridge_application_interface
 };
 
+static switch_application_interface_t displace_application_interface = {
+	/*.interface_name */ "displace",
+	/*.application_function */ displace_session_function,
+	/* long_desc */ "Displace audio from a file to the channels input",
+	/* short_desc */ "Displace File",
+	/* syntax */ "<path> [+time_limit_ms] [mux]",
+	/* flags */ SAF_NONE,
+	&speak_application_interface
+};
+
+static switch_application_interface_t stop_displace_application_interface = {
+	/*.interface_name */ "displace",
+	/*.application_function */ stop_displace_session_function,
+	/* long_desc */ "Stop Displacing to a file",
+	/* short_desc */ "Stop Displace File",
+	/* syntax */ "<path>",
+	/* flags */ SAF_NONE,
+	&displace_application_interface
+};
+
 static switch_application_interface_t record_application_interface = {
 	/*.interface_name */ "record",
 	/*.application_function */ record_function,
@@ -1002,7 +1059,7 @@
 	/* short_desc */ "Record File",
 	/* syntax */ "<path> [+time_limit_ms]",
 	/* flags */ SAF_NONE,
-	&speak_application_interface
+	&stop_displace_application_interface
 };
 
 

Modified: freeswitch/trunk/src/mod/applications/mod_soundtouch/mod_soundtouch.cpp
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_soundtouch/mod_soundtouch.cpp	(original)
+++ freeswitch/trunk/src/mod/applications/mod_soundtouch/mod_soundtouch.cpp	Thu Jun 14 21:47:48 2007
@@ -257,8 +257,13 @@
 	char *lbuf = NULL;
     int x;
  
-    if (switch_channel_get_private(channel, "_soundtouch_")) {
-        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot run 2 at once on the same channel!\n");
+    if ((bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_soundtouch_"))) {
+        if (!switch_strlen_zero(data) && !strcasecmp(data, "stop")) {
+            switch_channel_set_private(channel, "_soundtouch_", NULL);
+            switch_core_media_bug_remove(session, &bug);
+        } else {
+            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot run 2 at once on the same channel!\n");
+        }
         return;
     }
 

Modified: freeswitch/trunk/src/switch_core_codec.c
==============================================================================
--- freeswitch/trunk/src/switch_core_codec.c	(original)
+++ freeswitch/trunk/src/switch_core_codec.c	Thu Jun 14 21:47:48 2007
@@ -50,6 +50,8 @@
 	session->read_codec = codec;
 	session->raw_read_frame.codec = session->read_codec;
 	session->raw_write_frame.codec = session->read_codec;
+	session->enc_read_frame.codec = session->read_codec;
+	session->enc_write_frame.codec = session->read_codec;
 
 	return SWITCH_STATUS_SUCCESS;
 }

Modified: freeswitch/trunk/src/switch_core_io.c
==============================================================================
--- freeswitch/trunk/src/switch_core_io.c	(original)
+++ freeswitch/trunk/src/switch_core_io.c	Thu Jun 14 21:47:48 2007
@@ -241,7 +241,7 @@
 					do_bugs = 0;
 					if (bp->callback) {
 						bp->read_replace_frame_in = read_frame;
-						bp->read_replace_frame_out = NULL;
+						bp->read_replace_frame_out = read_frame;
 						if ((ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ_REPLACE)) == SWITCH_TRUE) {
 							read_frame = bp->read_replace_frame_out;
 						}
@@ -509,7 +509,7 @@
 					do_bugs = 0;
 					if (bp->callback) {
 						bp->write_replace_frame_in = write_frame;
-						bp->write_replace_frame_out = NULL;
+						bp->write_replace_frame_out = write_frame;
 						if ((ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_WRITE_REPLACE)) == SWITCH_TRUE) {
 							write_frame = bp->write_replace_frame_out;
 						}

Modified: freeswitch/trunk/src/switch_ivr_async.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr_async.c	(original)
+++ freeswitch/trunk/src/switch_ivr_async.c	Thu Jun 14 21:47:48 2007
@@ -96,6 +96,151 @@
 }
 
 
+typedef struct {
+	switch_file_handle_t fh;
+	int mux;
+} displace_helper_t;
+
+static switch_bool_t displace_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
+{
+	displace_helper_t *dh = (displace_helper_t *) user_data;
+	uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE];
+	switch_frame_t frame = { 0 };
+
+	frame.data = data;
+	frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
+
+	switch (type) {
+	case SWITCH_ABC_TYPE_INIT:
+		break;
+	case SWITCH_ABC_TYPE_CLOSE:
+		if (dh) {
+			switch_core_file_close(&dh->fh);
+		}
+		break;
+	case SWITCH_ABC_TYPE_READ_REPLACE:
+		{
+			switch_frame_t *frame = switch_core_media_bug_get_read_replace_frame(bug);
+			if (dh && !dh->mux) {
+				memset(frame->data, 255, frame->datalen);
+			}
+			switch_core_media_bug_set_read_replace_frame(bug, frame);
+		}
+		break;
+	case SWITCH_ABC_TYPE_WRITE_REPLACE:
+		if (dh) {
+			switch_frame_t *frame = NULL;
+			switch_size_t len;
+
+			frame = switch_core_media_bug_get_write_replace_frame(bug);
+			len = frame->samples;
+
+			if (dh->mux) {
+				int16_t buf[1024];
+				int16_t *fp = frame->data;
+				int x;
+				
+				switch_core_file_read(&dh->fh, buf, &len);
+				
+				for(x = 0; x < len; x++) {
+					int32_t mixed = fp[x] + buf[x];
+					switch_normalize_to_16bit(mixed);
+					fp[x] = (int16_t) mixed;
+				}
+			} else {
+				switch_core_file_read(&dh->fh, frame->data, &len);
+				frame->samples = len;
+				frame->datalen = frame->samples * 2;
+			}
+			switch_core_media_bug_set_write_replace_frame(bug, frame);
+		}
+		break;
+	case SWITCH_ABC_TYPE_WRITE:
+	default:
+		break;
+	}
+
+	return SWITCH_TRUE;
+}
+
+SWITCH_DECLARE(switch_status_t) switch_ivr_stop_displace_session(switch_core_session_t *session, char *file)
+{
+	switch_media_bug_t *bug;
+	switch_channel_t *channel = switch_core_session_get_channel(session);
+
+	assert(channel != NULL);
+	if ((bug = switch_channel_get_private(channel, file))) {
+		switch_channel_set_private(channel, file, NULL);
+		switch_core_media_bug_remove(session, &bug);
+		return SWITCH_STATUS_SUCCESS;
+	}
+
+	return SWITCH_STATUS_FALSE;
+
+}
+
+SWITCH_DECLARE(switch_status_t) switch_ivr_displace_session(switch_core_session_t *session, char *file, uint32_t limit, const char *flags)
+{
+	switch_channel_t *channel;
+	switch_codec_t *read_codec;
+	switch_media_bug_t *bug;
+	switch_status_t status;
+	time_t to = 0;
+	displace_helper_t *dh;
+
+
+	channel = switch_core_session_get_channel(session);
+	assert(channel != NULL);
+
+	if ((bug = switch_channel_get_private(channel, file))) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Only 1 of the same file per channel please!\n");
+		return SWITCH_STATUS_FALSE;
+	}
+
+	if (!(dh = switch_core_session_alloc(session, sizeof(*dh)))) {
+		return SWITCH_STATUS_MEMERR;
+	}
+
+
+
+	read_codec = switch_core_session_get_read_codec(session);
+	assert(read_codec != NULL);
+
+	dh->fh.channels = read_codec->implementation->number_of_channels;
+	dh->fh.samplerate = read_codec->implementation->samples_per_second;
+
+
+	if (switch_core_file_open(&dh->fh,
+							  file,
+							  read_codec->implementation->number_of_channels,
+							  read_codec->implementation->samples_per_second,
+							  SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT,
+							  switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
+		switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+		switch_core_session_reset(session);
+		return SWITCH_STATUS_GENERR;
+	}
+
+	switch_channel_answer(channel);
+
+	if (limit) {
+		to = time(NULL) + limit;
+	}
+
+	if (flags && strchr(flags, 'm')) {
+		dh->mux++;
+	}
+
+	if ((status = switch_core_media_bug_add(session, displace_callback, dh, to, SMBF_WRITE_REPLACE | SMBF_READ_REPLACE, &bug)) != SWITCH_STATUS_SUCCESS) {
+		switch_core_file_close(&dh->fh);
+		return status;
+	}
+
+	switch_channel_set_private(channel, file, bug);
+
+	return SWITCH_STATUS_SUCCESS;
+}
+
 
 static switch_bool_t record_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
 {
@@ -158,14 +303,20 @@
 	switch_status_t status;
 	time_t to = 0;
 
+	channel = switch_core_session_get_channel(session);
+	assert(channel != NULL);
+
+	if ((bug = switch_channel_get_private(channel, file))) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Only 1 of the same file per channel please!\n");
+		return SWITCH_STATUS_FALSE;
+	}
+
 	if (!fh) {
 		if (!(fh = switch_core_session_alloc(session, sizeof(*fh)))) {
 			return SWITCH_STATUS_MEMERR;
 		}
 	}
 
-	channel = switch_core_session_get_channel(session);
-	assert(channel != NULL);
 
 	read_codec = switch_core_session_get_read_codec(session);
 	assert(read_codec != NULL);



More information about the Freeswitch-svn mailing list