[asterisk-commits] file: branch file/ah r58882 - in /team/file/ah: include/asterisk/ main/

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Tue Mar 13 19:27:24 MST 2007


Author: file
Date: Tue Mar 13 21:27:23 2007
New Revision: 58882

URL: http://svn.digium.com/view/asterisk?view=rev&rev=58882
Log:
Use 1 API call for interfacing all types of audiohooks with the core's read/write functions.

Modified:
    team/file/ah/include/asterisk/audiohook.h
    team/file/ah/main/audiohook.c
    team/file/ah/main/channel.c

Modified: team/file/ah/include/asterisk/audiohook.h
URL: http://svn.digium.com/view/asterisk/team/file/ah/include/asterisk/audiohook.h?view=diff&rev=58882&r1=58881&r2=58882
==============================================================================
--- team/file/ah/include/asterisk/audiohook.h (original)
+++ team/file/ah/include/asterisk/audiohook.h Tue Mar 13 21:27:23 2007
@@ -120,27 +120,13 @@
  */
 int ast_audiohook_detach_list(struct ast_audiohook_list *audiohook_list);
 
-/*! \brief Writes a frame out to spies
- * \param list List of audiohooks
- * \param direction Direction the audio frame came from
- * \param frame Frame to write in
- * \return Returns 0 on success, -1 on failure
+/*! \brief Pass a frame off to be handled by the audiohook core
+ * \param audiohook_list List of audiohooks
+ * \param direction Direction frame is coming in from
+ * \param frame The frame itself
+ * \return Return frame on success, NULL on failure
  */
-int ast_audiohook_spy_write_frame(struct ast_audiohook_list *audiohook_list, enum ast_audiohook_direction direction, struct ast_frame *frame);
-
-/*! \brief Merges frame with data from whisper sources
- * \param list List of audiohooks
- * \param frame Frame to merge data into
- * \return Returns 0 on success, -1 on failure
- */
-int ast_audiohook_whisper_read_frame(struct ast_audiohook_list *audiohook_list, struct ast_frame *frame);
-
-/*! \brief Passes frame to manipulate audiohook to be modified
- * \param list List of audiohooks
- * \param frame Frame to be manipulated
- * \return Returns 0 on success, -1 on failure
- */
-int ast_audiohook_manipulate_frame(struct ast_audiohook_list *audiohook_list, struct ast_frame *frame);
+struct ast_frame *ast_audiohook_write_list(struct ast_audiohook_list *audiohook_list, enum ast_audiohook_direction direction, struct ast_frame *frame);
 
 /*! \brief Wait for audiohook trigger to be triggered
  * \param audiohook Audiohook to wait on

Modified: team/file/ah/main/audiohook.c
URL: http://svn.digium.com/view/asterisk/team/file/ah/main/audiohook.c?view=diff&rev=58882&r1=58881&r2=58882
==============================================================================
--- team/file/ah/main/audiohook.c (original)
+++ team/file/ah/main/audiohook.c Tue Mar 13 21:27:23 2007
@@ -45,7 +45,14 @@
 #include "asterisk/frame.h"
 #include "asterisk/translate.h"
 
+struct ast_audiohook_translate {
+	struct ast_trans_pvt *trans_pvt;
+	int format;
+};
+
 struct ast_audiohook_list {
+	struct ast_audiohook_translate in_translate[2];
+	struct ast_audiohook_translate out_translate[2];
 	AST_LIST_HEAD_NOLOCK(, ast_audiohook) spy_list;
 	AST_LIST_HEAD_NOLOCK(, ast_audiohook) whisper_list;
 	AST_LIST_HEAD_NOLOCK(, ast_audiohook) manipulate_list;
@@ -219,7 +226,7 @@
 				audiohook->trans_pvt = NULL;
 			}
 			/* 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(AST_FORMAT_SLINEAR, format))) {
+			if (!(audiohook->trans_pvt = ast_translator_build_path(format, AST_FORMAT_SLINEAR))) {
 				ast_frfree(read_frame);
 				return NULL;
 			}
@@ -327,17 +334,33 @@
 	return 0;
 }
 
-/*! \brief Writes a frame out to spies
- * \param list List of audiohooks
- * \param direction Direction the audio frame came from
- * \param frame Frame to write in
- * \return Returns 0 on success, -1 on failure
- */
-int ast_audiohook_spy_write_frame(struct ast_audiohook_list *audiohook_list, enum ast_audiohook_direction direction, struct ast_frame *frame)
-{
+/*! \brief Pass a frame off to be handled by the audiohook core
+ * \param audiohook_list List of audiohooks
+ * \param direction Direction frame is coming in from
+ * \param frame The frame itself
+ * \return Return frame on success, NULL on failure
+ */
+struct ast_frame *ast_audiohook_write_list(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;
-
-	/* Write out frame to each spy */
+	
+	/* If the frame coming in is not signed linear we have to send it through the in_translate path */
+	if (frame->subclass != AST_FORMAT_SLINEAR) {
+		if (in_translate->format != frame->subclass) {
+			if (in_translate->trans_pvt)
+				ast_translator_free_path(in_translate->trans_pvt);
+			if (!(in_translate->trans_pvt = ast_translator_build_path(AST_FORMAT_SLINEAR, frame->subclass)))
+				return frame;
+			in_translate->format = frame->subclass;
+		}
+		if (!(middle_frame = ast_translate(in_translate->trans_pvt, frame, 0)))
+			return frame;
+	}
+
+	/* Queue up signed linear frame to each spy */
 	AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->spy_list, audiohook, list) {
 		ast_mutex_lock(&audiohook->lock);
 		if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
@@ -347,64 +370,59 @@
 			ast_mutex_unlock(&audiohook->lock);
 			continue;
 		}
-		ast_audiohook_write_frame(audiohook, direction, frame);
+		ast_audiohook_write_frame(audiohook, direction, middle_frame);
 		ast_mutex_unlock(&audiohook->lock);
 	}
 	AST_LIST_TRAVERSE_SAFE_END
 
-	return 0;
-}
-
-/*! \brief Merges frame with data from whisper sources
- * \param list List of audiohooks
- * \param frame Frame to merge data into
- * \return Returns 0 on success, -1 on failure
- */
-int ast_audiohook_whisper_read_frame(struct ast_audiohook_list *audiohook_list, struct ast_frame *frame)
-{
-	struct ast_audiohook *audiohook = NULL;
-
-	AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->whisper_list, audiohook, list) {
-		ast_mutex_lock(&audiohook->lock);
-		/* If the audiohook wants to detach, let it go */
-		if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
-			AST_LIST_REMOVE_CURRENT(&audiohook_list->whisper_list, list);
-			audiohook->status = AST_AUDIOHOOK_STATUS_DONE;
-			ast_cond_signal(&audiohook->trigger);
+	/* If this frame is being written out to the channel then we need to use whisper sources */
+	if (direction == AST_AUDIOHOOK_DIRECTION_WRITE && !AST_LIST_EMPTY(&audiohook_list->whisper_list)) {
+		short read_buf[middle_frame->samples], combine_buf[middle_frame->samples];
+		/* Ensure our combined buffer is blank to begin with */
+		memset(&combine_buf, 0, sizeof(combine_buf));
+		AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->whisper_list, audiohook, list) {
+			ast_mutex_lock(&audiohook->lock);
+			if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
+				AST_LIST_REMOVE_CURRENT(&audiohook_list->whisper_list, list);
+				audiohook->status = AST_AUDIOHOOK_STATUS_DONE;
+				ast_cond_signal(&audiohook->trigger);
+				ast_mutex_unlock(&audiohook->lock);
+				continue;
+			}
+			if ((ast_slinfactory_available(&audiohook->write_factory) >= middle_frame->samples) && ast_slinfactory_read(&audiohook->write_factory, read_buf, frame->samples)) {
+			}
 			ast_mutex_unlock(&audiohook->lock);
-			continue;
-		}
-		ast_mutex_unlock(&audiohook->lock);
-	}
-	AST_LIST_TRAVERSE_SAFE_END
-
-	return 0;
-}
-
-/*! \brief Passes frame to manipulate audiohook to be modified
- * \param list List of audiohooks
- * \param frame Frame to be manipulated
- * \return Returns 0 on success, -1 on failure
- */
-int ast_audiohook_manipulate_frame(struct ast_audiohook_list *audiohook_list, struct ast_frame *frame)
-{
-	struct ast_audiohook *audiohook = NULL;
-
-	AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->manipulate_list, audiohook, list) {
-		ast_mutex_lock(&audiohook->lock);
-		/* If the audiohook wants to detach, let it go */
-		if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
-			AST_LIST_REMOVE_CURRENT(&audiohook_list->manipulate_list, list);
-			audiohook->status = AST_AUDIOHOOK_STATUS_DONE;
-			ast_cond_signal(&audiohook->trigger);
+		}
+		AST_LIST_TRAVERSE_SAFE_END
+		/* Now that we are done with the whisper sources, we take their combined values and combine them into our source frame */
+		end_frame = middle_frame;
+	}
+
+	/* Pass off frame to manipulate audiohooks */
+	if (!AST_LIST_EMPTY(&audiohook_list->manipulate_list)) {
+		AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->manipulate_list, audiohook, list) {
+			ast_mutex_lock(&audiohook->lock);
+			if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
+				AST_LIST_REMOVE_CURRENT(&audiohook_list->manipulate_list, list);
+				audiohook->status = AST_AUDIOHOOK_STATUS_DONE;
+				ast_cond_signal(&audiohook->trigger);
+				ast_mutex_unlock(&audiohook->lock);
+				continue;
+			}
 			ast_mutex_unlock(&audiohook->lock);
-			continue;
-		}
-		ast_mutex_unlock(&audiohook->lock);
-	}
-	AST_LIST_TRAVERSE_SAFE_END
-
-	return 0;
+		}
+		AST_LIST_TRAVERSE_SAFE_END
+		end_frame = middle_frame;
+	}
+
+	if (start_frame != end_frame) {
+		/* We are ending with a different frame then we started with... probably have to transcode */
+	}
+
+	/* We never ever need to keep the middle frame */
+	ast_frfree(middle_frame);
+
+	return end_frame;
 }
 
 /*! \brief Wait for audiohook trigger to be triggered

Modified: team/file/ah/main/channel.c
URL: http://svn.digium.com/view/asterisk/team/file/ah/main/channel.c?view=diff&rev=58882&r1=58881&r2=58882
==============================================================================
--- team/file/ah/main/channel.c (original)
+++ team/file/ah/main/channel.c Tue Mar 13 21:27:23 2007
@@ -1916,7 +1916,7 @@
 			} else {
 				/* Send frame to audiohooks if present */
 				if (chan->audiohooks)
-					ast_audiohook_spy_write_frame(chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
+					f = ast_audiohook_write_list(chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
 				if (chan->monitor && chan->monitor->read_stream ) {
 					/* XXX what does this do ? */
 #ifndef MONITOR_CONSTANT_DELAY
@@ -2308,7 +2308,7 @@
 
 		/* If audiohooks are present, write the frame out */
 		if (chan->audiohooks)
-			ast_audiohook_spy_write_frame(chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
+			fr = ast_audiohook_write_list(chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
 		
 		/* If the frame is in the raw write format, then it's easy... just use the frame - otherwise we will have to translate */
 		if (fr->subclass == chan->rawwriteformat)



More information about the asterisk-commits mailing list