Index: apps/app_mixmonitor.c
===================================================================
--- apps/app_mixmonitor.c	(revision 363310)
+++ apps/app_mixmonitor.c	(working copy)
@@ -407,6 +407,7 @@
 			}
 			continue;
 		}
+		ast_debug(5, "MixMonitor got itself a frame and is gonna write it!\n");
 
 		/* audiohook lock is not required for the next block.
 		 * Unlock it, but remember to lock it before looping or exiting */
Index: main/audiohook.c
===================================================================
--- main/audiohook.c	(revision 363310)
+++ main/audiohook.c	(working copy)
@@ -116,6 +116,7 @@
 	/* Since we are just starting out... this audiohook is new */
 	ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_NEW);
 
+	ast_debug(5, "Initialized audiohook %p with sample rate %u\n", audiohook, audiohook->hook_internal_samp_rate);
 	return 0;
 }
 
@@ -165,6 +166,8 @@
 	int muteme = 0;
 
 	/* Update last feeding time to be current */
+	ast_debug(5, "[%p] %s %p is getting fed (nom nom nom)\n", audiohook, direction == AST_AUDIOHOOK_DIRECTION_READ ? "Read factory" : "Write factory",
+		direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->read_factory : &audiohook->write_factory);
 	*rwtime = ast_tvnow();
 
 	our_factory_samples = ast_slinfactory_available(factory);
@@ -240,8 +243,11 @@
 
 static struct ast_frame *audiohook_read_frame_both(struct ast_audiohook *audiohook, size_t samples, struct ast_frame **read_reference, struct ast_frame **write_reference)
 {
-	int i = 0, usable_read, usable_write;
+	int i = 0, usable_read, usable_write, read_comparison, write_comparison;
+	int64_t write_diff, read_diff;
 	short buf1[samples], buf2[samples], *read_buf = NULL, *write_buf = NULL, *final_buf = NULL, *data1 = NULL, *data2 = NULL;
+	struct timeval time_now;
+	unsigned int read_size, write_size;
 	struct ast_frame frame = {
 		.frametype = AST_FRAME_VOICE,
 		.data.ptr = NULL,
@@ -251,24 +257,40 @@
 	ast_format_set(&frame.subclass.format, ast_format_slin_by_rate(audiohook->hook_internal_samp_rate), 0);
 
 	/* Make sure both factories have the required samples */
-	usable_read = (ast_slinfactory_available(&audiohook->read_factory) >= samples ? 1 : 0);
-	usable_write = (ast_slinfactory_available(&audiohook->write_factory) >= samples ? 1 : 0);
+	write_size = ast_slinfactory_available(&audiohook->write_factory);
+	read_size = ast_slinfactory_available(&audiohook->read_factory);
+	usable_read = (read_size >= samples ? 1 : 0);
+	usable_write = (write_size >= samples ? 1 : 0);
 
+	ast_debug(5, "[%p] Got %u and %u samples from the read/write factories %p/%p\n",
+		audiohook, read_size, write_size, &audiohook->read_factory, &audiohook->write_factory);
 	if (!usable_read && !usable_write) {
 		/* If both factories are unusable bail out */
-		ast_debug(1, "Read factory %p and write factory %p both fail to provide %zd samples\n", &audiohook->read_factory, &audiohook->write_factory, samples);
+		ast_debug(1, "[%p] Read factory %p and write factory %p both fail to provide %zd samples\n", audiohook, &audiohook->read_factory, &audiohook->write_factory, samples);
 		return NULL;
 	}
 
 	/* If we want to provide only a read factory make sure we aren't waiting for other audio */
-	if (usable_read && !usable_write && (ast_tvdiff_ms(ast_tvnow(), audiohook->write_time) < (samples/8)*2)) {
-		ast_debug(3, "Write factory %p was pretty quick last time, waiting for them.\n", &audiohook->write_factory);
+	time_now = ast_tvnow();
+	audiohook->read_time.tv_sec = 0;
+	audiohook->read_time.tv_usec = 0;
+	read_diff = ast_tvdiff_ms(time_now, audiohook->read_time);
+	write_diff = ast_tvdiff_ms(time_now, audiohook->write_time);
+	write_comparison = write_diff < (samples/8)*2;
+	read_comparison = read_diff < (samples/8)*2;
+	ast_debug(5, "[%p] Samples: %zu; Sample threshold: %zu; Current time: %ld.%ld; write time: %ld.%ld; write diff: %ld; write compare: %d; read time: %ld.%ld; read_diff: %ld; read compare: %d\n",
+		audiohook, samples, (samples/8)*2, time_now.tv_sec, time_now.tv_usec, audiohook->write_time.tv_sec, audiohook->write_time.tv_usec,
+		write_diff, write_comparison, audiohook->read_time.tv_sec, audiohook->read_time.tv_usec, read_diff, read_comparison);
+	if (usable_read && !usable_write && (ast_tvdiff_ms(ast_tvnow(), audiohook->write_time) < (samples/8)*2)
+		&& !(audiohook->write_time.tv_sec == 0)) {
+		ast_debug(3, "[%p] Write factory %p was pretty quick last time, waiting for them.\n", audiohook, &audiohook->write_factory);
 		return NULL;
 	}
 
 	/* If we want to provide only a write factory make sure we aren't waiting for other audio */
-	if (usable_write && !usable_read && (ast_tvdiff_ms(ast_tvnow(), audiohook->read_time) < (samples/8)*2)) {
-		ast_debug(3, "Read factory %p was pretty quick last time, waiting for them.\n", &audiohook->read_factory);
+	if (usable_write && !usable_read && (ast_tvdiff_ms(ast_tvnow(), audiohook->read_time) < (samples/8)*2)
+		&& !(audiohook->read_time.tv_sec == 0)) {
+		ast_debug(3, "[%p] Read factory %p was pretty quick last time, waiting for them.\n", audiohook, &audiohook->read_factory);
 		return NULL;
 	}
 
@@ -288,8 +310,9 @@
 				}
 			}
 		}
+	} else {
+		ast_debug(1, "[%p] Failed to get %d samples from read factory %p\n", audiohook, (int)samples, &audiohook->read_factory);
 	}
-	ast_debug(1, "Failed to get %d samples from read factory %p\n", (int)samples, &audiohook->read_factory);
 
 	/* Move on to the write factory... if there are enough samples, read them in */
 	if (usable_write) {
@@ -307,8 +330,9 @@
 				}
 			}
 		}
+	} else {
+		ast_debug(1, "[%p] Failed to get %d samples from write factory %p\n", audiohook, (int)samples, &audiohook->write_factory);
 	}
-	ast_debug(1, "Failed to get %d samples from write factory %p\n", (int)samples, &audiohook->write_factory);
 
 	/* Basically we figure out which buffer to use... and if mixing can be done here */
 	if (read_buf && read_reference) {
@@ -358,8 +382,9 @@
 
 	if (!(read_frame = (direction == AST_AUDIOHOOK_DIRECTION_BOTH ? 
 		audiohook_read_frame_both(audiohook, samples_converted, read_reference, write_reference) : 
-		audiohook_read_frame_single(audiohook, samples_converted, direction)))) { 
-		return NULL; 
+		audiohook_read_frame_single(audiohook, samples_converted, direction)))) {
+		ast_debug(5, "[%p] Failed to read frame for audiohook (%zd: %ud: %d)\n", audiohook, samples, audiohook->hook_internal_samp_rate, ast_format_rate(format));
+		return NULL;
 	}
 
 	/* If they don't want signed linear back out, we'll have to send it through the translation path */
@@ -373,6 +398,7 @@
 
 			/* Setup new translation path for this format... if we fail we can't very well return signed linear so free the frame and return nothing */
 			if (!(audiohook->trans_pvt = ast_translator_build_path(format, ast_format_set(&tmp_fmt, ast_format_slin_by_rate(audiohook->hook_internal_samp_rate), 0)))) {
+				ast_log(AST_LOG_WARNING, "Failed to create translator path from %s to %s\n", ast_getformatname(format), ast_getformatname(&tmp_fmt));
 				ast_frfree(read_frame);
 				return NULL;
 			}
@@ -785,6 +811,7 @@
 
 	/* ---Part_1. translate start_frame to SLINEAR if necessary. */
 	if (!(middle_frame = audiohook_list_translate_to_slin(audiohook_list, direction, start_frame))) {
+		ast_debug(5, "Rut roh - failed to translate frame to slin in audiohook\n");
 		return frame;
 	}
 	samples = middle_frame->samples;
