[asterisk-commits] file: branch file/audiohook-chains r116918 - in /team/file/audiohook-chains: ...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sat May 17 15:43:38 CDT 2008


Author: file
Date: Sat May 17 15:43:38 2008
New Revision: 116918

URL: http://svn.digium.com/view/asterisk?view=rev&rev=116918
Log:
Add chain based audiohooks. The audiohook can now specify whether it will be placed at the start or end of the chain.

Modified:
    team/file/audiohook-chains/include/asterisk/audiohook.h
    team/file/audiohook-chains/main/audiohook.c

Modified: team/file/audiohook-chains/include/asterisk/audiohook.h
URL: http://svn.digium.com/view/asterisk/team/file/audiohook-chains/include/asterisk/audiohook.h?view=diff&rev=116918&r1=116917&r2=116918
==============================================================================
--- team/file/audiohook-chains/include/asterisk/audiohook.h (original)
+++ team/file/audiohook-chains/include/asterisk/audiohook.h Sat May 17 15:43:38 2008
@@ -50,6 +50,12 @@
 	AST_AUDIOHOOK_DIRECTION_READ = 0, /*!< Reading audio in */
 	AST_AUDIOHOOK_DIRECTION_WRITE,    /*!< Writing audio out */
 	AST_AUDIOHOOK_DIRECTION_BOTH,     /*!< Both reading audio in and writing audio out */
+};
+
+enum ast_audiohook_position {
+	AST_AUDIOHOOK_POSITION_DEFAULT = 0, /*!< Place audiohook in the default position based on type */
+	AST_AUDIOHOOK_POSITION_START,       /*!< Place audiohook at start of chain */
+	AST_AUDIOHOOK_POSITION_END,         /*!< Place audiohook at end of chain */
 };
 
 enum ast_audiohook_flags {
@@ -93,6 +99,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 */
+	enum ast_audiohook_position position;                  /*!< Where the audiohook should be placed */
 	AST_LIST_ENTRY(ast_audiohook) list;                    /*!< Linked list information */
 };
 

Modified: team/file/audiohook-chains/main/audiohook.c
URL: http://svn.digium.com/view/asterisk/team/file/audiohook-chains/main/audiohook.c?view=diff&rev=116918&r1=116917&r2=116918
==============================================================================
--- team/file/audiohook-chains/main/audiohook.c (original)
+++ team/file/audiohook-chains/main/audiohook.c Sat May 17 15:43:38 2008
@@ -46,9 +46,7 @@
 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;
+	AST_LIST_HEAD_NOLOCK(, ast_audiohook) chain;
 };
 
 /*! \brief Initialize an audiohook structure
@@ -313,6 +311,15 @@
  */
 int ast_audiohook_attach(struct ast_channel *chan, struct ast_audiohook *audiohook)
 {
+	/* If the default position has been chosen then see where it should be placed based on type */
+	if (audiohook->position == AST_AUDIOHOOK_POSITION_DEFAULT) {
+		if (audiohook->type == AST_AUDIOHOOK_TYPE_SPY || audiohook->type == AST_AUDIOHOOK_TYPE_WHISPER) {
+			audiohook->position = AST_AUDIOHOOK_POSITION_START;
+		} else if (audiohook->type == AST_AUDIOHOOK_TYPE_MANIPULATE) {
+			audiohook->position = AST_AUDIOHOOK_POSITION_END;
+		}
+	}
+
 	ast_channel_lock(chan);
 
 	if (!chan->audiohooks) {
@@ -321,18 +328,15 @@
 			ast_channel_unlock(chan);
 			return -1;
 		}
-		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);
-	}
-
-	/* Drop into respective list */
-	if (audiohook->type == AST_AUDIOHOOK_TYPE_SPY)
-		AST_LIST_INSERT_TAIL(&chan->audiohooks->spy_list, audiohook, list);
-	else if (audiohook->type == AST_AUDIOHOOK_TYPE_WHISPER)
-		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);
+		AST_LIST_HEAD_INIT_NOLOCK(&chan->audiohooks->chain);
+	}
+
+	/* Depending on the position either add it to the head or tail */
+	if (audiohook->position == AST_AUDIOHOOK_POSITION_START) {
+		AST_LIST_INSERT_HEAD(&chan->audiohooks->chain, audiohook, list);
+	} else if (audiohook->position == AST_AUDIOHOOK_POSITION_END) {
+		AST_LIST_INSERT_TAIL(&chan->audiohooks->chain, audiohook, list);
+	}
 
 	/* Change status over to running since it is now attached */
 	audiohook->status = AST_AUDIOHOOK_STATUS_RUNNING;
@@ -368,28 +372,15 @@
 	int i = 0;
 	struct ast_audiohook *audiohook = NULL;
 
-	/* Drop any spies */
-	while ((audiohook = AST_LIST_REMOVE_HEAD(&audiohook_list->spy_list, list))) {
+	/* Drop every audiohook from the chain */
+	while ((audiohook = AST_LIST_REMOVE_HEAD(&audiohook_list->chain, list))) {
 		ast_audiohook_lock(audiohook);
 		audiohook->status = AST_AUDIOHOOK_STATUS_DONE;
 		ast_cond_signal(&audiohook->trigger);
 		ast_audiohook_unlock(audiohook);
-	}
-
-	/* Drop any whispering sources */
-	while ((audiohook = AST_LIST_REMOVE_HEAD(&audiohook_list->whisper_list, list))) {
-		ast_audiohook_lock(audiohook);
-		audiohook->status = AST_AUDIOHOOK_STATUS_DONE;
-		ast_cond_signal(&audiohook->trigger);
-		ast_audiohook_unlock(audiohook);
-	}
-
-	/* Drop any manipulaters */
-	while ((audiohook = AST_LIST_REMOVE_HEAD(&audiohook_list->manipulate_list, list))) {
-		ast_audiohook_lock(audiohook);
-		audiohook->status = AST_AUDIOHOOK_STATUS_DONE;
-		ast_audiohook_unlock(audiohook);
-		audiohook->manipulate_callback(audiohook, NULL, NULL, 0);
+		if (audiohook->type == AST_AUDIOHOOK_TYPE_MANIPULATE) {
+			audiohook->manipulate_callback(audiohook, NULL, NULL, 0);
+		}
 	}
 
 	/* Drop translation paths if present */
@@ -410,19 +401,10 @@
 {
 	struct ast_audiohook *audiohook = NULL;
 
-	AST_LIST_TRAVERSE(&audiohook_list->spy_list, audiohook, list) {
-		if (!strcasecmp(audiohook->source, source))
+	AST_LIST_TRAVERSE(&audiohook_list->chain, audiohook, list) {
+		if (!strcasecmp(audiohook->source, source)) {
 			return audiohook;
-	}
-
-	AST_LIST_TRAVERSE(&audiohook_list->whisper_list, audiohook, list) {
-		if (!strcasecmp(audiohook->source, source))
-			return audiohook;
-	}
-
-	AST_LIST_TRAVERSE(&audiohook_list->manipulate_list, audiohook, list) {
-		if (!strcasecmp(audiohook->source, source))
-			return audiohook;
+		}
 	}
 
 	return NULL;
@@ -474,12 +456,7 @@
 		return -1;
 	}
 
-	if (audiohook->type == AST_AUDIOHOOK_TYPE_SPY)
-		AST_LIST_REMOVE(&chan->audiohooks->spy_list, audiohook, list);
-	else if (audiohook->type == AST_AUDIOHOOK_TYPE_WHISPER)
-		AST_LIST_REMOVE(&chan->audiohooks->whisper_list, audiohook, list);
-	else if (audiohook->type == AST_AUDIOHOOK_TYPE_MANIPULATE)
-		AST_LIST_REMOVE(&chan->audiohooks->manipulate_list, audiohook, list);
+	AST_LIST_REMOVE(&chan->audiohooks->chain, audiohook, list);
 
 	ast_audiohook_lock(audiohook);
 	audiohook->status = AST_AUDIOHOOK_STATUS_DONE;
@@ -502,7 +479,11 @@
 {
 	struct ast_audiohook *audiohook = NULL;
 
-	AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->manipulate_list, audiohook, list) {
+	AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->chain, audiohook, list) {
+		if (audiohook->type != AST_AUDIOHOOK_TYPE_MANIPULATE) {
+			continue;
+		}
+
 		ast_audiohook_lock(audiohook);
 		if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
 			AST_LIST_REMOVE_CURRENT(list);
@@ -548,68 +529,47 @@
 			return frame;
 	}
 
-	/* Queue up signed linear frame to each spy */
-	AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->spy_list, audiohook, list) {
+	/* Iterate through the chain of audiohooks */
+	AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->chain, audiohook, list) {
 		ast_audiohook_lock(audiohook);
+
+		/* If the audiohook wants to be detached then do it */
 		if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
 			AST_LIST_REMOVE_CURRENT(list);
 			audiohook->status = AST_AUDIOHOOK_STATUS_DONE;
 			ast_cond_signal(&audiohook->trigger);
 			ast_audiohook_unlock(audiohook);
+			if (audiohook->type == AST_AUDIOHOOK_TYPE_MANIPULATE) {
+				audiohook->manipulate_callback(audiohook, NULL, NULL, 0);
+			}
 			continue;
 		}
-		ast_audiohook_write_frame(audiohook, direction, middle_frame);
+
+		if (audiohook->type == AST_AUDIOHOOK_TYPE_SPY) {
+			/* If this is a spy we simply write the frame of audio out */
+			ast_audiohook_write_frame(audiohook, direction, middle_frame);
+		} else if (audiohook->type == AST_AUDIOHOOK_TYPE_WHISPER && direction == AST_AUDIOHOOK_DIRECTION_WRITE) {
+			short read_buf[samples];
+
+			/* Read in audio from the whisper source and combine it with the current frame */
+			if (ast_slinfactory_available(&audiohook->write_factory) >= samples && ast_slinfactory_read(&audiohook->write_factory, read_buf, samples)) {
+				int i = 0;
+				short *data1 = middle_frame->data, *data2 = read_buf;
+
+				for (i = 0; i < samples; i++, data1++, data2++) {
+					ast_slinear_saturated_add(data1, data2);
+				}
+
+				end_frame = middle_frame;
+			}
+		} else if (audiohook->type == AST_AUDIOHOOK_TYPE_MANIPULATE) {
+			audiohook->manipulate_callback(audiohook, chan, middle_frame, direction);
+			end_frame = middle_frame;
+		}
+
 		ast_audiohook_unlock(audiohook);
 	}
-	AST_LIST_TRAVERSE_SAFE_END
-
-	/* 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)) {
-		int i = 0;
-		short read_buf[samples], combine_buf[samples], *data1 = NULL, *data2 = NULL;
-		memset(&combine_buf, 0, sizeof(combine_buf));
-		AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->whisper_list, audiohook, list) {
-			ast_audiohook_lock(audiohook);
-			if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
-				AST_LIST_REMOVE_CURRENT(list);
-				audiohook->status = AST_AUDIOHOOK_STATUS_DONE;
-				ast_cond_signal(&audiohook->trigger);
-				ast_audiohook_unlock(audiohook);
-				continue;
-			}
-			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++)
-					ast_slinear_saturated_add(data1, data2);
-			}
-			ast_audiohook_unlock(audiohook);
-		}
-		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, data2 = combine_buf; i < samples; i++, data1++, data2++)
-			ast_slinear_saturated_add(data1, data2);
-		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_audiohook_lock(audiohook);
-			if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
-				AST_LIST_REMOVE_CURRENT(list);
-				audiohook->status = 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 */
-				audiohook->manipulate_callback(audiohook, chan, NULL, direction);
-				continue;
-			}
-			/* Feed in frame to manipulation */
-			audiohook->manipulate_callback(audiohook, chan, middle_frame, direction);
-			ast_audiohook_unlock(audiohook);
-		}
-		AST_LIST_TRAVERSE_SAFE_END
-		end_frame = middle_frame;
-	}
+	AST_LIST_TRAVERSE_SAFE_END;
 
 	/* Now we figure out what to do with our end frame (whether to transcode or not) */
 	if (middle_frame == end_frame) {
@@ -682,39 +642,16 @@
 int ast_channel_audiohook_count_by_source(struct ast_channel *chan, const char *source, enum ast_audiohook_type type)
 {
 	int count = 0;
-	struct ast_audiohook *ah = NULL;
-
-	if (!chan->audiohooks)
+	struct ast_audiohook *audiohook = NULL;
+
+	if (!chan->audiohooks) {
 		return -1;
-
-	switch (type) {
-		case AST_AUDIOHOOK_TYPE_SPY:
-			AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->audiohooks->spy_list, ah, list) {
-				if (!strcmp(ah->source, source)) {
-					count++;
-				}
-			}
-			AST_LIST_TRAVERSE_SAFE_END;
-			break;
-		case AST_AUDIOHOOK_TYPE_WHISPER:
-			AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->audiohooks->whisper_list, ah, list) {
-				if (!strcmp(ah->source, source)) {
-					count++;
-				}
-			}
-			AST_LIST_TRAVERSE_SAFE_END;
-			break;
-		case AST_AUDIOHOOK_TYPE_MANIPULATE:
-			AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->audiohooks->manipulate_list, ah, list) {
-				if (!strcmp(ah->source, source)) {
-					count++;
-				}
-			}
-			AST_LIST_TRAVERSE_SAFE_END;
-			break;
-		default:
-			ast_log(LOG_DEBUG, "Invalid audiohook type supplied, (%d)\n", type);
-			return -1;
+	}
+
+	AST_LIST_TRAVERSE(&chan->audiohooks->chain, audiohook, list) {
+		if (audiohook->type == type && !strcmp(audiohook->source, source)) {
+			count++;
+		}
 	}
 
 	return count;
@@ -724,36 +661,18 @@
 int ast_channel_audiohook_count_by_source_running(struct ast_channel *chan, const char *source, enum ast_audiohook_type type)
 {
 	int count = 0;
-	struct ast_audiohook *ah = NULL;
-	if (!chan->audiohooks)
+	struct ast_audiohook *audiohook = NULL;
+
+	if (!chan->audiohooks) {
 		return -1;
-
-	switch (type) {
-		case AST_AUDIOHOOK_TYPE_SPY:
-			AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->audiohooks->spy_list, ah, list) {
-				if ((!strcmp(ah->source, source)) && (ah->status == AST_AUDIOHOOK_STATUS_RUNNING))
-					count++;
-			}
-			AST_LIST_TRAVERSE_SAFE_END;
-			break;
-		case AST_AUDIOHOOK_TYPE_WHISPER:
-			AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->audiohooks->whisper_list, ah, list) {
-				if ((!strcmp(ah->source, source)) && (ah->status == AST_AUDIOHOOK_STATUS_RUNNING))
-					count++;
-			}
-			AST_LIST_TRAVERSE_SAFE_END;
-			break;
-		case AST_AUDIOHOOK_TYPE_MANIPULATE:
-			AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->audiohooks->manipulate_list, ah, list) {
-				if ((!strcmp(ah->source, source)) && (ah->status == AST_AUDIOHOOK_STATUS_RUNNING))
-					count++;
-			}
-			AST_LIST_TRAVERSE_SAFE_END;
-			break;
-		default:
-			ast_log(LOG_DEBUG, "Invalid audiohook type supplied, (%d)\n", type);
-			return -1;
-	}
+	}
+
+	AST_LIST_TRAVERSE(&chan->audiohooks->chain, audiohook, list) {
+		if (audiohook->type == type && !strcmp(audiohook->source, source) && audiohook->status == AST_AUDIOHOOK_STATUS_RUNNING) {
+			count++;
+		}
+	}
+
 	return count;
 }
 




More information about the asterisk-commits mailing list