[asterisk-commits] dvossel: branch dvossel/hd_confbridge r310133 - in /team/dvossel/hd_confbridg...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Mar 8 15:32:31 CST 2011
Author: dvossel
Date: Tue Mar 8 15:32:24 2011
New Revision: 310133
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=310133
Log:
Addition of the 'drop_silence' ConfBridge option for removing silence from mixing
Modified:
team/dvossel/hd_confbridge/apps/app_confbridge.c
team/dvossel/hd_confbridge/apps/confbridge/conf_config_parser.c
team/dvossel/hd_confbridge/apps/confbridge/include/confbridge.h
team/dvossel/hd_confbridge/configs/confbridge.conf.sample
team/dvossel/hd_confbridge/include/asterisk/bridging.h
team/dvossel/hd_confbridge/include/asterisk/bridging_features.h
team/dvossel/hd_confbridge/include/asterisk/dsp.h
team/dvossel/hd_confbridge/main/bridging.c
team/dvossel/hd_confbridge/main/dsp.c
Modified: team/dvossel/hd_confbridge/apps/app_confbridge.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/apps/app_confbridge.c?view=diff&rev=310133&r1=310132&r2=310133
==============================================================================
--- team/dvossel/hd_confbridge/apps/app_confbridge.c (original)
+++ team/dvossel/hd_confbridge/apps/app_confbridge.c Tue Mar 8 15:32:24 2011
@@ -608,9 +608,13 @@
volume_adjustments[0] = ast_audiohook_volume_get(chan, AST_AUDIOHOOK_DIRECTION_READ);
volume_adjustments[1] = ast_audiohook_volume_get(chan, AST_AUDIOHOOK_DIRECTION_WRITE);
- /* If the caller should be joined already muted, make it so */
+ /* If the caller should be joined already muted, make it so */
if (ast_test_flag(&conference_bridge_user.u_profile, USER_OPT_STARTMUTED)) {
conference_bridge_user.features.mute = 1;
+ }
+
+ if (conference_bridge_user.u_profile.drop_silence) {
+ conference_bridge_user.features.detect_silence = conference_bridge_user.u_profile.drop_silence;
}
/* Grab join/leave sounds from the channel */
Modified: team/dvossel/hd_confbridge/apps/confbridge/conf_config_parser.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/apps/confbridge/conf_config_parser.c?view=diff&rev=310133&r1=310132&r2=310133
==============================================================================
--- team/dvossel/hd_confbridge/apps/confbridge/conf_config_parser.c (original)
+++ team/dvossel/hd_confbridge/apps/confbridge/conf_config_parser.c Tue Mar 8 15:32:24 2011
@@ -35,6 +35,8 @@
#define CONF_CONFIG "confbridge.conf"
+#define DEFAULT_SILENCE_THRESHOLD 3000 /* ms of silence before audio is dropped from mixing */
+
static struct ao2_container *user_profiles;
static struct ao2_container *bridge_profiles;
static struct ao2_container *menus;
@@ -184,6 +186,7 @@
ao2_lock(u_profile);
/* set defaults */
u_profile->flags = 0;
+ u_profile->drop_silence = 0;
for (var = ast_variable_browse(cfg, cat); var; var = var->next) {
if (!strcasecmp(var->name, "type")) {
continue;
@@ -219,6 +222,15 @@
u_profile->flags = ast_true(var->value) ?
u_profile->flags | USER_OPT_WAITMARKED :
u_profile->flags & ~USER_OPT_WAITMARKED;
+ } else if (!strcasecmp(var->name, "drop_silence")) {
+ if (ast_true(var->value)) {
+ u_profile->drop_silence = DEFAULT_SILENCE_THRESHOLD;
+ } else if (ast_false(var->value)) {
+ u_profile->drop_silence = 0;
+ } else if (sscanf(var->value, "%30u", &u_profile->drop_silence) != 1) {
+ ast_log(LOG_WARNING, "drop_silence '%s' at line %d of %s is not supported.\n",
+ var->value, var->lineno, CONF_CONFIG);
+ }
} else {
ast_log(LOG_WARNING, "Unknown option '%s' at line %d of %s is not supported.\n",
var->name, var->lineno, CONF_CONFIG);
@@ -418,6 +430,12 @@
ast_cli(a->fd,"Wait Marked: %s\n",
u_profile.flags & USER_OPT_WAITMARKED ?
"enabled" : "disabled");
+ if (u_profile.drop_silence) {
+ ast_cli(a->fd,"Drop Silence: %dms\n",
+ u_profile.drop_silence);
+ } else {
+ ast_cli(a->fd,"Drop Silence: disabled\n");
+ }
ast_cli(a->fd,"\n");
return CLI_SUCCESS;
Modified: team/dvossel/hd_confbridge/apps/confbridge/include/confbridge.h
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/apps/confbridge/include/confbridge.h?view=diff&rev=310133&r1=310132&r2=310133
==============================================================================
--- team/dvossel/hd_confbridge/apps/confbridge/include/confbridge.h (original)
+++ team/dvossel/hd_confbridge/apps/confbridge/include/confbridge.h Tue Mar 8 15:32:24 2011
@@ -85,6 +85,7 @@
struct user_profile {
char name[64];
unsigned int flags;
+ unsigned int drop_silence; /*!< Number of ms of silence before dropping audio. If 0, never drop silence. */
int delme;
};
Modified: team/dvossel/hd_confbridge/configs/confbridge.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/configs/confbridge.conf.sample?view=diff&rev=310133&r1=310132&r2=310133
==============================================================================
--- team/dvossel/hd_confbridge/configs/confbridge.conf.sample (original)
+++ team/dvossel/hd_confbridge/configs/confbridge.conf.sample Tue Mar 8 15:32:24 2011
@@ -20,8 +20,19 @@
; caller. Off by default.
;announce_only_user=yes ; Sets if the only user announcement should be played
; when a channel enters a empty conference. On by default.
-;wait_marked=yes ; Sets if the user must wait for a marked user to enter before
- ; joining the conference. Off by default
+;wait_marked=yes ; Sets if the user must wait for a marked user to enter before
+ ; joining the conference. Off by default
+;drop_silence=yes ; Sets if a channel's audio should be dropped from mixing
+ ; after a certain number of milliseconds of silence is detected.
+ ; Once the user begins talking audio will enter back into
+ ; the bridge. This option will improve the performance
+ ; of the conference bridge when large numbers of people are present.
+ ; By default this option is off. When set to yes, audio will
+ ; be dropped from conference bridge mixing after 3000 milliseconds
+ ; (3 seconds) of silence is detected. The number of
+ ; milliseconds can be configured as well by assigning
+ ; this option the number of milliseconds to wait before detecting
+ ; silence instead of yes/no.
[default_bridge]
type=bridge
Modified: team/dvossel/hd_confbridge/include/asterisk/bridging.h
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/include/asterisk/bridging.h?view=diff&rev=310133&r1=310132&r2=310133
==============================================================================
--- team/dvossel/hd_confbridge/include/asterisk/bridging.h (original)
+++ team/dvossel/hd_confbridge/include/asterisk/bridging.h Tue Mar 8 15:32:24 2011
@@ -63,6 +63,7 @@
#endif
#include "asterisk/bridging_features.h"
+#include "asterisk/dsp.h"
/*! \brief Capabilities for a bridge technology */
enum ast_bridge_capability {
@@ -139,6 +140,8 @@
struct ast_bridge_features *features;
/*! Queue of DTMF digits used for DTMF streaming */
char dtmf_stream_q[8];
+ /*! DSP used for silence and noise detection */
+ struct ast_dsp *dsp;
/*! Linked list information */
AST_LIST_ENTRY(ast_bridge_channel) entry;
};
Modified: team/dvossel/hd_confbridge/include/asterisk/bridging_features.h
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/include/asterisk/bridging_features.h?view=diff&rev=310133&r1=310132&r2=310133
==============================================================================
--- team/dvossel/hd_confbridge/include/asterisk/bridging_features.h (original)
+++ team/dvossel/hd_confbridge/include/asterisk/bridging_features.h Tue Mar 8 15:32:24 2011
@@ -99,6 +99,10 @@
AST_LIST_HEAD_NOLOCK(, ast_bridge_features_hook) hooks;
/*! Feature flags that are enabled */
struct ast_flags feature_flags;
+ /*! The number of ms of silence before channel read audio is dropped as
+ * silence from the bridge. When this varaible is 0, audio is never dropped
+ * due to silence. */
+ unsigned int detect_silence;
/*! Bit to indicate that this structure is useful and should be considered when looking for features */
unsigned int usable:1;
/*! Bit to indicate whether the channel/bridge is muted or not */
Modified: team/dvossel/hd_confbridge/include/asterisk/dsp.h
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/include/asterisk/dsp.h?view=diff&rev=310133&r1=310132&r2=310133
==============================================================================
--- team/dvossel/hd_confbridge/include/asterisk/dsp.h (original)
+++ team/dvossel/hd_confbridge/include/asterisk/dsp.h Tue Mar 8 15:32:24 2011
@@ -74,6 +74,10 @@
struct ast_dsp *ast_dsp_new(void);
void ast_dsp_free(struct ast_dsp *dsp);
+
+/*! \brief Retrieve the sample rate this DSP structure was
+ * created with */
+unsigned int ast_dsp_get_sample_rate(const struct ast_dsp *dsp);
/*! \brief Set threshold value for silence */
void ast_dsp_set_threshold(struct ast_dsp *dsp, int threshold);
Modified: team/dvossel/hd_confbridge/main/bridging.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/main/bridging.c?view=diff&rev=310133&r1=310132&r2=310133
==============================================================================
--- team/dvossel/hd_confbridge/main/bridging.c (original)
+++ team/dvossel/hd_confbridge/main/bridging.c Tue Mar 8 15:32:24 2011
@@ -273,6 +273,48 @@
}
}
+/*!
+ * \internal
+ *
+ * \brief This function places itself in the middle of the channel's read audio
+ * path to allow the bridge to perform preprocessing audio features before
+ * the bridging technology see's the frame.
+ *
+ * \note This function expects the frame to be in slinear format.
+ * \note
+ *
+ * \retval frame after preprocessing is complete.
+ */
+static struct ast_frame *bridge_channel_preprocess_read_audio(struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
+{
+ int detect_silence = MAX(bridge_channel->bridge->features.detect_silence, (bridge_channel->features ? bridge_channel->features->detect_silence : 0));
+
+ if (detect_silence) {
+ int totalsilence = 0;
+ /* make sure we have a dsp for the correct sample rate. A change in sample rate in a
+ * single direction does not happen often, but our DSP needs to be made aware of such a change. */
+ if (bridge_channel->dsp &&
+ (ast_dsp_get_sample_rate(bridge_channel->dsp) != ast_format_rate(&frame->subclass.format))) {
+
+ ast_dsp_free(bridge_channel->dsp);
+ bridge_channel->dsp = NULL;
+ }
+ if (!bridge_channel->dsp && !(bridge_channel->dsp = ast_dsp_new_with_rate(ast_format_rate(&frame->subclass.format)))) {
+ return frame;
+ }
+
+ /* if silence is detected and the total is above the threshold, drop the audio */
+ if (ast_dsp_silence(bridge_channel->dsp, frame, &totalsilence) &&
+ (totalsilence > detect_silence)) {
+
+ ast_frfree(frame);
+ return &ast_null_frame;
+ }
+ }
+
+ return frame;
+}
+
void ast_bridge_handle_trip(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_channel *chan, int outfd)
{
/* If no bridge channel has been provided and the actual channel has been provided find it */
@@ -293,6 +335,8 @@
} else {
if (frame->frametype == AST_FRAME_DTMF_BEGIN) {
frame = bridge_handle_dtmf(bridge, bridge_channel, frame);
+ } else if (frame->frametype == AST_FRAME_VOICE && ast_format_is_slinear(&frame->subclass.format)) {
+ frame = bridge_channel_preprocess_read_audio(bridge_channel, frame);
}
/* Simply write the frame out to the bridge technology if it still exists */
if (frame) {
@@ -1021,6 +1065,17 @@
return state;
}
+static struct ast_bridge_channel *free_bridge_channel(struct ast_bridge_channel *bridge_channel)
+{
+ /* Destroy elements of the bridge channel structure and the bridge channel structure itself */
+ ast_dsp_free(bridge_channel->dsp);
+ ast_mutex_destroy(&bridge_channel->lock);
+ ast_cond_destroy(&bridge_channel->cond);
+
+ ast_free(bridge_channel);
+ return NULL;
+}
+
/*! \brief Thread responsible for imparted bridged channels */
static void *bridge_channel_thread(void *data)
{
@@ -1036,10 +1091,7 @@
ast_hangup(bridge_channel->chan);
}
- /* Destroy elements of the bridge channel structure and the bridge channel structure itself */
- ast_mutex_destroy(&bridge_channel->lock);
- ast_cond_destroy(&bridge_channel->cond);
- ast_free(bridge_channel);
+ free_bridge_channel(bridge_channel);
return NULL;
}
@@ -1069,9 +1121,7 @@
/* Actually create the thread that will handle the channel */
if (ast_pthread_create(&bridge_channel->thread, NULL, bridge_channel_thread, bridge_channel)) {
ao2_ref(bridge, -1);
- ast_cond_destroy(&bridge_channel->cond);
- ast_mutex_destroy(&bridge_channel->lock);
- ast_free(bridge_channel);
+ free_bridge_channel(bridge_channel);
return -1;
}
Modified: team/dvossel/hd_confbridge/main/dsp.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/main/dsp.c?view=diff&rev=310133&r1=310132&r2=310133
==============================================================================
--- team/dvossel/hd_confbridge/main/dsp.c (original)
+++ team/dvossel/hd_confbridge/main/dsp.c Tue Mar 8 15:32:24 2011
@@ -1516,6 +1516,11 @@
dsp->ringtimeout= 0;
}
+unsigned int ast_dsp_get_sample_rate(const struct ast_dsp *dsp)
+{
+ return dsp->sample_rate;
+}
+
static struct ast_dsp *__ast_dsp_new(unsigned int sample_rate)
{
struct ast_dsp *dsp;
More information about the asterisk-commits
mailing list