[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