diff --git a/app.c b/app.c
index b547a037b15a27acc8f10b4245107d060bb5a41b..0a72bec42706669c66e136aa94f704d1c37118ac 100755
--- a/app.c
+++ b/app.c
@@ -560,6 +560,7 @@ int ast_play_and_record(struct ast_channel *chan, const char *playfile, const ch
 	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 @@ int ast_play_and_record(struct ast_channel *chan, const char *playfile, const ch
 	if (path)
 		ast_unlock_path(path);
 
-
-	
 	if (maxsilence > 0) {
 		sildet = ast_dsp_new(); /* Create the silence detector */
 		if (!sildet) {
@@ -632,9 +631,13 @@ int ast_play_and_record(struct ast_channel *chan, const char *playfile, const ch
 			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 @@ int ast_play_and_record(struct ast_channel *chan, const char *playfile, const ch
 		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++) {
diff --git a/apps/app_record.c b/apps/app_record.c
index 38fadf00119210f5487429a8ed34ef8dfe47f4c6..c5fa93280ea1994269361940e59a622bc3af18c8 100755
--- a/apps/app_record.c
+++ b/apps/app_record.c
@@ -38,6 +38,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/translate.h"
 #include "asterisk/dsp.h"
 #include "asterisk/utils.h"
+#include "asterisk/options.h"
 
 static char *tdesc = "Trivial Record Application";
 
@@ -98,6 +99,8 @@ static int record_exec(struct ast_channel *chan, void *data)
 	int option_quiet = 0;
 	int rfmt = 0;
 	int flags;
+	int waitres;
+	struct ast_silence_generator *silgen = NULL;
 	
 	/* The next few lines of code parse out the filename and header from the input string */
 	if (ast_strlen_zero(data)) { /* no data implies no filename or anything is present */
@@ -199,123 +202,131 @@ static int record_exec(struct ast_channel *chan, void *data)
 		}
 	}
 	
-	if (!res) {
+	if (res) {
+		ast_log(LOG_WARNING, "Could not answer channel '%s'\n", chan->name);
+		goto out;
+	}
 	
-		if (!option_quiet) {
-			/* Some code to play a nice little beep to signify the start of the record operation */
-			res = ast_streamfile(chan, "beep", chan->language);
-			if (!res) {
-				res = ast_waitstream(chan, "");
-			} else {
-				ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", chan->name);
-			}
-			ast_stopstream(chan);
+	if (!option_quiet) {
+		/* Some code to play a nice little beep to signify the start of the record operation */
+		res = ast_streamfile(chan, "beep", chan->language);
+		if (!res) {
+			res = ast_waitstream(chan, "");
+		} else {
+			ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", chan->name);
 		}
+		ast_stopstream(chan);
+	}
 		
-		/* The end of beep code.  Now the recording starts */
+	/* The end of beep code.  Now the recording starts */
 		
-		if (silence > 0) {
-			rfmt = chan->readformat;
-			res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
-			if (res < 0) {
-				ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
-				LOCAL_USER_REMOVE(u);
-				return -1;
-			}
-			sildet = ast_dsp_new();
-			if (!sildet) {
-				ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
-				LOCAL_USER_REMOVE(u);
-				return -1;
-			}
-			ast_dsp_set_threshold(sildet, 256);
-		} 
+	if (silence > 0) {
+		rfmt = chan->readformat;
+		res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
+		if (res < 0) {
+			ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
+			LOCAL_USER_REMOVE(u);
+			return -1;
+		}
+		sildet = ast_dsp_new();
+		if (!sildet) {
+			ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
+			LOCAL_USER_REMOVE(u);
+			return -1;
+		}
+		ast_dsp_set_threshold(sildet, 256);
+	} 
 		
 		
-		flags = option_append ? O_CREAT|O_APPEND|O_WRONLY : O_CREAT|O_TRUNC|O_WRONLY;
-		s = ast_writefile( tmp, ext, NULL, flags , 0, 0644);
+	flags = option_append ? O_CREAT|O_APPEND|O_WRONLY : O_CREAT|O_TRUNC|O_WRONLY;
+	s = ast_writefile( tmp, ext, NULL, flags , 0, 0644);
 		
-		if (s) {
-			int waitres;
-
-			/* Request a video update */
-			ast_indicate(chan, AST_CONTROL_VIDUPDATE);
+	if (!s) {
+		ast_log(LOG_WARNING, "Could not create file %s\n", filename);
+		goto out;
+	}
 
-			if (maxduration <= 0)
-				maxduration = -1;
+	if (option_transmit_silence_during_record)
+		silgen = ast_channel_start_silence_generator(chan);
+	
+	/* Request a video update */
+	ast_indicate(chan, AST_CONTROL_VIDUPDATE);
+	
+	if (maxduration <= 0)
+		maxduration = -1;
+	
+	while ((waitres = ast_waitfor(chan, maxduration)) > -1) {
+		if (maxduration > 0) {
+			if (waitres == 0) {
+				gottimeout = 1;
+				break;
+			}
+			maxduration = waitres;
+		}
+		
+		f = ast_read(chan);
+		if (!f) {
+			res = -1;
+			break;
+		}
+		if (f->frametype == AST_FRAME_VOICE) {
+			res = ast_writestream(s, f);
 			
-			while ((waitres = ast_waitfor(chan, maxduration)) > -1) {
-				if (maxduration > 0) {
-					if (waitres == 0) {
-						gottimeout = 1;
-						break;
-					}
-					maxduration = waitres;
-  				}
-				
-				f = ast_read(chan);
-				if (!f) {
-					res = -1;
-					break;
-				}
-				if (f->frametype == AST_FRAME_VOICE) {
-					res = ast_writestream(s, f);
-					
-					if (res) {
-						ast_log(LOG_WARNING, "Problem writing frame\n");
-						break;
-					}
-					
-					if (silence > 0) {
-						dspsilence = 0;
-						ast_dsp_silence(sildet, f, &dspsilence);
-						if (dspsilence) {
-							totalsilence = dspsilence;
-						} else {
-							totalsilence = 0;
-						}
-						if (totalsilence > silence) {
-							/* Ended happily with silence */
-							ast_frfree(f);
-							gotsilence = 1;
-							break;
-						}
-					}
-				}
-				if (f->frametype == AST_FRAME_VIDEO) {
-					res = ast_writestream(s, f);
-					
-					if (res) {
-						ast_log(LOG_WARNING, "Problem writing frame\n");
-						break;
-					}
+			if (res) {
+				ast_log(LOG_WARNING, "Problem writing frame\n");
+				break;
+			}
+			
+			if (silence > 0) {
+				dspsilence = 0;
+				ast_dsp_silence(sildet, f, &dspsilence);
+				if (dspsilence) {
+					totalsilence = dspsilence;
+				} else {
+					totalsilence = 0;
 				}
-				if ((f->frametype == AST_FRAME_DTMF) &&
-					(f->subclass == terminator)) {
+				if (totalsilence > silence) {
+					/* Ended happily with silence */
 					ast_frfree(f);
+					gotsilence = 1;
 					break;
 				}
-				ast_frfree(f);
-			}
-			if (!f) {
-				ast_log(LOG_DEBUG, "Got hangup\n");
-				res = -1;
 			}
+		}
+		if (f->frametype == AST_FRAME_VIDEO) {
+			res = ast_writestream(s, f);
 			
-			if (gotsilence) {
-				ast_stream_rewind(s, silence-1000);
-				ast_truncstream(s);
-			} else if (!gottimeout) {
-				/* Strip off the last 1/4 second of it */
-				ast_stream_rewind(s, 250);
-				ast_truncstream(s);
+			if (res) {
+				ast_log(LOG_WARNING, "Problem writing frame\n");
+				break;
 			}
-			ast_closestream(s);
-		} else			
-			ast_log(LOG_WARNING, "Could not create file %s\n", filename);
-	} else
-		ast_log(LOG_WARNING, "Could not answer channel '%s'\n", chan->name);
+		}
+		if ((f->frametype == AST_FRAME_DTMF) &&
+		    (f->subclass == terminator)) {
+			ast_frfree(f);
+			break;
+		}
+		ast_frfree(f);
+	}
+	if (!f) {
+		ast_log(LOG_DEBUG, "Got hangup\n");
+		res = -1;
+	}
+			
+	if (gotsilence) {
+		ast_stream_rewind(s, silence-1000);
+		ast_truncstream(s);
+	} else if (!gottimeout) {
+		/* Strip off the last 1/4 second of it */
+		ast_stream_rewind(s, 250);
+		ast_truncstream(s);
+	}
+	ast_closestream(s);
+
+	if (silgen)
+		ast_channel_stop_silence_generator(chan, silgen);
 	
+ out:
 	if ((silence > 0) && rfmt) {
 		res = ast_set_read_format(chan, rfmt);
 		if (res)
diff --git a/asterisk.c b/asterisk.c
index 43cc189fef1e95345ca974baad5367b2addae0ba..4d796c4c11780a14c2ff88246cc3520a178c5950 100755
--- a/asterisk.c
+++ b/asterisk.c
@@ -142,6 +142,7 @@ int option_timestamp = 0;
 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 @@ static void ast_readconfig(void) {
 		/* 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;
diff --git a/channel.c b/channel.c
index 6aa64e495ff638e17ef484c27fa98e71d9dc0a30..6c2566ffe1dee3e5672a41a192199b94f65eb8c4 100755
--- a/channel.c
+++ b/channel.c
@@ -3921,3 +3921,100 @@ struct ast_frame *ast_channel_spy_read_frame(struct ast_channel_spy *spy, unsign
 
 	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);
+}
diff --git a/doc/README.asterisk.conf b/doc/README.asterisk.conf
index 22416f942724dc5c33d03673a9adc42342619b9a..d2d8befcdd354fd6ac3831787512055cc52a56e8 100755
--- a/doc/README.asterisk.conf
+++ b/doc/README.asterisk.conf
@@ -39,24 +39,26 @@ astlogdir => /var/log/asterisk
 ;Under "options" you can enter configuration options
 ;that you also can set with command line options
 
-verbose=0		; Verbosity level for logging (-v)
-debug=3			; Debug: "No" or value (1-4)
-nofork=yes | no		; Background execution disabled (-f)
-console= yes | no	; Console mode (-c)
-highpriority = yes | no	; Execute with high priority (-p)
-initcrypto = yes | no	; Initialize crypto at startup (-i)
-nocolor = yes | no	; Disable ANSI colors (-n)
-dumpcore = yes | no	; Dump core on failure (-g)
-quiet = yes | no	; Run quietly (-q)
-timestamp = yes | no	; Force timestamping on log entries to console (-T)
-execincludes = yes | no ; Allow #exec entries in configuration files
-dontwarn = yes | no	; Don't over-inform the Asterisk sysadm, he's a guru
-transcode_via_sln = yes | no ; Build transcode paths via SLINEAR
-maxcalls = 255		; The maximum number of concurrent calls you want to allow 
-maxload = 1.0		; The maximum load average we accept calls for
-		
-;This option has no command line equivalent
-cache_record_files = yes | no	; Cache record() files in another directory until 				completion record_cache_dir = <dir>
+verbose = 0					; Verbosity level for logging (-v)
+debug = 3					; Debug: "No" or value (1-4)
+nofork=yes | no					; Background execution disabled (-f)
+console= yes | no				; Console mode (-c)
+highpriority = yes | no				; Execute with high priority (-p)
+initcrypto = yes | no				; Initialize crypto at startup (-i)
+nocolor = yes | no				; Disable ANSI colors (-n)
+dumpcore = yes | no				; Dump core on failure (-g)
+quiet = yes | no				; Run quietly (-q)
+timestamp = yes | no				; Force timestamping on log entries to console (-T)
+
+;These options have no command line equivalent
+cache_record_files = yes | no			; Cache record() files in another directory until completion
+record_cache_dir = <dir>
+transcode_via_sln = yes | no 			; Build transcode paths via SLINEAR
+transmit_silence_during_record = yes | no	; send SLINEAR silence while channel is being recorded
+maxload = 1.0					; The maximum load average we accept calls for
+maxcalls = 255					; The maximum number of concurrent calls you want to allow 
+execincludes = yes | no 			; Allow #exec entries in configuration files
+dontwarn = yes | no				; Don't over-inform the Asterisk sysadm, he's a guru
 
 [files]
 ; Changing the following lines may compromise your security
diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h
index 12ee9178e7f2531d08a36c52a3ecf5cc7d62c29e..6599edbb5e5bb608f18b1beeedba6687b4090918 100755
--- a/include/asterisk/channel.h
+++ b/include/asterisk/channel.h
@@ -1099,6 +1099,10 @@ struct ast_frame *ast_channel_spy_read_frame(struct ast_channel_spy *spy, unsign
  */
 void ast_channel_spy_trigger_wait(struct ast_channel_spy *spy);
 
+struct ast_silence_generator;
+struct ast_silence_generator *ast_channel_start_silence_generator(struct ast_channel *chan);
+void ast_channel_stop_silence_generator(struct ast_channel *chan, struct ast_silence_generator *state);
+
 /* Misc. functions below */
 
 /* Helper function for migrating select to poll */
diff --git a/include/asterisk/options.h b/include/asterisk/options.h
index 52f0af02719061eba6f0d8b928107d2fd09cf3fd..fd8f3aadb5e1997e15c81858b260ba8ac4604bf3 100755
--- a/include/asterisk/options.h
+++ b/include/asterisk/options.h
@@ -42,6 +42,7 @@ extern int option_exec_includes;
 extern int option_cache_record_files;
 extern int option_timestamp;
 extern int option_transcode_slin;
+extern int option_transmit_silence_during_record;
 extern int option_maxcalls;
 extern double option_maxload;
 extern int option_dontwarn;