[asterisk-commits] dvossel: branch dvossel/hd_conferencing_ftw r307966 - in /team/dvossel/hd_con...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Feb 15 16:24:25 CST 2011


Author: dvossel
Date: Tue Feb 15 16:24:20 2011
New Revision: 307966

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=307966
Log:
Addition of the ability to perform audiohook manipulation at any samplerate

This functionality has been extended to Volume, All speex preprocessing functions,
and pitchshift.

Modified:
    team/dvossel/hd_conferencing_ftw/apps/app_chanspy.c
    team/dvossel/hd_conferencing_ftw/apps/app_jack.c
    team/dvossel/hd_conferencing_ftw/apps/app_mixmonitor.c
    team/dvossel/hd_conferencing_ftw/bridges/bridge_softmix.c
    team/dvossel/hd_conferencing_ftw/funcs/func_pitchshift.c
    team/dvossel/hd_conferencing_ftw/funcs/func_speex.c
    team/dvossel/hd_conferencing_ftw/funcs/func_volume.c
    team/dvossel/hd_conferencing_ftw/include/asterisk/audiohook.h
    team/dvossel/hd_conferencing_ftw/include/asterisk/format.h
    team/dvossel/hd_conferencing_ftw/main/audiohook.c
    team/dvossel/hd_conferencing_ftw/main/frame.c
    team/dvossel/hd_conferencing_ftw/res/res_mutestream.c

Modified: team/dvossel/hd_conferencing_ftw/apps/app_chanspy.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_conferencing_ftw/apps/app_chanspy.c?view=diff&rev=307966&r1=307965&r2=307966
==============================================================================
--- team/dvossel/hd_conferencing_ftw/apps/app_chanspy.c (original)
+++ team/dvossel/hd_conferencing_ftw/apps/app_chanspy.c Tue Feb 15 16:24:20 2011
@@ -541,15 +541,15 @@
 	memset(&csth, 0, sizeof(csth));
 	ast_copy_flags(&csth.spy_audiohook, flags, AST_FLAGS_ALL);
 
-	ast_audiohook_init(&csth.spy_audiohook, AST_AUDIOHOOK_TYPE_SPY, "ChanSpy");
+	ast_audiohook_init(&csth.spy_audiohook, AST_AUDIOHOOK_TYPE_SPY, "ChanSpy", 0);
 
 	if (start_spying(spyee_autochan, spyer_name, &csth.spy_audiohook)) {
 		ast_audiohook_destroy(&csth.spy_audiohook);
 		return 0;
 	}
 
-	ast_audiohook_init(&csth.whisper_audiohook, AST_AUDIOHOOK_TYPE_WHISPER, "ChanSpy");
-	ast_audiohook_init(&csth.bridge_whisper_audiohook, AST_AUDIOHOOK_TYPE_WHISPER, "Chanspy");
+	ast_audiohook_init(&csth.whisper_audiohook, AST_AUDIOHOOK_TYPE_WHISPER, "ChanSpy", 0);
+	ast_audiohook_init(&csth.bridge_whisper_audiohook, AST_AUDIOHOOK_TYPE_WHISPER, "Chanspy", 0);
 	if (start_spying(spyee_autochan, spyer_name, &csth.whisper_audiohook)) {
 		ast_log(LOG_WARNING, "Unable to attach whisper audiohook to spyee %s. Whisper mode disabled!\n", name);
 	}

Modified: team/dvossel/hd_conferencing_ftw/apps/app_jack.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_conferencing_ftw/apps/app_jack.c?view=diff&rev=307966&r1=307965&r2=307966
==============================================================================
--- team/dvossel/hd_conferencing_ftw/apps/app_jack.c (original)
+++ team/dvossel/hd_conferencing_ftw/apps/app_jack.c Tue Feb 15 16:24:20 2011
@@ -885,7 +885,7 @@
 		goto return_error;
 
 	jack_data->has_audiohook = 1;
-	ast_audiohook_init(&jack_data->audiohook, AST_AUDIOHOOK_TYPE_MANIPULATE, "JACK_HOOK");
+	ast_audiohook_init(&jack_data->audiohook, AST_AUDIOHOOK_TYPE_MANIPULATE, "JACK_HOOK", 0);
 	jack_data->audiohook.manipulate_callback = jack_hook_callback;
 
 	datastore->data = jack_data;

Modified: team/dvossel/hd_conferencing_ftw/apps/app_mixmonitor.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_conferencing_ftw/apps/app_mixmonitor.c?view=diff&rev=307966&r1=307965&r2=307966
==============================================================================
--- team/dvossel/hd_conferencing_ftw/apps/app_mixmonitor.c (original)
+++ team/dvossel/hd_conferencing_ftw/apps/app_mixmonitor.c Tue Feb 15 16:24:20 2011
@@ -426,7 +426,7 @@
 	}
 
 	/* Setup the actual spy before creating our thread */
-	if (ast_audiohook_init(&mixmonitor->audiohook, AST_AUDIOHOOK_TYPE_SPY, mixmonitor_spy_type)) {
+	if (ast_audiohook_init(&mixmonitor->audiohook, AST_AUDIOHOOK_TYPE_SPY, mixmonitor_spy_type, 0)) {
 		mixmonitor_free(mixmonitor);
 		return;
 	}

Modified: team/dvossel/hd_conferencing_ftw/bridges/bridge_softmix.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_conferencing_ftw/bridges/bridge_softmix.c?view=diff&rev=307966&r1=307965&r2=307966
==============================================================================
--- team/dvossel/hd_conferencing_ftw/bridges/bridge_softmix.c (original)
+++ team/dvossel/hd_conferencing_ftw/bridges/bridge_softmix.c Tue Feb 15 16:24:20 2011
@@ -124,25 +124,6 @@
 	return 0;
 }
 
-static enum ast_format_id slin_by_rate(int rate) {
-	if (rate >= 96000) {
-		return AST_FORMAT_SLINEAR96;
-	} else if (rate >= 48000) {
-		return AST_FORMAT_SLINEAR48;
-	} else if (rate >= 44100) {
-		return AST_FORMAT_SLINEAR44;
-	} else if (rate >= 32000) {
-		return AST_FORMAT_SLINEAR32;
-	} else if (rate >= 24000) {
-		return AST_FORMAT_SLINEAR24;
-	} else if (rate >= 16000) {
-		return AST_FORMAT_SLINEAR16;
-	} else if (rate >= 12000) {
-		return AST_FORMAT_SLINEAR12;
-	}
-	return AST_FORMAT_SLINEAR;
-}
-
 static void set_softmix_bridge_data(int rate, struct ast_bridge_channel *bridge_channel, int reset)
 {
 	struct softmix_channel *sc = bridge_channel->bridge_pvt;
@@ -152,7 +133,7 @@
 	/* Setup frame parameters */
 	sc->frame.frametype = AST_FRAME_VOICE;
 
-	ast_format_set(&sc->frame.subclass.format, slin_by_rate(rate), 0);
+	ast_format_set(&sc->frame.subclass.format, ast_format_slin_by_rate(rate), 0);
 	sc->frame.data.ptr = sc->final_buf;
 	sc->frame.datalen = SOFTMIX_DATALEN(rate);
 	sc->frame.samples = SOFTMIX_SAMPLES(rate);

Modified: team/dvossel/hd_conferencing_ftw/funcs/func_pitchshift.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_conferencing_ftw/funcs/func_pitchshift.c?view=diff&rev=307966&r1=307965&r2=307966
==============================================================================
--- team/dvossel/hd_conferencing_ftw/funcs/func_pitchshift.c (original)
+++ team/dvossel/hd_conferencing_ftw/funcs/func_pitchshift.c Tue Feb 15 16:24:20 2011
@@ -170,8 +170,7 @@
 	}
 	if ((audiohook->status == AST_AUDIOHOOK_STATUS_DONE) ||
 		(f->frametype != AST_FRAME_VOICE) ||
-		((f->subclass.format.id != AST_FORMAT_SLINEAR) &&
-		(f->subclass.format.id != AST_FORMAT_SLINEAR16))) {
+		!(ast_format_is_slinear(&f->subclass.format))) {
 		return -1;
 	}
 
@@ -209,7 +208,7 @@
 			return 0;
 		}
 
-		ast_audiohook_init(&shift->audiohook, AST_AUDIOHOOK_TYPE_MANIPULATE, "pitch_shift");
+		ast_audiohook_init(&shift->audiohook, AST_AUDIOHOOK_TYPE_MANIPULATE, "pitch_shift", AST_AUDIOHOOK_NATIVE_SLIN_CAPABLE);
 		shift->audiohook.manipulate_callback = pitchshift_cb;
 		datastore->data = shift;
 		new = 1;

Modified: team/dvossel/hd_conferencing_ftw/funcs/func_speex.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_conferencing_ftw/funcs/func_speex.c?view=diff&rev=307966&r1=307965&r2=307966
==============================================================================
--- team/dvossel/hd_conferencing_ftw/funcs/func_speex.c (original)
+++ team/dvossel/hd_conferencing_ftw/funcs/func_speex.c Tue Feb 15 16:24:20 2011
@@ -105,6 +105,7 @@
 
 struct speex_info {
 	struct ast_audiohook audiohook;
+	int lastrate;
 	struct speex_direction_info *tx, *rx;
 };
 
@@ -163,12 +164,13 @@
 		return -1;
 	}
 
-	if (sdi->samples != frame->samples) {
+	if ((sdi->samples != frame->samples) || (ast_format_rate(&frame->subclass.format) != si->lastrate)) {
+		si->lastrate = ast_format_rate(&frame->subclass.format);
 		if (sdi->state) {
 			speex_preprocess_state_destroy(sdi->state);
 		}
 
-		if (!(sdi->state = speex_preprocess_state_init((sdi->samples = frame->samples), 8000))) {
+		if (!(sdi->state = speex_preprocess_state_init((sdi->samples = frame->samples), si->lastrate))) {
 			return -1;
 		}
 
@@ -212,9 +214,9 @@
 			return 0;
 		}
 
-		ast_audiohook_init(&si->audiohook, AST_AUDIOHOOK_TYPE_MANIPULATE, "speex");
+		ast_audiohook_init(&si->audiohook, AST_AUDIOHOOK_TYPE_MANIPULATE, "speex", AST_AUDIOHOOK_NATIVE_SLIN_CAPABLE);
 		si->audiohook.manipulate_callback = speex_callback;
-
+		si->lastrate = 8000;
 		is_new = 1;
 	} else {
 		ast_channel_unlock(chan);

Modified: team/dvossel/hd_conferencing_ftw/funcs/func_volume.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_conferencing_ftw/funcs/func_volume.c?view=diff&rev=307966&r1=307965&r2=307966
==============================================================================
--- team/dvossel/hd_conferencing_ftw/funcs/func_volume.c (original)
+++ team/dvossel/hd_conferencing_ftw/funcs/func_volume.c Tue Feb 15 16:24:20 2011
@@ -132,7 +132,7 @@
 			ast_datastore_free(datastore);
 			return 0;
 		}
-		ast_audiohook_init(&vi->audiohook, AST_AUDIOHOOK_TYPE_MANIPULATE, "Volume");
+		ast_audiohook_init(&vi->audiohook, AST_AUDIOHOOK_TYPE_MANIPULATE, "Volume", 0);
 		vi->audiohook.manipulate_callback = volume_callback;
 		ast_set_flag(&vi->audiohook, AST_AUDIOHOOK_WANTS_DTMF);
 		is_new = 1;

Modified: team/dvossel/hd_conferencing_ftw/include/asterisk/audiohook.h
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_conferencing_ftw/include/asterisk/audiohook.h?view=diff&rev=307966&r1=307965&r2=307966
==============================================================================
--- team/dvossel/hd_conferencing_ftw/include/asterisk/audiohook.h (original)
+++ team/dvossel/hd_conferencing_ftw/include/asterisk/audiohook.h Tue Feb 15 16:24:20 2011
@@ -63,6 +63,11 @@
 	AST_AUDIOHOOK_SMALL_QUEUE = (1 << 3),
 	AST_AUDIOHOOK_MUTE_READ = (1 << 4),     /*!< audiohook should be mute frames read */
 	AST_AUDIOHOOK_MUTE_WRITE = (1 << 5),    /*!< audiohook should be mute frames written */
+};
+
+enum ast_audiohook_init_flags {
+	/* Audiohook is capable of handling slinear at any sample rate */
+	AST_AUDIOHOOK_NATIVE_SLIN_CAPABLE = (1 << 0),
 };
 
 #define AST_AUDIOHOOK_SYNC_TOLERANCE 100 /*< Tolerance in milliseconds for audiohooks synchronization */
@@ -97,6 +102,7 @@
 	ast_cond_t trigger;                                    /*!< Trigger condition (if enabled) */
 	enum ast_audiohook_type type;                          /*!< Type of audiohook */
 	enum ast_audiohook_status status;                      /*!< Status of the audiohook */
+	enum ast_audiohook_init_flags init_flags;              /*!< Init flags */
 	const char *source;                                    /*!< Who this audiohook ultimately belongs to */
 	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 */
@@ -116,9 +122,10 @@
  * \param audiohook Audiohook structure
  * \param type Type of audiohook to initialize this as
  * \param source Who is initializing this audiohook
- * \return Returns 0 on success, -1 on failure
- */
-int ast_audiohook_init(struct ast_audiohook *audiohook, enum ast_audiohook_type type, const char *source);
+ * \param init flags
+ * \return Returns 0 on success, -1 on failure
+ */
+int ast_audiohook_init(struct ast_audiohook *audiohook, enum ast_audiohook_type type, const char *source, enum ast_audiohook_init_flags flags);
 
 /*! \brief Destroys an audiohook structure
  * \param audiohook Audiohook structure

Modified: team/dvossel/hd_conferencing_ftw/include/asterisk/format.h
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_conferencing_ftw/include/asterisk/format.h?view=diff&rev=307966&r1=307965&r2=307966
==============================================================================
--- team/dvossel/hd_conferencing_ftw/include/asterisk/format.h (original)
+++ team/dvossel/hd_conferencing_ftw/include/asterisk/format.h Tue Feb 15 16:24:20 2011
@@ -451,4 +451,28 @@
 	return 0;
 }
 
+/*!
+ * \brief Get the best slinear format id for a given sample rate
+ */
+static force_inline enum ast_format_id ast_format_slin_by_rate(int rate) {
+	if (rate >= 192000) {
+		return AST_FORMAT_SLINEAR192;
+	} else if (rate >= 96000) {
+		return AST_FORMAT_SLINEAR96;
+	} else if (rate >= 48000) {
+		return AST_FORMAT_SLINEAR48;
+	} else if (rate >= 44100) {
+		return AST_FORMAT_SLINEAR44;
+	} else if (rate >= 32000) {
+		return AST_FORMAT_SLINEAR32;
+	} else if (rate >= 24000) {
+		return AST_FORMAT_SLINEAR24;
+	} else if (rate >= 16000) {
+		return AST_FORMAT_SLINEAR16;
+	} else if (rate >= 12000) {
+		return AST_FORMAT_SLINEAR12;
+	}
+	return AST_FORMAT_SLINEAR;
+}
+
 #endif /* _AST_FORMAT_H */

Modified: team/dvossel/hd_conferencing_ftw/main/audiohook.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_conferencing_ftw/main/audiohook.c?view=diff&rev=307966&r1=307965&r2=307966
==============================================================================
--- team/dvossel/hd_conferencing_ftw/main/audiohook.c (original)
+++ team/dvossel/hd_conferencing_ftw/main/audiohook.c Tue Feb 15 16:24:20 2011
@@ -44,6 +44,11 @@
 };
 
 struct ast_audiohook_list {
+	/* If all the audiohooks in this list are capable
+	 * of processing slinear at any sample rate, this
+	 * variable will be set and the sample rate will
+	 * be preserved during ast_audiohook_write_list()*/
+	int native_slin_compatible;
 	struct ast_audiohook_translate in_translate[2];
 	struct ast_audiohook_translate out_translate[2];
 	AST_LIST_HEAD_NOLOCK(, ast_audiohook) spy_list;
@@ -57,7 +62,7 @@
  * \param source
  * \return Returns 0 on success, -1 on failure
  */
-int ast_audiohook_init(struct ast_audiohook *audiohook, enum ast_audiohook_type type, const char *source)
+int ast_audiohook_init(struct ast_audiohook *audiohook, enum ast_audiohook_type type, const char *source, enum ast_audiohook_init_flags init_flags)
 {
 	/* Need to keep the type and source */
 	audiohook->type = type;
@@ -77,6 +82,8 @@
 	default:
 		break;
 	}
+
+	audiohook->init_flags = init_flags;
 
 	/* Since we are just starting out... this audiohook is new */
 	ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_NEW);
@@ -332,6 +339,30 @@
 	return final_frame;
 }
 
+static void audiohook_list_set_samplerate_compatibility(struct ast_audiohook_list *audiohook_list)
+{
+	struct ast_audiohook *ah = NULL;
+	audiohook_list->native_slin_compatible = 1;
+	AST_LIST_TRAVERSE(&audiohook_list->spy_list, ah, list) {
+		if (!(ah->init_flags & AST_AUDIOHOOK_NATIVE_SLIN_CAPABLE)) {
+			audiohook_list->native_slin_compatible = 0;
+			return;
+		}
+	}
+	AST_LIST_TRAVERSE(&audiohook_list->whisper_list, ah, list) {
+		if (!(ah->init_flags & AST_AUDIOHOOK_NATIVE_SLIN_CAPABLE)) {
+			audiohook_list->native_slin_compatible = 0;
+			return;
+		}
+	}
+	AST_LIST_TRAVERSE(&audiohook_list->manipulate_list, ah, list) {
+		if (!(ah->init_flags & AST_AUDIOHOOK_NATIVE_SLIN_CAPABLE)) {
+			audiohook_list->native_slin_compatible = 0;
+			return;
+		}
+	}
+}
+
 /*! \brief Attach audiohook to channel
  * \param chan Channel
  * \param audiohook Audiohook structure
@@ -359,6 +390,8 @@
 		AST_LIST_INSERT_TAIL(&chan->audiohooks->whisper_list, audiohook, list);
 	else if (audiohook->type == AST_AUDIOHOOK_TYPE_MANIPULATE)
 		AST_LIST_INSERT_TAIL(&chan->audiohooks->manipulate_list, audiohook, list);
+
+	audiohook_list_set_samplerate_compatibility(chan->audiohooks);
 
 	/* Change status over to running since it is now attached */
 	ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_RUNNING);
@@ -546,6 +579,7 @@
 	else if (audiohook->type == AST_AUDIOHOOK_TYPE_MANIPULATE)
 		AST_LIST_REMOVE(&chan->audiohooks->manipulate_list, audiohook, list);
 
+	audiohook_list_set_samplerate_compatibility(chan->audiohooks);
 	ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_DONE);
 
 	ast_channel_unlock(chan);
@@ -563,11 +597,13 @@
 static struct ast_frame *dtmf_audiohook_write_list(struct ast_channel *chan, struct ast_audiohook_list *audiohook_list, enum ast_audiohook_direction direction, struct ast_frame *frame)
 {
 	struct ast_audiohook *audiohook = NULL;
+	int removed = 0;
 
 	AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->manipulate_list, audiohook, list) {
 		ast_audiohook_lock(audiohook);
 		if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
 			AST_LIST_REMOVE_CURRENT(list);
+			removed = 1;
 			ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_DONE);
 			ast_audiohook_unlock(audiohook);
 			audiohook->manipulate_callback(audiohook, NULL, NULL, 0);
@@ -579,7 +615,66 @@
 	}
 	AST_LIST_TRAVERSE_SAFE_END;
 
+	/* if an audiohook got removed, reset samplerate compatibility */
+	if (removed) {
+		audiohook_list_set_samplerate_compatibility(audiohook_list);
+	}
 	return frame;
+}
+
+static struct ast_frame *audiohook_list_translate_to_slin(struct ast_audiohook_list *audiohook_list,
+	enum ast_audiohook_direction direction, struct ast_frame *frame)
+{
+	struct ast_audiohook_translate *in_translate = (direction == AST_AUDIOHOOK_DIRECTION_READ ?
+		&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;
+
+	if (frame->subclass.format.id == slin_id) {
+		return new_frame;
+	}
+
+	if (ast_format_cmp(&frame->subclass.format, &in_translate->format) == AST_FORMAT_CMP_NOT_EQUAL) {
+		if (in_translate->trans_pvt) {
+			ast_translator_free_path(in_translate->trans_pvt);
+		}
+		if (!(in_translate->trans_pvt = ast_translator_build_path(ast_format_set(&tmp_fmt, slin_id, 0), &frame->subclass.format))) {
+			return NULL;
+		}
+		ast_format_copy(&in_translate->format, &frame->subclass.format);
+	}
+	if (!(new_frame = ast_translate(in_translate->trans_pvt, frame, 0))) {
+		return NULL;
+	}
+
+	return new_frame;
+}
+
+static struct ast_frame *audiohook_list_translate_to_native(struct ast_audiohook_list *audiohook_list,
+	enum ast_audiohook_direction direction, struct ast_frame *slin_frame, struct ast_format *outformat)
+{
+	struct ast_audiohook_translate *out_translate = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook_list->out_translate[0] : &audiohook_list->out_translate[1]);
+	struct ast_frame *outframe = NULL;
+	if (ast_format_cmp(&slin_frame->subclass.format, outformat) == AST_FORMAT_CMP_NOT_EQUAL) {
+		/* rebuild translators if necessary */
+		if (ast_format_cmp(&out_translate->format, outformat) == AST_FORMAT_CMP_NOT_EQUAL) {
+			if (out_translate->trans_pvt) {
+				ast_translator_free_path(out_translate->trans_pvt);
+			}
+			if (!(out_translate->trans_pvt = ast_translator_build_path(outformat, &slin_frame->subclass.format))) {
+				return NULL;
+			}
+			ast_format_copy(&out_translate->format, outformat);
+		}
+		/* translate back to the format the frame came in as. */
+		if (!(outframe = ast_translate(out_translate->trans_pvt, slin_frame, 0))) {
+			return NULL;
+		}
+	}
+	return outframe;
 }
 
 /*!
@@ -613,27 +708,17 @@
  */
 static struct ast_frame *audio_audiohook_write_list(struct ast_channel *chan, struct ast_audiohook_list *audiohook_list, enum ast_audiohook_direction direction, struct ast_frame *frame)
 {
-	struct ast_audiohook_translate *in_translate = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook_list->in_translate[0] : &audiohook_list->in_translate[1]);
-	struct ast_audiohook_translate *out_translate = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook_list->out_translate[0] : &audiohook_list->out_translate[1]);
 	struct ast_frame *start_frame = frame, *middle_frame = frame, *end_frame = frame;
 	struct ast_audiohook *audiohook = NULL;
-	struct ast_format tmp_fmt;
-	int samples = frame->samples;
+	int samples;
+	int middle_frame_manipulated = 0;
+	int removed = 0;
 
 	/* ---Part_1. translate start_frame to SLINEAR if necessary. */
-	/* If the frame coming in is not signed linear we have to send it through the in_translate path */
-	if (frame->subclass.format.id != AST_FORMAT_SLINEAR) {
-		if (ast_format_cmp(&frame->subclass.format, &in_translate->format) == AST_FORMAT_CMP_NOT_EQUAL) {
-			if (in_translate->trans_pvt)
-				ast_translator_free_path(in_translate->trans_pvt);
-			if (!(in_translate->trans_pvt = ast_translator_build_path(ast_format_set(&tmp_fmt, AST_FORMAT_SLINEAR, 0), &frame->subclass.format)))
-				return frame;
-			ast_format_copy(&in_translate->format, &frame->subclass.format);
-		}
-		if (!(middle_frame = ast_translate(in_translate->trans_pvt, frame, 0)))
-			return frame;
-		samples = middle_frame->samples;
-	}
+	if (!(middle_frame = audiohook_list_translate_to_slin(audiohook_list, direction, frame))) {
+		return frame;
+	}
+	samples = middle_frame->samples;
 
 	/* ---Part_2: Send middle_frame to spy and manipulator lists.  middle_frame is guaranteed to be SLINEAR here.*/
 	/* Queue up signed linear frame to each spy */
@@ -641,6 +726,7 @@
 		ast_audiohook_lock(audiohook);
 		if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
 			AST_LIST_REMOVE_CURRENT(list);
+			removed = 1;
 			ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_DONE);
 			ast_audiohook_unlock(audiohook);
 			continue;
@@ -659,6 +745,7 @@
 			ast_audiohook_lock(audiohook);
 			if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
 				AST_LIST_REMOVE_CURRENT(list);
+				removed = 1;
 				ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_DONE);
 				ast_audiohook_unlock(audiohook);
 				continue;
@@ -672,9 +759,10 @@
 		}
 		AST_LIST_TRAVERSE_SAFE_END;
 		/* We take all of the combined whisper sources and combine them into the audio being written out */
-		for (i = 0, data1 = middle_frame->data.ptr, data2 = combine_buf; i < samples; i++, data1++, data2++)
+		for (i = 0, data1 = middle_frame->data.ptr, data2 = combine_buf; i < samples; i++, data1++, data2++) {
 			ast_slinear_saturated_add(data1, data2);
-		end_frame = middle_frame;
+		}
+		middle_frame_manipulated = 1;
 	}
 
 	/* Pass off frame to manipulate audiohooks */
@@ -683,6 +771,7 @@
 			ast_audiohook_lock(audiohook);
 			if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
 				AST_LIST_REMOVE_CURRENT(list);
+				removed = 1;
 				ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_DONE);
 				ast_audiohook_unlock(audiohook);
 				/* We basically drop all of our links to the manipulate audiohook and prod it to do it's own destructive things */
@@ -700,35 +789,27 @@
 			ast_audiohook_unlock(audiohook);
 		}
 		AST_LIST_TRAVERSE_SAFE_END;
-		end_frame = middle_frame;
-	}
+		middle_frame_manipulated = 1;
+	}
+
 
 	/* ---Part_3: Decide what to do with the end_frame (whether to transcode or not) */
-	if (middle_frame == end_frame) {
-		/* Middle frame was modified and became the end frame... let's see if we need to transcode */
-		if (ast_format_cmp(&end_frame->subclass.format, &start_frame->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
-			if (ast_format_cmp(&out_translate->format, &start_frame->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
-				if (out_translate->trans_pvt)
-					ast_translator_free_path(out_translate->trans_pvt);
-				if (!(out_translate->trans_pvt = ast_translator_build_path(&start_frame->subclass.format, ast_format_set(&tmp_fmt, AST_FORMAT_SLINEAR, 0)))) {
-					/* We can't transcode this... drop our middle frame and return the original */
-					ast_frfree(middle_frame);
-					return start_frame;
-				}
-				ast_format_copy(&out_translate->format, &start_frame->subclass.format);
-			}
-			/* Transcode from our middle (signed linear) frame to new format of the frame that came in */
-			if (!(end_frame = ast_translate(out_translate->trans_pvt, middle_frame, 0))) {
-				/* Failed to transcode the frame... drop it and return the original */
-				ast_frfree(middle_frame);
-				return start_frame;
-			}
-			/* Here's the scoop... middle frame is no longer of use to us */
-			ast_frfree(middle_frame);
+	if (middle_frame_manipulated) {
+		if (!(end_frame = audiohook_list_translate_to_native(audiohook_list, direction, middle_frame, &start_frame->subclass.format))) {
+			/* translation failed, so just pass back the input frame */
+			end_frame = start_frame;
 		}
 	} else {
-		/* No frame was modified, we can just drop our middle frame and pass the frame we got in out */
+		end_frame = start_frame;
+	}
+	/* clean up our middle_frame if required */
+	if (middle_frame != end_frame) {
 		ast_frfree(middle_frame);
+	}
+
+	/* Before returning, if an audiohook got removed, reset samplerate compatibility */
+	if (removed) {
+		audiohook_list_set_samplerate_compatibility(audiohook_list);
 	}
 
 	return end_frame;
@@ -956,7 +1037,7 @@
 	}
 
 	/* Setup our audiohook structure so we can manipulate the audio */
-	ast_audiohook_init(&audiohook_volume->audiohook, AST_AUDIOHOOK_TYPE_MANIPULATE, "Volume");
+	ast_audiohook_init(&audiohook_volume->audiohook, AST_AUDIOHOOK_TYPE_MANIPULATE, "Volume", AST_AUDIOHOOK_NATIVE_SLIN_CAPABLE);
 	audiohook_volume->audiohook.manipulate_callback = audiohook_volume_callback;
 
 	/* Attach the audiohook_volume blob to the datastore and attach to the channel */

Modified: team/dvossel/hd_conferencing_ftw/main/frame.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_conferencing_ftw/main/frame.c?view=diff&rev=307966&r1=307965&r2=307966
==============================================================================
--- team/dvossel/hd_conferencing_ftw/main/frame.c (original)
+++ team/dvossel/hd_conferencing_ftw/main/frame.c Tue Feb 15 16:24:20 2011
@@ -1075,7 +1075,7 @@
 	short *fdata = f->data.ptr;
 	short adjust_value = abs(adjustment);
 
-	if ((f->frametype != AST_FRAME_VOICE) || (f->subclass.format.id != AST_FORMAT_SLINEAR))
+	if ((f->frametype != AST_FRAME_VOICE) || !(ast_format_is_slinear(&f->subclass.format)))
 		return -1;
 
 	if (!adjustment)

Modified: team/dvossel/hd_conferencing_ftw/res/res_mutestream.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_conferencing_ftw/res/res_mutestream.c?view=diff&rev=307966&r1=307965&r2=307966
==============================================================================
--- team/dvossel/hd_conferencing_ftw/res/res_mutestream.c (original)
+++ team/dvossel/hd_conferencing_ftw/res/res_mutestream.c Tue Feb 15 16:24:20 2011
@@ -173,7 +173,7 @@
 		ast_datastore_free(datastore);
 		return NULL;
 	}
-	ast_audiohook_init(&mute->audiohook, AST_AUDIOHOOK_TYPE_MANIPULATE, "Mute");
+	ast_audiohook_init(&mute->audiohook, AST_AUDIOHOOK_TYPE_MANIPULATE, "Mute", 0);
 	mute->audiohook.manipulate_callback = mute_callback;
 	datastore->data = mute;
 	return datastore;




More information about the asterisk-commits mailing list