summaryrefslogtreecommitdiff
path: root/bridges
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2018-01-30 19:22:51 -0600
committerRichard Mudgett <rmudgett@digium.com>2018-01-31 13:14:40 -0600
commit1ccac0be0e0cd94ee1c07b9125823875571eadee (patch)
tree464756773471197f8ad6ad1b585fce3af8b7a41a /bridges
parent6c5e3226ec6db12b06962247ac39db32f05c5065 (diff)
bridge_softmix.c: Report not talking immediately when muted.
Currently in app_confbridge if someone mutes a channel while that channel is talking, the talk detection code is suspended while the channel is muted. As far an an external observer is concerned, the muted channel's talk status is still "talking" even though the channel is not contributing audio to the conference bridge. When the channel is later unmuted, it takes the usual 'dsp_silence_threshold' option time to clear the talking status even though the channel may have stopped talking while the channel was muted. * In bridge_softmix.c, clear the talking status and report talking stopped if the channel was talking when the channel is muted. When the channel is unmuted and the channel is still talking then report the channel as talking since it is contributing audio to the bridge again. ASTERISK-27647 Change-Id: Ie4fdbc05a0bc7343c2972bab012e2567917b3d4e
Diffstat (limited to 'bridges')
-rw-r--r--bridges/bridge_softmix.c54
1 files changed, 46 insertions, 8 deletions
diff --git a/bridges/bridge_softmix.c b/bridges/bridge_softmix.c
index 1ff92ad91..461b6e5ba 100644
--- a/bridges/bridge_softmix.c
+++ b/bridges/bridge_softmix.c
@@ -860,12 +860,17 @@ static void softmix_bridge_write_voice(struct ast_bridge *bridge, struct ast_bri
{
struct softmix_channel *sc = bridge_channel->tech_pvt;
struct softmix_bridge_data *softmix_data = bridge->tech_pvt;
+ int silent = 0;
int totalsilence = 0;
int cur_energy = 0;
int silence_threshold = bridge_channel->tech_args.silence_threshold ?
bridge_channel->tech_args.silence_threshold :
DEFAULT_SOFTMIX_SILENCE_THRESHOLD;
- char update_talking = -1; /* if this is set to 0 or 1, tell the bridge that the channel has started or stopped talking. */
+ /*
+ * If update_talking is set to 0 or 1, tell the bridge that the channel
+ * has started or stopped talking.
+ */
+ char update_talking = -1;
/* Write the frame into the conference */
ast_mutex_lock(&sc->lock);
@@ -893,7 +898,7 @@ static void softmix_bridge_write_voice(struct ast_bridge *bridge, struct ast_bri
/* The channel will be leaving soon if there is no dsp. */
if (sc->dsp) {
- ast_dsp_silence_with_energy(sc->dsp, frame, &totalsilence, &cur_energy);
+ silent = ast_dsp_silence_with_energy(sc->dsp, frame, &totalsilence, &cur_energy);
}
if (bridge->softmix.video_mode.mode == AST_BRIDGE_VIDEO_MODE_TALKER_SRC) {
@@ -910,15 +915,16 @@ static void softmix_bridge_write_voice(struct ast_bridge *bridge, struct ast_bri
}
if (totalsilence < silence_threshold) {
- if (!sc->talking) {
+ if (!sc->talking && !silent) {
+ /* Tell the write process we have audio to be mixed out */
+ sc->talking = 1;
update_talking = 1;
}
- sc->talking = 1; /* tell the write process we have audio to be mixed out */
} else {
if (sc->talking) {
+ sc->talking = 0;
update_talking = 0;
}
- sc->talking = 0;
}
/* Before adding audio in, make sure we haven't fallen behind. If audio has fallen
@@ -928,9 +934,8 @@ static void softmix_bridge_write_voice(struct ast_bridge *bridge, struct ast_bri
ast_slinfactory_flush(&sc->factory);
}
- /* If a frame was provided add it to the smoother, unless drop silence is enabled and this frame
- * is not determined to be talking. */
- if (!(bridge_channel->tech_args.drop_silence && !sc->talking)) {
+ if (sc->talking || !bridge_channel->tech_args.drop_silence) {
+ /* Add frame to the smoother for mixing with other channels. */
ast_slinfactory_feed(&sc->factory, frame);
}
@@ -942,6 +947,38 @@ static void softmix_bridge_write_voice(struct ast_bridge *bridge, struct ast_bri
}
}
+/*!
+ * \internal
+ * \brief Check for voice status updates.
+ * \since 13.20.0
+ *
+ * \param bridge Which bridge we are in
+ * \param bridge_channel Which channel we are checking
+ *
+ * \return Nothing
+ */
+static void softmix_bridge_check_voice(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
+{
+ struct softmix_channel *sc = bridge_channel->tech_pvt;
+
+ if (sc->talking
+ && bridge_channel->features->mute) {
+ /*
+ * We were muted while we were talking.
+ *
+ * Immediately stop contributing to mixing
+ * and report no longer talking.
+ */
+ ast_mutex_lock(&sc->lock);
+ ast_slinfactory_flush(&sc->factory);
+ sc->talking = 0;
+ ast_mutex_unlock(&sc->lock);
+
+ /* Notify that we are no longer talking. */
+ ast_bridge_channel_notify_talking(bridge_channel, 0);
+ }
+}
+
static int remove_all_original_streams(struct ast_stream_topology *dest,
const struct ast_stream_topology *source,
const struct ast_stream_topology *original)
@@ -1119,6 +1156,7 @@ static int softmix_bridge_write(struct ast_bridge *bridge, struct ast_bridge_cha
switch (frame->frametype) {
case AST_FRAME_NULL:
/* "Accept" the frame and discard it. */
+ softmix_bridge_check_voice(bridge, bridge_channel);
break;
case AST_FRAME_DTMF_BEGIN:
case AST_FRAME_DTMF_END: