[asterisk-commits] dvossel: branch dvossel/fixtheworld_phase2 r308203 - in /team/dvossel/fixthew...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Feb 17 10:39:34 CST 2011


Author: dvossel
Date: Thu Feb 17 10:39:28 2011
New Revision: 308203

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=308203
Log:
Fixes issue with audiohook internal sample rate

Modified:
    team/dvossel/fixtheworld_phase2/include/asterisk/audiohook.h
    team/dvossel/fixtheworld_phase2/main/audiohook.c

Modified: team/dvossel/fixtheworld_phase2/include/asterisk/audiohook.h
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase2/include/asterisk/audiohook.h?view=diff&rev=308203&r1=308202&r2=308203
==============================================================================
--- team/dvossel/fixtheworld_phase2/include/asterisk/audiohook.h (original)
+++ team/dvossel/fixtheworld_phase2/include/asterisk/audiohook.h Thu Feb 17 10:39:28 2011
@@ -116,9 +116,7 @@
 	struct ast_trans_pvt *trans_pvt;                       /*!< Translation path for reading frames */
 	ast_audiohook_manipulate_callback manipulate_callback; /*!< Manipulation callback */
 	struct ast_audiohook_options options;                  /*!< Applicable options */
-	int last_read_rate;                  /*!< The last sample rate used when writing in the read direction to the audiohook. */
-	int last_write_rate;                 /*!< The last sample rate used when writing in the write direction to the audiohook. */
-	int internal_read_write_rate;        /*!< internal read/write rate is the MAX(last_read_rate, last_write_rate) */
+	int hook_internal_samp_rate;                           /*!< internal read/write sample rate on the audiohook.*/
 	AST_LIST_ENTRY(ast_audiohook) list;                    /*!< Linked list information */
 };
 

Modified: team/dvossel/fixtheworld_phase2/main/audiohook.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase2/main/audiohook.c?view=diff&rev=308203&r1=308202&r2=308203
==============================================================================
--- team/dvossel/fixtheworld_phase2/main/audiohook.c (original)
+++ team/dvossel/fixtheworld_phase2/main/audiohook.c Thu Feb 17 10:39:28 2011
@@ -49,6 +49,8 @@
 	 * variable will be set and the sample rate will
 	 * be preserved during ast_audiohook_write_list()*/
 	int native_slin_compatible;
+	int list_internal_samp_rate;/*!< Internal sample rate used when writing to the audiohook list */
+
 	struct ast_audiohook_translate in_translate[2];
 	struct ast_audiohook_translate out_translate[2];
 	AST_LIST_HEAD_NOLOCK(, ast_audiohook) spy_list;
@@ -56,16 +58,15 @@
 	AST_LIST_HEAD_NOLOCK(, ast_audiohook) manipulate_list;
 };
 
-static int audiohook_set_internal_rate(struct ast_audiohook *audiohook, int reset)
+static int audiohook_set_internal_rate(struct ast_audiohook *audiohook, int rate, int reset)
 {
 	struct ast_format slin;
-	int rate = MAX(audiohook->last_read_rate, audiohook->last_write_rate);
-
-	if (audiohook->internal_read_write_rate == rate) {
+
+	if (audiohook->hook_internal_samp_rate == rate) {
 		return 0;
 	}
 
-	audiohook->internal_read_write_rate = rate;
+	audiohook->hook_internal_samp_rate = rate;
 
 	ast_format_set(&slin, ast_format_slin_by_rate(rate), 0);
 	/* Setup the factories that are needed for this audiohook type */
@@ -88,23 +89,6 @@
 	return 0;
 }
 
-static int audiohook_update_rate(struct ast_audiohook *audiohook, enum ast_audiohook_direction direction, int rate)
-{
-	switch (direction) {
-	case AST_AUDIOHOOK_DIRECTION_READ:
-		audiohook->last_read_rate = rate;
-		break;
-	case AST_AUDIOHOOK_DIRECTION_WRITE:
-		audiohook->last_write_rate = rate;
-		break;
-	case AST_AUDIOHOOK_DIRECTION_BOTH:
-		audiohook->last_read_rate = rate;
-		audiohook->last_write_rate = rate;
-		break;
-	}
-	return audiohook_set_internal_rate(audiohook, 1);
-}
-
 /*! \brief Initialize an audiohook structure
  * \param audiohook Audiohook structure
  * \param type
@@ -122,10 +106,9 @@
 	ast_cond_init(&audiohook->trigger, NULL);
 
 	audiohook->init_flags = init_flags;
+
 	/* initialize internal rate at 8khz, this will adjust if necessary */
-	audiohook->last_read_rate = audiohook->last_write_rate = 8000;
-
-	audiohook_set_internal_rate(audiohook, 0);
+	audiohook_set_internal_rate(audiohook, 8000, 0);
 
 	/* Since we are just starting out... this audiohook is new */
 	ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_NEW);
@@ -182,9 +165,9 @@
 	*rwtime = ast_tvnow();
 
 	our_factory_samples = ast_slinfactory_available(factory);
-	our_factory_ms = ast_tvdiff_ms(*rwtime, previous_time) + (our_factory_samples / (audiohook->internal_read_write_rate / 1000));
+	our_factory_ms = ast_tvdiff_ms(*rwtime, previous_time) + (our_factory_samples / (audiohook->hook_internal_samp_rate / 1000));
 	other_factory_samples = ast_slinfactory_available(other_factory);
-	other_factory_ms = other_factory_samples / (audiohook->internal_read_write_rate / 1000);
+	other_factory_ms = other_factory_samples / (audiohook->hook_internal_samp_rate / 1000);
 
 	if (ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_SYNC) && other_factory_samples && (our_factory_ms - other_factory_ms > AST_AUDIOHOOK_SYNC_TOLERANCE)) {
 		ast_debug(1, "Flushing audiohook %p so it remains in sync\n", audiohook);
@@ -235,7 +218,7 @@
 		.datalen = sizeof(buf),
 		.samples = samples,
 	};
-	ast_format_set(&frame.subclass.format, ast_format_slin_by_rate(audiohook->internal_read_write_rate), 0);
+	ast_format_set(&frame.subclass.format, ast_format_slin_by_rate(audiohook->hook_internal_samp_rate), 0);
 
 	/* Ensure the factory is able to give us the samples we want */
 	if (samples > ast_slinfactory_available(factory))
@@ -262,7 +245,7 @@
 		.datalen = sizeof(buf1),
 		.samples = samples,
 	};
-	ast_format_set(&frame.subclass.format, ast_format_slin_by_rate(audiohook->internal_read_write_rate), 0);
+	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);
@@ -358,12 +341,12 @@
 
 	/* the number of samples requested is based on the format they are requesting.  Inorder
 	 * to process this correctly samples must be converted to our internal sample rate */
-	if (audiohook->internal_read_write_rate == ast_format_rate(format)) {
+	if (audiohook->hook_internal_samp_rate == ast_format_rate(format)) {
 		samples_converted = samples;
-	} else if (audiohook->internal_read_write_rate > ast_format_rate(format)) {
-		samples_converted = samples * (audiohook->internal_read_write_rate / (float) ast_format_rate(format));
+	} else if (audiohook->hook_internal_samp_rate > ast_format_rate(format)) {
+		samples_converted = samples * (audiohook->hook_internal_samp_rate / (float) ast_format_rate(format));
 	} else {
-		samples_converted = samples * (ast_format_rate(format) / (float) audiohook->internal_read_write_rate);
+		samples_converted = samples * (ast_format_rate(format) / (float) audiohook->hook_internal_samp_rate);
 	}
 
 	if (!(read_frame = (direction == AST_AUDIOHOOK_DIRECTION_BOTH ?
@@ -373,7 +356,7 @@
 	}
 
 	/* If they don't want signed linear back out, we'll have to send it through the translation path */
-	if (format->id != ast_format_slin_by_rate(audiohook->internal_read_write_rate)) {
+	if (format->id != ast_format_slin_by_rate(audiohook->hook_internal_samp_rate)) {
 		/* Rebuild translation path if different format then previously */
 		if (ast_format_cmp(format, &audiohook->format) == AST_FORMAT_CMP_NOT_EQUAL) {
 			if (audiohook->trans_pvt) {
@@ -382,7 +365,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->internal_read_write_rate), 0)))) {
+			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_frfree(read_frame);
 				return NULL;
 			}
@@ -427,6 +410,8 @@
 		AST_LIST_HEAD_INIT_NOLOCK(&chan->audiohooks->spy_list);
 		AST_LIST_HEAD_INIT_NOLOCK(&chan->audiohooks->whisper_list);
 		AST_LIST_HEAD_INIT_NOLOCK(&chan->audiohooks->manipulate_list);
+		/* This sample rate will adjust as necessary when writing to the list. */
+		chan->audiohooks->list_internal_samp_rate = 8000;
 	}
 
 	/* Drop into respective list */
@@ -437,6 +422,8 @@
 	else if (audiohook->type == AST_AUDIOHOOK_TYPE_MANIPULATE)
 		AST_LIST_INSERT_TAIL(&chan->audiohooks->manipulate_list, audiohook, list);
 
+
+	audiohook_set_internal_rate(audiohook, chan->audiohooks->list_internal_samp_rate, 1);
 	audiohook_list_set_samplerate_compatibility(chan->audiohooks);
 
 	/* Change status over to running since it is now attached */
@@ -675,9 +662,18 @@
 		&audiohook_list->in_translate[0] : &audiohook_list->in_translate[1]);
 	struct ast_frame *new_frame = frame;
 	struct ast_format tmp_fmt;
-	enum ast_format_id slin_id = audiohook_list->native_slin_compatible ?
-		ast_format_slin_by_rate(ast_format_rate(&frame->subclass.format)) :
-		AST_FORMAT_SLINEAR;
+	enum ast_format_id slin_id;
+
+	/* If we are capable of maintaining doing samplerates other that 8khz, update
+	 * the internal audiohook_list's rate and higher samplerate audio arrives. By
+	 * updating the list's rate, all the audiohooks in the list will be updated as well
+	 * as the are written and read from. */
+	if (audiohook_list->native_slin_compatible) {
+		audiohook_list->list_internal_samp_rate =
+			MAX(ast_format_rate(&frame->subclass.format), audiohook_list->list_internal_samp_rate);
+	}
+
+	slin_id = ast_format_slin_by_rate(audiohook_list->list_internal_samp_rate);
 
 	if (frame->subclass.format.id == slin_id) {
 		return new_frame;
@@ -777,7 +773,7 @@
 			ast_audiohook_unlock(audiohook);
 			continue;
 		}
-		audiohook_update_rate(audiohook, direction, ast_format_rate(&middle_frame->subclass.format));
+		audiohook_set_internal_rate(audiohook, audiohook_list->list_internal_samp_rate, 1);
 		ast_audiohook_write_frame(audiohook, direction, middle_frame);
 		ast_audiohook_unlock(audiohook);
 	}
@@ -797,7 +793,7 @@
 				ast_audiohook_unlock(audiohook);
 				continue;
 			}
-			audiohook_update_rate(audiohook, direction, ast_format_rate(&middle_frame->subclass.format));
+			audiohook_set_internal_rate(audiohook, audiohook_list->list_internal_samp_rate, 1);
 			if (ast_slinfactory_available(&audiohook->write_factory) >= samples && ast_slinfactory_read(&audiohook->write_factory, read_buf, samples)) {
 				/* Take audio from this whisper source and combine it into our main buffer */
 				for (i = 0, data1 = combine_buf, data2 = read_buf; i < samples; i++, data1++, data2++)
@@ -826,6 +822,7 @@
 				audiohook->manipulate_callback(audiohook, chan, NULL, direction);
 				continue;
 			}
+			audiohook_set_internal_rate(audiohook, audiohook_list->list_internal_samp_rate, 1);
 			/* Feed in frame to manipulation. */
 			if (audiohook->manipulate_callback(audiohook, chan, middle_frame, direction)) {
 				/* XXX IGNORE FAILURE */




More information about the asterisk-commits mailing list