[svn-commits] file: branch file/ah r59060 - in /team/file/ah: apps/
include/asterisk/ main/
svn-commits at lists.digium.com
svn-commits at lists.digium.com
Mon Mar 19 20:44:56 MST 2007
Author: file
Date: Mon Mar 19 22:44:56 2007
New Revision: 59060
URL: http://svn.digium.com/view/asterisk?view=rev&rev=59060
Log:
Add support for whispering.
Modified:
team/file/ah/apps/app_chanspy.c
team/file/ah/apps/app_mixmonitor.c
team/file/ah/include/asterisk/audiohook.h
team/file/ah/main/audiohook.c
Modified: team/file/ah/apps/app_chanspy.c
URL: http://svn.digium.com/view/asterisk/team/file/ah/apps/app_chanspy.c?view=diff&rev=59060&r1=59059&r2=59060
==============================================================================
--- team/file/ah/apps/app_chanspy.c (original)
+++ team/file/ah/apps/app_chanspy.c Mon Mar 19 22:44:56 2007
@@ -166,7 +166,8 @@
struct chanspy_translation_helper {
/* spy data */
- struct ast_audiohook audiohook;
+ struct ast_audiohook spy_audiohook;
+ struct ast_audiohook whisper_audiohook;
int fd;
int volfactor;
};
@@ -187,16 +188,16 @@
struct chanspy_translation_helper *csth = data;
struct ast_frame *f = NULL;
- ast_mutex_lock(&csth->audiohook.lock);
- if (csth->audiohook.status != AST_AUDIOHOOK_STATUS_RUNNING) {
+ ast_audiohook_lock(&csth->spy_audiohook);
+ if (csth->spy_audiohook.status != AST_AUDIOHOOK_STATUS_RUNNING) {
/* Channel is already gone more than likely */
- ast_mutex_unlock(&csth->audiohook.lock);
+ ast_audiohook_unlock(&csth->spy_audiohook);
return -1;
}
- f = ast_audiohook_read_frame(&csth->audiohook, samples, AST_AUDIOHOOK_DIRECTION_BOTH, AST_FORMAT_SLINEAR);
-
- ast_mutex_unlock(&csth->audiohook.lock);
+ f = ast_audiohook_read_frame(&csth->spy_audiohook, samples, AST_AUDIOHOOK_DIRECTION_BOTH, AST_FORMAT_SLINEAR);
+
+ ast_audiohook_unlock(&csth->spy_audiohook);
if (!f)
return 0;
@@ -254,11 +255,16 @@
memset(&csth, 0, sizeof(csth));
- ast_audiohook_init(&csth.audiohook, AST_AUDIOHOOK_TYPE_SPY, "ChanSpy");
+ ast_audiohook_init(&csth.spy_audiohook, AST_AUDIOHOOK_TYPE_SPY, "ChanSpy");
- if (start_spying(spyee, chan, &csth.audiohook)) {
- ast_audiohook_destroy(&csth.audiohook);
+ if (start_spying(spyee, chan, &csth.spy_audiohook)) {
+ ast_audiohook_destroy(&csth.spy_audiohook);
return 0;
+ }
+
+ if (ast_test_flag(flags, OPTION_WHISPER)) {
+ ast_audiohook_init(&csth.whisper_audiohook, AST_AUDIOHOOK_TYPE_WHISPER, "ChanSpy");
+ start_spying(spyee, chan, &csth.whisper_audiohook);
}
if (ast_test_flag(flags, OPTION_PRIVATE))
@@ -280,10 +286,18 @@
has arrived, since the spied-on channel could have gone away while
we were waiting
*/
- while ((res = ast_waitfor(chan, -1) > -1) && csth.audiohook.status == AST_AUDIOHOOK_STATUS_RUNNING) {
+ while ((res = ast_waitfor(chan, -1) > -1) && csth.spy_audiohook.status == AST_AUDIOHOOK_STATUS_RUNNING) {
if (!(f = ast_read(chan)) || ast_check_hangup(chan)) {
running = -1;
break;
+ }
+
+ if (ast_test_flag(flags, OPTION_WHISPER) && f->frametype == AST_FRAME_VOICE) {
+ ast_audiohook_lock(&csth.whisper_audiohook);
+ ast_audiohook_write_frame(&csth.whisper_audiohook, AST_AUDIOHOOK_DIRECTION_WRITE, f);
+ ast_audiohook_unlock(&csth.whisper_audiohook);
+ ast_frfree(f);
+ continue;
}
res = (f->frametype == AST_FRAME_DTMF) ? f->subclass : 0;
@@ -337,12 +351,17 @@
else
ast_deactivate_generator(chan);
- ast_mutex_lock(&csth.audiohook.lock);
- ast_audiohook_detach(&csth.audiohook);
- ast_mutex_unlock(&csth.audiohook.lock);
-
- /* If a channel still exists on our spy structure then we need to remove ourselves */
- ast_audiohook_destroy(&csth.audiohook);
+ if (ast_test_flag(flags, OPTION_WHISPER)) {
+ ast_audiohook_lock(&csth.whisper_audiohook);
+ ast_audiohook_detach(&csth.whisper_audiohook);
+ ast_audiohook_unlock(&csth.whisper_audiohook);
+ ast_audiohook_destroy(&csth.whisper_audiohook);
+ }
+
+ ast_audiohook_lock(&csth.spy_audiohook);
+ ast_audiohook_detach(&csth.spy_audiohook);
+ ast_audiohook_unlock(&csth.spy_audiohook);
+ ast_audiohook_destroy(&csth.spy_audiohook);
if (option_verbose >= 2)
ast_verbose(VERBOSE_PREFIX_2 "Done Spying on channel %s\n", name);
Modified: team/file/ah/apps/app_mixmonitor.c
URL: http://svn.digium.com/view/asterisk/team/file/ah/apps/app_mixmonitor.c?view=diff&rev=59060&r1=59059&r2=59060
==============================================================================
--- team/file/ah/apps/app_mixmonitor.c (original)
+++ team/file/ah/apps/app_mixmonitor.c Mon Mar 19 22:44:56 2007
@@ -152,7 +152,7 @@
if (option_verbose > 1)
ast_verbose(VERBOSE_PREFIX_2 "Begin MixMonitor Recording %s\n", mixmonitor->name);
- ast_mutex_lock(&mixmonitor->audiohook.lock);
+ ast_audiohook_lock(&mixmonitor->audiohook);
while (mixmonitor->audiohook.status == AST_AUDIOHOOK_STATUS_RUNNING) {
struct ast_frame *fr = NULL;
@@ -191,9 +191,7 @@
}
ast_audiohook_detach(&mixmonitor->audiohook);
-
- ast_mutex_unlock(&mixmonitor->audiohook.lock);
-
+ ast_audiohook_unlock(&mixmonitor->audiohook);
ast_audiohook_destroy(&mixmonitor->audiohook);
if (option_verbose > 1)
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=59060&r1=59059&r2=59060
==============================================================================
--- team/file/ah/include/asterisk/audiohook.h (original)
+++ team/file/ah/include/asterisk/audiohook.h Mon Mar 19 22:44:56 2007
@@ -133,6 +133,22 @@
*/
void ast_audiohook_trigger_wait(struct ast_audiohook *audiohook);
+/*! \brief Lock an audiohook
+ * \param audiohook Audiohook structure
+ */
+static inline int ast_audiohook_lock(struct ast_audiohook *audiohook)
+{
+ return ast_mutex_lock(&audiohook->lock);
+}
+
+/*! \brief Unlock an audiohook
+ * \param audiohook Audiohook structure
+ */
+static inline int ast_audiohook_unlock(struct ast_audiohook *audiohook)
+{
+ return ast_mutex_unlock(&audiohook->lock);
+}
+
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
Modified: team/file/ah/main/audiohook.c
URL: http://svn.digium.com/view/asterisk/team/file/ah/main/audiohook.c?view=diff&rev=59060&r1=59059&r2=59060
==============================================================================
--- team/file/ah/main/audiohook.c (original)
+++ team/file/ah/main/audiohook.c Mon Mar 19 22:44:56 2007
@@ -301,31 +301,32 @@
/* Drop any spies */
AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->spy_list, audiohook, list) {
- ast_mutex_lock(&audiohook->lock);
+ ast_audiohook_lock(audiohook);
AST_LIST_REMOVE_CURRENT(&audiohook_list->spy_list, list);
audiohook->status = AST_AUDIOHOOK_STATUS_DONE;
ast_cond_signal(&audiohook->trigger);
- ast_mutex_unlock(&audiohook->lock);
+ ast_audiohook_unlock(audiohook);
}
AST_LIST_TRAVERSE_SAFE_END
/* Drop any whispering sources */
AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->whisper_list, audiohook, list) {
- ast_mutex_lock(&audiohook->lock);
+ ast_audiohook_lock(audiohook);
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);
+ ast_audiohook_unlock(audiohook);
}
AST_LIST_TRAVERSE_SAFE_END
/* Drop any manipulaters */
AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->manipulate_list, audiohook, list) {
+ ast_audiohook_lock(audiohook);
ast_mutex_lock(&audiohook->lock);
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);
+ ast_audiohook_unlock(audiohook);
}
AST_LIST_TRAVERSE_SAFE_END
@@ -352,9 +353,10 @@
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_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;
+ int samples = frame->samples;
/* 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) {
@@ -371,65 +373,93 @@
/* Queue up signed linear frame to each spy */
AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->spy_list, audiohook, list) {
- ast_mutex_lock(&audiohook->lock);
+ ast_audiohook_lock(audiohook);
if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
AST_LIST_REMOVE_CURRENT(&audiohook_list->spy_list, list);
audiohook->status = AST_AUDIOHOOK_STATUS_DONE;
ast_cond_signal(&audiohook->trigger);
- ast_mutex_unlock(&audiohook->lock);
+ ast_audiohook_unlock(audiohook);
continue;
}
ast_audiohook_write_frame(audiohook, direction, middle_frame);
- ast_mutex_unlock(&audiohook->lock);
+ 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)) {
- short read_buf[middle_frame->samples], combine_buf[middle_frame->samples];
- /* Ensure our combined buffer is blank to begin with */
+ 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_mutex_lock(&audiohook->lock);
+ ast_audiohook_lock(audiohook);
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);
+ ast_audiohook_unlock(audiohook);
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);
+ 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
- /* Now that we are done with the whisper sources, we take their combined values and combine them into our source frame */
+ /* 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_mutex_lock(&audiohook->lock);
+ ast_audiohook_lock(audiohook);
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);
+ ast_audiohook_unlock(audiohook);
continue;
}
- ast_mutex_unlock(&audiohook->lock);
+ ast_audiohook_unlock(audiohook);
}
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);
+ /* Now we figure out what to do with our 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 (end_frame->subclass != start_frame->subclass) {
+ if (out_translate->format != start_frame->subclass) {
+ 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, AST_FORMAT_SLINEAR))) {
+ /* We can't transcode this... drop our middle frame and return the original */
+ ast_frfree(middle_frame);
+ return start_frame;
+ }
+ out_translate->format = start_frame->subclass;
+ }
+ /* 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);
+ }
+ /* Yay let's rid ourselves of the start frame */
+ ast_frfree(start_frame);
+ } else {
+ /* No frame was modified, we can just drop our middle frame and pass the frame we got in out */
+ ast_frfree(middle_frame);
+ }
return end_frame;
}
More information about the svn-commits
mailing list