diff --git a/apps/app_mixmonitor.c b/apps/app_mixmonitor.c
index af2949209056d91034ca12b886501bc5029a3def..6746c473cf733e4b88cd42e46dfee71349f6e576 100644
--- a/apps/app_mixmonitor.c
+++ b/apps/app_mixmonitor.c
@@ -115,6 +115,11 @@
 						Like with the basic filename argument, if an absolute path isn't given, it will create
 						the file in the configured monitoring directory.</para>
 					</option>
+					<option name="S">
+						<para>When combined with the <replaceable>r</replaceable> or <replaceable>t</replaceable>
+						option, inserts silence when necessary to maintain synchronization between the receive
+						and transmit audio streams.</para>
+					</option>
 					<option name="i">
 						<argument name="chanvar" required="true" />
 						<para>Stores the MixMonitor's ID on this channel variable.</para>
@@ -347,7 +352,8 @@ enum mixmonitor_flags {
 	MUXFLAG_VMRECIPIENTS = (1 << 10),
 	MUXFLAG_BEEP = (1 << 11),
 	MUXFLAG_BEEP_START = (1 << 12),
-	MUXFLAG_BEEP_STOP = (1 << 13)
+	MUXFLAG_BEEP_STOP = (1 << 13),
+	MUXFLAG_RWSYNC = (1 << 14),
 };
 
 enum mixmonitor_args {
@@ -359,6 +365,7 @@ enum mixmonitor_args {
 	OPT_ARG_UID,
 	OPT_ARG_VMRECIPIENTS,
 	OPT_ARG_BEEP_INTERVAL,
+	OPT_ARG_RWSYNC,
 	OPT_ARG_ARRAY_SIZE,	/* Always last element of the enum */
 };
 
@@ -375,6 +382,7 @@ AST_APP_OPTIONS(mixmonitor_opts, {
 	AST_APP_OPTION_ARG('t', MUXFLAG_WRITE, OPT_ARG_WRITENAME),
 	AST_APP_OPTION_ARG('i', MUXFLAG_UID, OPT_ARG_UID),
 	AST_APP_OPTION_ARG('m', MUXFLAG_VMRECIPIENTS, OPT_ARG_VMRECIPIENTS),
+	AST_APP_OPTION_ARG('S', MUXFLAG_RWSYNC, OPT_ARG_RWSYNC),
 });
 
 struct mixmonitor_ds {
@@ -962,6 +970,9 @@ static int launch_monitor_thread(struct ast_channel *chan, const char *filename,
 	}
 
 	ast_set_flag(&mixmonitor->audiohook, AST_AUDIOHOOK_TRIGGER_SYNC);
+	if ((ast_test_flag(mixmonitor, MUXFLAG_RWSYNC))) {
+		ast_set_flag(&mixmonitor->audiohook, AST_AUDIOHOOK_SUBSTITUTE_SILENCE);
+	}
 
 	if (readvol)
 		mixmonitor->audiohook.options.read_volume = readvol;
diff --git a/doc/CHANGES-staging/mixmonitor-s-option.txt b/doc/CHANGES-staging/mixmonitor-s-option.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d08b86d3fc3acfb7e3a12647c3a11aa10699abe4
--- /dev/null
+++ b/doc/CHANGES-staging/mixmonitor-s-option.txt
@@ -0,0 +1,7 @@
+Subject: app_mixmonitor
+
+An option 'S' has been added to MixMonitor. If used in combination with
+the r() and/or t() options, if a frame is available to write to one of
+those files but not the other, a frame of silence if written to the file
+that does not have an audio frame. This should prevent the two files
+from "drifting" when mixed after the fact.
diff --git a/include/asterisk/audiohook.h b/include/asterisk/audiohook.h
index cae8cc0711902699b9163f5fc416d7b56f3c4088..1252e3655b63ab1143260ada36d3b3e026809cab 100644
--- a/include/asterisk/audiohook.h
+++ b/include/asterisk/audiohook.h
@@ -64,6 +64,8 @@ enum ast_audiohook_flags {
 	AST_AUDIOHOOK_MUTE_READ     = (1 << 5), /*!< audiohook should be mute frames read */
 	AST_AUDIOHOOK_MUTE_WRITE    = (1 << 6), /*!< audiohook should be mute frames written */
 	AST_AUDIOHOOK_COMPATIBLE    = (1 << 7), /*!< is the audiohook native slin compatible */
+
+	AST_AUDIOHOOK_SUBSTITUTE_SILENCE = (1 << 8), /*!< Substitute silence for missing audio */
 };
 
 enum ast_audiohook_init_flags {
diff --git a/main/audiohook.c b/main/audiohook.c
index 04a379fefe190042c5fd52ca00e42e76d4e341cb..4db32ea7c0de0222150306e4d46a4f9e80bece3f 100644
--- a/main/audiohook.c
+++ b/main/audiohook.c
@@ -338,6 +338,17 @@ static struct ast_frame *audiohook_read_frame_both(struct ast_audiohook *audioho
 
 	frame.subclass.format = ast_format_cache_get_slin_by_rate(audiohook->hook_internal_samp_rate);
 
+	/* Should we substitute silence if one side lacks audio? */
+	if ((ast_test_flag(audiohook, AST_AUDIOHOOK_SUBSTITUTE_SILENCE))) {
+		if (read_reference && !read_buf && write_buf) {
+			read_buf = buf1;
+			memset(buf1, 0, sizeof(buf1));
+		} else if (write_reference && read_buf && !write_buf) {
+			write_buf = buf2;
+			memset(buf2, 0, sizeof(buf2));
+		}
+	}
+
 	/* Basically we figure out which buffer to use... and if mixing can be done here */
 	if (read_buf && read_reference) {
 		frame.data.ptr = read_buf;