[Asterisk-cvs] asterisk app.c, 1.80, 1.81 asterisk.c, 1.187, 1.188 channel.c, 1.254, 1.255

kpfleming kpfleming
Tue Nov 1 12:30:26 CST 2005


Update of /usr/cvsroot/asterisk
In directory mongoose.digium.com:/tmp/cvs-serv12746

Modified Files:
	app.c asterisk.c channel.c 
Log Message:
optionally send silence during recording (issue #5135)


Index: app.c
===================================================================
RCS file: /usr/cvsroot/asterisk/app.c,v
retrieving revision 1.80
retrieving revision 1.81
diff -u -d -r1.80 -r1.81
--- app.c	30 Oct 2005 06:58:17 -0000	1.80
+++ app.c	1 Nov 2005 17:22:25 -0000	1.81
@@ -560,6 +560,7 @@
 	int dspsilence = 0;
 	int gotsilence = 0;		/* did we timeout for silence? */
 	int rfmt=0;
+	struct ast_silence_generator *silgen = NULL;
 
 	if (silencethreshold < 0)
 		silencethreshold = global_silence_threshold;
@@ -615,8 +616,6 @@
 	if (path)
 		ast_unlock_path(path);
 
-
-	
 	if (maxsilence > 0) {
 		sildet = ast_dsp_new(); /* Create the silence detector */
 		if (!sildet) {
@@ -632,9 +631,13 @@
 			return -1;
 		}
 	}
+
 	/* Request a video update */
 	ast_indicate(chan, AST_CONTROL_VIDUPDATE);
 
+	if (option_transmit_silence_during_record)
+		silgen = ast_channel_start_silence_generator(chan);
+
 	if (x == fmtcnt) {
 	/* Loop forever, writing the packets we read to the writer(s), until
 	   we read a # or get a hangup */
@@ -735,6 +738,9 @@
 		ast_log(LOG_WARNING, "Error creating writestream '%s', format '%s'\n", recordfile, sfmt[x]);
 	}
 
+	if (silgen)
+		ast_channel_stop_silence_generator(chan, silgen);
+
 	*duration = end - start;
 
 	for (x=0;x<fmtcnt;x++) {

Index: asterisk.c
===================================================================
RCS file: /usr/cvsroot/asterisk/asterisk.c,v
retrieving revision 1.187
retrieving revision 1.188
diff -u -d -r1.187 -r1.188
--- asterisk.c	31 Oct 2005 21:25:21 -0000	1.187
+++ asterisk.c	1 Nov 2005 17:22:25 -0000	1.188
@@ -142,6 +142,7 @@
 int option_overrideconfig = 0;
 int option_reconnect = 0;
 int option_transcode_slin = 1;
+int option_transmit_silence_during_record = 0;
 int option_maxcalls = 0;
 double option_maxload = 0.0;
 int option_dontwarn = 0;
@@ -1869,6 +1870,9 @@
 		/* Build transcode paths via SLINEAR, instead of directly */
 		} else if (!strcasecmp(v->name, "transcode_via_sln")) {
 			option_transcode_slin = ast_true(v->value);
+		/* Transmit SLINEAR silence while a channel is being recorded */
+		} else if (!strcasecmp(v->name, "transmit_silence_during_record")) {
+			option_transmit_silence_during_record = ast_true(v->value);
 		} else if (!strcasecmp(v->name, "maxcalls")) {
 			if ((sscanf(v->value, "%d", &option_maxcalls) != 1) || (option_maxcalls < 0)) {
 				option_maxcalls = 0;

Index: channel.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channel.c,v
retrieving revision 1.254
retrieving revision 1.255
diff -u -d -r1.254 -r1.255
--- channel.c	31 Oct 2005 15:34:11 -0000	1.254
+++ channel.c	1 Nov 2005 17:22:25 -0000	1.255
@@ -3921,3 +3921,100 @@
 
 	return result;
 }
+
+static void *silence_generator_alloc(struct ast_channel *chan, void *data)
+{
+	/* just store the data pointer in the channel structure */
+	return data;
+}
+
+static void silence_generator_release(struct ast_channel *chan, void *data)
+{
+	/* nothing to do */
+}
+
+static short normal_silence_buf[160] = { 0, };
+static struct ast_frame normal_silence_frame = {
+	.frametype = AST_FRAME_VOICE,
+	.subclass = AST_FORMAT_SLINEAR,
+	.data = normal_silence_buf,
+	.samples = 160,
+	.datalen = sizeof(normal_silence_buf),
+};
+
+static int silence_generator_generate(struct ast_channel *chan, void *data, int len, int samples) 
+{
+	if (samples == 160) {
+		if (ast_write(chan, &normal_silence_frame))
+			return -1;
+	} else {
+		short buf[samples];
+		int x;
+		struct ast_frame frame = {
+			.frametype = AST_FRAME_VOICE,
+			.subclass = AST_FORMAT_SLINEAR,
+			.data = normal_silence_buf,
+			.samples = samples,
+			.datalen = sizeof(buf),
+		};
+
+		for (x = 0; x < samples; x++)
+			buf[x] = 0;
+
+		if (ast_write(chan, &frame))
+			return -1;
+	}
+
+	return 0;
+}
+
+static struct ast_generator silence_generator = {
+	.alloc = silence_generator_alloc,
+	.release = silence_generator_release,
+	.generate = silence_generator_generate, 
+};
+
+struct ast_silence_generator {
+	int old_write_format;
+};
+
+struct ast_silence_generator *ast_channel_start_silence_generator(struct ast_channel *chan)
+{
+	struct ast_silence_generator *state;
+
+	if (!(state = calloc(1, sizeof(*state)))) {
+		ast_log(LOG_WARNING, "Could not allocate state structure\n");
+		return NULL;
+	}
+
+	state->old_write_format = chan->writeformat;
+
+	if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
+		ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n");
+		free(state);
+		return NULL;
+	}
+
+	ast_activate_generator(chan, &silence_generator, state);
+
+	if (option_debug)
+		ast_log(LOG_DEBUG, "Started silence generator on '%s'\n", chan->name);
+
+	return state;
+}
+
+void ast_channel_stop_silence_generator(struct ast_channel *chan, struct ast_silence_generator *state)
+{
+	if (!state)
+		return;
+
+	ast_deactivate_generator(chan);
+
+	if (option_debug)
+		ast_log(LOG_DEBUG, "Stopped silence generator on '%s'\n", chan->name);
+
+	if (ast_set_write_format(chan, state->old_write_format) < 0)
+		ast_log(LOG_ERROR, "Could not return write format to its original state\n");
+
+	free(state);
+}




More information about the svn-commits mailing list