Mute first reflector TX after TG activation
By default mute the first transmission after selecting a talk group. This is good for reducing unneccessary talk group activations and to allow local node DTMF command submission without disturbing an ongoing QSO on a talk group.
This commit is contained in:
parent
a2fa7c6f4b
commit
dbfd1a8266
|
|
@ -648,6 +648,17 @@ It is also possible to set audio codec parameters using the same configuration
|
|||
variables as documented for networked receivers and transmitters. For example,
|
||||
to lighten the encoder CPU load for the Opus encoder, set OPUS_ENC_COMPLEXITY
|
||||
to something lower than 9.
|
||||
.TP
|
||||
.B MUTE_FIRST_TX
|
||||
Mute the first transmission after selecting a talk group. This feature is good
|
||||
to have enabled for a number of reasons. One reason is to suppress short
|
||||
openings of a talk group when someone just make a single transmission to test
|
||||
the local node. Another reason is for to allow someone to submit DTMF commands
|
||||
to the node without disturbing the reflector network. For example, if the local
|
||||
node have opened up due to activity on a monitored talk group but a local user
|
||||
wish to switch to another talk group, that local user can do that without
|
||||
transmitting into the currently active talk group. This feature is enabled by
|
||||
default.
|
||||
.
|
||||
.SS QSO Recorder Section
|
||||
.
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
#include <AsyncTcpClient.h>
|
||||
#include <AsyncUdpSocket.h>
|
||||
#include <AsyncAudioPassthrough.h>
|
||||
#include <AsyncAudioValve.h>
|
||||
#include <version/SVXLINK.h>
|
||||
|
||||
|
||||
|
|
@ -133,7 +134,7 @@ ReflectorLogic::ReflectorLogic(Async::Config& cfg, const std::string& name)
|
|||
m_tg_select_timeout_cnt(0), m_selected_tg(0), m_previous_tg(0),
|
||||
m_event_handler(0),
|
||||
m_report_tg_timer(500, Async::Timer::TYPE_ONESHOT, false),
|
||||
m_tg_local_activity(false), m_last_qsy(0)
|
||||
m_tg_local_activity(false), m_last_qsy(0), m_logic_con_in_valve(0)
|
||||
{
|
||||
m_reconnect_timer.expired.connect(
|
||||
sigc::hide(mem_fun(*this, &ReflectorLogic::reconnect)));
|
||||
|
|
@ -249,10 +250,24 @@ bool ReflectorLogic::initialize(void)
|
|||
m_logic_con_in = new Async::AudioStreamStateDetector;
|
||||
m_logic_con_in->sigStreamStateChanged.connect(
|
||||
sigc::mem_fun(*this, &ReflectorLogic::onLogicConInStreamStateChanged));
|
||||
AudioSource *prev_src = m_logic_con_in;
|
||||
|
||||
bool mute_first_tx = true;
|
||||
cfg().getValue(name(), "MUTE_FIRST_TX", mute_first_tx);
|
||||
if (mute_first_tx)
|
||||
{
|
||||
m_logic_con_in_valve = new Async::AudioValve;
|
||||
m_logic_con_in_valve->setOpen(false);
|
||||
prev_src->registerSink(m_logic_con_in_valve);
|
||||
prev_src = m_logic_con_in_valve;
|
||||
}
|
||||
|
||||
m_enc_endpoint = prev_src;
|
||||
prev_src = 0;
|
||||
|
||||
// Create dummy audio codec used before setting the real encoder
|
||||
if (!setAudioCodec("DUMMY")) { return false; }
|
||||
AudioSource *prev_src = m_dec;
|
||||
prev_src = m_dec;
|
||||
|
||||
// Create jitter buffer
|
||||
AudioFifo *fifo = new Async::AudioFifo(2*INTERNAL_SAMPLE_RATE);
|
||||
|
|
@ -1352,7 +1367,7 @@ bool ReflectorLogic::setAudioCodec(const std::string& codec_name)
|
|||
mem_fun(*this, &ReflectorLogic::sendEncodedAudio));
|
||||
m_enc->flushEncodedSamples.connect(
|
||||
mem_fun(*this, &ReflectorLogic::flushEncodedAudio));
|
||||
m_logic_con_in->registerSink(m_enc, false);
|
||||
m_enc_endpoint->registerSink(m_enc, false);
|
||||
|
||||
string opt_prefix(m_enc->name());
|
||||
opt_prefix += "_ENC_";
|
||||
|
|
@ -1423,7 +1438,14 @@ void ReflectorLogic::onLogicConInStreamStateChanged(bool is_active,
|
|||
{
|
||||
//cout << "### ReflectorLogic::onLogicConInStreamStateChanged: is_active="
|
||||
// << is_active << " is_idle=" << is_idle << endl;
|
||||
if (!is_idle)
|
||||
if (is_idle)
|
||||
{
|
||||
if ((m_logic_con_in_valve != 0) && (m_selected_tg > 0))
|
||||
{
|
||||
m_logic_con_in_valve->setOpen(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_tg_select_timeout_cnt == 0) // No TG currently selected
|
||||
{
|
||||
|
|
@ -1497,6 +1519,10 @@ void ReflectorLogic::selectTg(uint32_t tg, const std::string& event)
|
|||
m_tg_local_activity = false;
|
||||
m_event_handler->setVariable(name() + "::selected_tg", m_selected_tg);
|
||||
m_event_handler->setVariable(name() + "::previous_tg", m_previous_tg);
|
||||
if ((m_logic_con_in_valve != 0 ) && (tg == 0))
|
||||
{
|
||||
m_logic_con_in_valve->setOpen(false);
|
||||
}
|
||||
}
|
||||
m_tg_select_timeout_cnt = (tg > 0) ? m_tg_select_timeout : 0;
|
||||
} /* ReflectorLogic::selectTg */
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
namespace Async
|
||||
{
|
||||
class UdpSocket;
|
||||
class AudioValve;
|
||||
};
|
||||
|
||||
class ReflectorMsg;
|
||||
|
|
@ -244,6 +245,8 @@ class ReflectorLogic : public LogicBase
|
|||
uint32_t m_last_qsy;
|
||||
MonitorTgsSet m_monitor_tgs;
|
||||
Json::Value m_node_info;
|
||||
Async::AudioSource* m_enc_endpoint;
|
||||
Async::AudioValve* m_logic_con_in_valve;
|
||||
|
||||
ReflectorLogic(const ReflectorLogic&);
|
||||
ReflectorLogic& operator=(const ReflectorLogic&);
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ AUTH_KEY="Change this key now!"
|
|||
ANNOUNCE_REMOTE_MIN_INTERVAL=300
|
||||
EVENT_HANDLER=@SVX_SHARE_INSTALL_DIR@/events.tcl
|
||||
#NODE_INFO_FILE=@SVX_SYSCONF_INSTALL_DIR@/node_info.json
|
||||
#MUTE_FIRST_TX=1
|
||||
|
||||
[LinkToR4]
|
||||
CONNECT_LOGICS=RepeaterLogic:94:SK3AB,SimplexLogic:92:SK3CD
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ LIBECHOLIB=1.3.3
|
|||
LIBASYNC=1.6.0.99.3-reflector_tg
|
||||
|
||||
# SvxLink versions
|
||||
SVXLINK=1.7.99.11-reflector_tg
|
||||
SVXLINK=1.7.99.12-reflector_tg
|
||||
MODULE_HELP=1.0.0
|
||||
MODULE_PARROT=1.1.1
|
||||
MODULE_ECHO_LINK=1.5.0
|
||||
|
|
|
|||
Loading…
Reference in New Issue