[svn-commits] file: trunk r108084 - in /trunk: ./ apps/ include/asterisk/ main/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Mar 12 13:29:34 CDT 2008


Author: file
Date: Wed Mar 12 13:29:33 2008
New Revision: 108084

URL: http://svn.digium.com/view/asterisk?view=rev&rev=108084
Log:
Merged revisions 108083 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r108083 | file | 2008-03-12 15:26:37 -0300 (Wed, 12 Mar 2008) | 4 lines

Add a trigger mode that triggers on both read and write. The actual function that returns the combined audio frame though will wait until both sides have fed in audio, or until one side stops (such as the case when you call Wait).
(closes issue #11945)
Reported by: xheliox

........

Modified:
    trunk/   (props changed)
    trunk/apps/app_mixmonitor.c
    trunk/include/asterisk/audiohook.h
    trunk/main/audiohook.c

Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Modified: trunk/apps/app_mixmonitor.c
URL: http://svn.digium.com/view/asterisk/trunk/apps/app_mixmonitor.c?view=diff&rev=108084&r1=108083&r2=108084
==============================================================================
--- trunk/apps/app_mixmonitor.c (original)
+++ trunk/apps/app_mixmonitor.c Wed Mar 12 13:29:33 2008
@@ -253,7 +253,7 @@
 		return;
 	}
 
-	ast_set_flag(&mixmonitor->audiohook, AST_AUDIOHOOK_TRIGGER_WRITE);
+	ast_set_flag(&mixmonitor->audiohook, AST_AUDIOHOOK_TRIGGER_SYNC);
 
 	if (readvol)
 		mixmonitor->audiohook.options.read_volume = readvol;

Modified: trunk/include/asterisk/audiohook.h
URL: http://svn.digium.com/view/asterisk/trunk/include/asterisk/audiohook.h?view=diff&rev=108084&r1=108083&r2=108084
==============================================================================
--- trunk/include/asterisk/audiohook.h (original)
+++ trunk/include/asterisk/audiohook.h Wed Mar 12 13:29:33 2008
@@ -57,6 +57,7 @@
 	AST_AUDIOHOOK_TRIGGER_READ = (1 << 0),  /*!< Audiohook wants to be triggered when reading audio in */
 	AST_AUDIOHOOK_TRIGGER_WRITE = (2 << 0), /*!< Audiohook wants to be triggered when writing audio out */
 	AST_AUDIOHOOK_WANTS_DTMF = (1 << 1),    /*!< Audiohook also wants to receive DTMF frames */
+	AST_AUDIOHOOK_TRIGGER_SYNC = (1 << 2),  /*!< Audiohook wants to be triggered when both sides have combined audio available */
 };
 
 struct ast_audiohook;
@@ -86,6 +87,8 @@
 	unsigned int flags;                                    /*!< Flags on the audiohook */
 	struct ast_slinfactory read_factory;                   /*!< Factory where frames read from the channel, or read from the whisper source will go through */
 	struct ast_slinfactory write_factory;                  /*!< Factory where frames written to the channel will go through */
+	struct timeval read_time;                              /*!< Last time read factory was fed */
+	struct timeval write_time;                             /*!< Last time write factory was fed */
 	int format;                                            /*!< Format translation path is setup as */
 	struct ast_trans_pvt *trans_pvt;                       /*!< Translation path for reading frames */
 	ast_audiohook_manipulate_callback manipulate_callback; /*!< Manipulation callback */

Modified: trunk/main/audiohook.c
URL: http://svn.digium.com/view/asterisk/trunk/main/audiohook.c?view=diff&rev=108084&r1=108083&r2=108084
==============================================================================
--- trunk/main/audiohook.c (original)
+++ trunk/main/audiohook.c Wed Mar 12 13:29:33 2008
@@ -121,22 +121,21 @@
 int ast_audiohook_write_frame(struct ast_audiohook *audiohook, enum ast_audiohook_direction direction, struct ast_frame *frame)
 {
 	struct ast_slinfactory *factory = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->read_factory : &audiohook->write_factory);
+	struct timeval *time = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->read_time : &audiohook->write_time);
 
 	/* Write frame out to respective factory */
 	ast_slinfactory_feed(factory, frame);
 
+	/* Update last fed time for the above factory */
+	*time = ast_tvnow();
+
 	/* If we need to notify the respective handler of this audiohook, do so */
-	switch (ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_MODE)) {
-	case AST_AUDIOHOOK_TRIGGER_READ:
-		if (direction == AST_AUDIOHOOK_DIRECTION_READ)
-			ast_cond_signal(&audiohook->trigger);
-		break;
-	case AST_AUDIOHOOK_TRIGGER_WRITE:
-		if (direction == AST_AUDIOHOOK_DIRECTION_WRITE)
-			ast_cond_signal(&audiohook->trigger);
-		break;
-	default:
-		break;
+	if ((ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_MODE) == AST_AUDIOHOOK_TRIGGER_READ) && (direction == AST_AUDIOHOOK_DIRECTION_READ)) {
+		ast_cond_signal(&audiohook->trigger);
+	} else if ((ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_MODE) == AST_AUDIOHOOK_TRIGGER_WRITE) && (direction == AST_AUDIOHOOK_DIRECTION_WRITE)) {
+		ast_cond_signal(&audiohook->trigger);
+	} else if (ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_SYNC)) {
+		ast_cond_signal(&audiohook->trigger);
 	}
 
 	return 0;
@@ -172,7 +171,7 @@
 
 static struct ast_frame *audiohook_read_frame_both(struct ast_audiohook *audiohook, size_t samples)
 {
-	int i = 0;
+	int i = 0, usable_read, usable_write;
 	short buf1[samples], buf2[samples], *read_buf = NULL, *write_buf = NULL, *final_buf = NULL, *data1 = NULL, *data2 = NULL;
 	struct ast_frame frame = {
 		.frametype = AST_FRAME_VOICE,
@@ -182,8 +181,30 @@
 		.samples = samples,
 	};
 
+	/* 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);
+
+	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);
+		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(1, "Write factory %p was pretty quick last time, waiting for them.\n", &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->write_time) < (samples/8)*2)) {
+		ast_debug(1, "Read factory %p was pretty quick last time, waiting for them.\n", &audiohook->read_factory);
+		return NULL;
+	}
+
 	/* Start with the read factory... if there are enough samples, read them in */
-	if (ast_slinfactory_available(&audiohook->read_factory) >= samples) {
+	if (usable_read && ast_slinfactory_available(&audiohook->read_factory) >= samples) {
 		if (ast_slinfactory_read(&audiohook->read_factory, buf1, samples)) {
 			read_buf = buf1;
 			/* Adjust read volume if need be */
@@ -202,7 +223,7 @@
 		ast_log(LOG_DEBUG, "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 (ast_slinfactory_available(&audiohook->write_factory) >= samples) {
+	if (usable_write && ast_slinfactory_available(&audiohook->write_factory) >= samples) {
 		if (ast_slinfactory_read(&audiohook->write_factory, buf2, samples)) {
 			write_buf = buf2;
 			/* Adjust write volume if need be */




More information about the svn-commits mailing list