[Freeswitch-svn] [commit] r10664 - in freeswitch/trunk/src: . include

FreeSWITCH SVN anthm at freeswitch.org
Mon Dec 8 16:32:52 PST 2008


Author: anthm
Date: Mon Dec  8 19:32:51 2008
New Revision: 10664

Log:
a whole bunch of stuff just to avoid a sonus issue silence_when_idle=400 chanvar to send generated silence duing sleeps etc

Modified:
   freeswitch/trunk/src/include/switch_types.h
   freeswitch/trunk/src/switch_ivr.c
   freeswitch/trunk/src/switch_ivr_originate.c
   freeswitch/trunk/src/switch_resample.c
   freeswitch/trunk/src/switch_rtp.c

Modified: freeswitch/trunk/src/include/switch_types.h
==============================================================================
--- freeswitch/trunk/src/include/switch_types.h	(original)
+++ freeswitch/trunk/src/include/switch_types.h	Mon Dec  8 19:32:51 2008
@@ -110,6 +110,7 @@
 #define SWITCH_PATH_SEPARATOR "/"
 #endif
 #define SWITCH_URL_SEPARATOR "://"
+#define SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE "send_silence_when_idle"
 #define SWITCH_CURRENT_APPLICATION_VARIABLE "current_application"
 #define SWITCH_CURRENT_APPLICATION_DATA_VARIABLE "current_application_data"
 #define SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE "current_application_response"

Modified: freeswitch/trunk/src/switch_ivr.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr.c	(original)
+++ freeswitch/trunk/src/switch_ivr.c	Mon Dec  8 19:32:51 2008
@@ -47,6 +47,41 @@
 	int32_t left, elapsed;
 	char data[2] = "";
 
+	switch_frame_t write_frame = { 0 };
+	unsigned char *abuf = NULL;
+	switch_codec_implementation_t imp = {0};
+	switch_codec_t codec = { 0 };
+	int sval = 0;
+	const char *var;
+	
+	if ((var = switch_channel_get_variable(channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE)) && (sval = atoi(var))) {
+		switch_core_session_get_read_impl(session, &imp);
+	
+		if (switch_core_codec_init(&codec,
+								   "L16",
+								   NULL,
+								   imp.samples_per_second,
+								   imp.microseconds_per_packet / 1000,
+								   imp.number_of_channels, 
+								   SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, 
+								   switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec Error L16@%uhz %u channels %dms\n", 
+							  imp.samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000);
+			return SWITCH_STATUS_FALSE;
+		}
+
+
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Codec Activated L16@%uhz %u channels %dms\n", 
+						  imp.samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000);
+		
+		write_frame.codec = &codec;
+		switch_zmalloc(abuf, SWITCH_RECOMMENDED_BUFFER_SIZE);
+		write_frame.data = abuf;
+		write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
+		write_frame.datalen = imp.decoded_bytes_per_packet;
+		write_frame.samples = write_frame.datalen / sizeof(int16_t);
+	}
+
 	cng_frame.data = data;
 	cng_frame.datalen = 2;
 	cng_frame.buflen = 2;
@@ -134,10 +169,20 @@
 			}
 		}
 
-		switch_core_session_write_frame(session, &cng_frame, SWITCH_IO_FLAG_NONE, 0);
+		if (sval) {
+			switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.samples, sval);
+			switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
+		} else {
+			switch_core_session_write_frame(session, &cng_frame, SWITCH_IO_FLAG_NONE, 0);
+		}
+	}
 
+	if (write_frame.codec) {
+		switch_core_codec_destroy(&codec);
 	}
 
+	switch_safe_free(abuf);
+
 	return status;
 }
 
@@ -749,9 +794,44 @@
 	switch_time_t started = 0, digit_started = 0;
 	uint32_t abs_elapsed = 0, digit_elapsed = 0;
 	uint32_t eff_timeout = 0;
+	switch_frame_t write_frame = { 0 };
+	unsigned char *abuf = NULL;
+	switch_codec_implementation_t imp = {0};
+	switch_codec_t codec = { 0 };
+	int sval = 0;
+	const char *var;
+
+	if ((var = switch_channel_get_variable(channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE)) && (sval = atoi(var))) {
+		switch_core_session_get_read_impl(session, &imp);
+	
+		if (switch_core_codec_init(&codec,
+								   "L16",
+								   NULL,
+								   imp.samples_per_second,
+								   imp.microseconds_per_packet / 1000,
+								   imp.number_of_channels, 
+								   SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, 
+								   switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec Error L16@%uhz %u channels %dms\n", 
+							  imp.samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000);
+			return SWITCH_STATUS_FALSE;
+		}
+
+
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Codec Activated L16@%uhz %u channels %dms\n", 
+						  imp.samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000);
+		
+		write_frame.codec = &codec;
+		switch_zmalloc(abuf, SWITCH_RECOMMENDED_BUFFER_SIZE);
+		write_frame.data = abuf;
+		write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
+		write_frame.datalen = imp.decoded_bytes_per_packet;
+		write_frame.samples = write_frame.datalen / sizeof(int16_t);
+	}
 
-	if (terminator != NULL)
+	if (terminator != NULL) {
 		*terminator = '\0';
+	}
 
 	if (!switch_strlen_zero(terminators)) {
 		for (i = 0; i < x; i++) {
@@ -838,9 +918,21 @@
 			if (!SWITCH_READ_ACCEPTABLE(status)) {
 				break;
 			}
+
+			if (write_frame.data) {
+				switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.samples, sval);
+				switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
+			}
+			
 		}
 	}
 
+	if (write_frame.codec) {
+		switch_core_codec_destroy(&codec);
+	}
+
+	switch_safe_free(abuf);
+
 	return status;
 }
 

Modified: freeswitch/trunk/src/switch_ivr_originate.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr_originate.c	(original)
+++ freeswitch/trunk/src/switch_ivr_originate.c	Mon Dec  8 19:32:51 2008
@@ -279,6 +279,7 @@
 	teletone_generation_session_t ts;
 	switch_file_handle_t fhb;
 	switch_file_handle_t *fh;
+	int silence;
 	uint8_t asis;
 };
 
@@ -348,9 +349,16 @@
 			ringback_data = switch_channel_get_variable(caller_channel, "ringback");
 		}
 
-
 		if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE) || switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA)) {
 			ringback_data = NULL;
+		} else {
+			if ((var = switch_channel_get_variable(caller_channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE))) {
+				int sval = atoi(var);
+
+				if (sval) {
+					ringback_data = switch_core_session_sprintf(session, "ringback:%d", sval);
+				}
+			}
 		}
 	}
 
@@ -409,14 +417,27 @@
 						}
 						ringback.fh = &ringback.fhb;
 					} else {
-						teletone_init_session(&ringback.ts, 0, teletone_handler, &ringback);
-						ringback.ts.rate = read_codec->implementation->actual_samples_per_second;
-						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Play Ringback Tone [%s]\n", ringback_data);
-						if (teletone_run(&ringback.ts, ringback_data)) {
-							switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Playing Tone\n");
-							teletone_destroy_session(&ringback.ts);
-							switch_buffer_destroy(&ringback.audio_buffer);
-							ringback_data = NULL;
+						if (!strncasecmp(ringback_data, "silence", 7)) {
+							const char *p = ringback_data + 7;
+							if (*p == ':') {
+								p++;
+								if (p) {
+									ringback.silence = atoi(p);
+								}
+							}
+							if (ringback.silence <= 0) {
+								ringback.silence = 400;
+							}
+						} else {
+							teletone_init_session(&ringback.ts, 0, teletone_handler, &ringback);
+							ringback.ts.rate = read_codec->implementation->actual_samples_per_second;
+							switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Play Ringback Tone [%s]\n", ringback_data);
+							if (teletone_run(&ringback.ts, ringback_data)) {
+								switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Playing Tone\n");
+								teletone_destroy_session(&ringback.ts);
+								switch_buffer_destroy(&ringback.audio_buffer);
+								ringback_data = NULL;
+							}
 						}
 					}
 					switch_safe_free(tmp_data);
@@ -491,9 +512,12 @@
 																			  write_frame.codec->implementation->decoded_bytes_per_packet)) <= 0) {
 					break;
 				}
+			} else if (ringback.silence) {
+				write_frame.datalen = write_frame.codec->implementation->decoded_bytes_per_packet;
+				switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.datalen / 2, ringback.silence);
 			}
 
-			if ((ringback.fh || ringback.audio_buffer) && write_frame.codec && write_frame.datalen) {
+			if ((ringback.fh || ringback.silence || ringback.audio_buffer) && write_frame.codec && write_frame.datalen) {
 				if (switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
 					break;
 				}
@@ -769,6 +793,17 @@
 
 		if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE) || switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA)) {
 			ringback_data = NULL;
+		} else {
+			const char *vvar;
+			
+			if ((vvar = switch_channel_get_variable(caller_channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE))) {
+				int sval = atoi(vvar);
+
+				if (sval) {
+					ringback_data = switch_core_session_sprintf(session, "ringback:%d", sval);
+				}
+
+			}
 		}
 	}
 
@@ -1292,7 +1327,17 @@
 								}
 								ringback.fh = &ringback.fhb;
 
-
+							} else if (!strncasecmp(ringback_data, "silence", 7)) {
+								const char *p = ringback_data + 7;
+								if (*p == ':') {
+									p++;
+									if (p) {
+										ringback.silence = atoi(p);
+									}
+								}
+								if (ringback.silence <= 0) {
+									ringback.silence = 400;
+								}
 							} else {
 								teletone_init_session(&ringback.ts, 0, teletone_handler, &ringback);
 								ringback.ts.rate = read_codec->implementation->actual_samples_per_second;
@@ -1436,9 +1481,12 @@
 																						  write_frame.codec->implementation->decoded_bytes_per_packet)) <= 0) {
 								break;
 							}
+						} else if (ringback.silence) {
+							write_frame.datalen = write_frame.codec->implementation->decoded_bytes_per_packet;
+							switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.datalen / 2, ringback.silence);
 						}
 
-						if ((ringback.fh || ringback.audio_buffer) && write_frame.codec && write_frame.datalen) {
+						if ((ringback.fh || ringback.silence || ringback.audio_buffer) && write_frame.codec && write_frame.datalen) {
 							if (switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
 								break;
 							}

Modified: freeswitch/trunk/src/switch_resample.c
==============================================================================
--- freeswitch/trunk/src/switch_resample.c	(original)
+++ freeswitch/trunk/src/switch_resample.c	Mon Dec  8 19:32:51 2008
@@ -203,18 +203,19 @@
 
 SWITCH_DECLARE(void) switch_generate_sln_silence(int16_t *data, uint32_t samples, uint32_t divisor)
 {
-	int16_t rnd = 0, rnd2, x;
+	int16_t x;
 	uint32_t i;
 	int sum_rnd = 0;
+	int16_t rnd2 = (int16_t) switch_timestamp_now();
 
 	assert(divisor);
 
-	rnd2 = (int16_t) (intptr_t) &data + (int16_t)switch_timestamp(NULL);
+
 
 	for (i = 0; i < samples; i++, sum_rnd = 0) {
-		for (x = 0; x < 10; x++) {
-			rnd += (int16_t)((x + i) * rnd2);
-			sum_rnd += rnd;
+		for (x = 0; x < 6; x++) {
+			rnd2 = rnd2 * 31821U + 13849U;
+			sum_rnd += rnd2;
 		}
 		switch_normalize_to_16bit(sum_rnd);
 		*data = (int16_t) ((int16_t) sum_rnd / (int) divisor);

Modified: freeswitch/trunk/src/switch_rtp.c
==============================================================================
--- freeswitch/trunk/src/switch_rtp.c	(original)
+++ freeswitch/trunk/src/switch_rtp.c	Mon Dec  8 19:32:51 2008
@@ -158,6 +158,7 @@
 	uint32_t last_write_ts;
 	uint32_t last_write_samplecount;
 	uint32_t next_write_samplecount;
+	switch_time_t last_write_timestamp;
 	uint32_t flags;
 	switch_memory_pool_t *pool;
 	switch_sockaddr_t *from_addr;
@@ -1885,15 +1886,27 @@
 
 		rtp_session->send_msg.header.ts = htonl(rtp_session->ts);
 
+
 		if ((rtp_session->ts > (rtp_session->last_write_ts + (rtp_session->samples_per_interval * 10)))
 			|| rtp_session->ts == rtp_session->samples_per_interval) {
 			m++;
 		}
 
+		if (rtp_session->timer.interval && 
+			(rtp_session->timer.samplecount - rtp_session->last_write_samplecount) > rtp_session->samples_per_interval * 2) {
+			m++;
+		}
+
+		if (!rtp_session->timer.interval && 
+			((unsigned)((switch_timestamp_now() - rtp_session->last_write_timestamp))) > (rtp_session->ms_per_packet *2)) {
+			m++;
+		}
+
 		if (rtp_session->cn && payload != rtp_session->cng_pt) {
 			rtp_session->cn = 0;
 			m++;
 		}
+		
 		send_msg->header.m = m ? 1 : 0;
 
 		memcpy(send_msg->body, data, datalen);
@@ -2049,7 +2062,10 @@
 
 		if (rtp_session->timer.interval) {
 			rtp_session->last_write_samplecount = rtp_session->timer.samplecount;
+		} else {
+			rtp_session->last_write_timestamp = (uint32_t) switch_timestamp_now();
 		}
+
 		rtp_session->last_write_ts = this_ts;
 	}
 



More information about the Freeswitch-svn mailing list