[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