Split MUTE_FIRST_TX in local and remote versions

The MUTE_FIRST_TX ReflectorLogic configuration variable has been split
into two new variables, MUTE_FIRST_TX_LOC and MUTE_FIRST_TX_REM. This
has been done since the muting on local talk group activation is quite
intuitive but muting due to remote talk group activivation is not.

Have a look in the svxlink.conf (5) manual page for more information.
This commit is contained in:
Tobias Blomberg 2019-11-03 13:56:43 +01:00
parent 234f9e6921
commit 85c8ab9489
5 changed files with 48 additions and 31 deletions

View File

@ -649,16 +649,28 @@ 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.
.B MUTE_FIRST_TX_LOC
Mute the first transmission after selecting a talk group due to local activity.
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. An
example is that someone activates a talk group using CTCSS but then immediately
select another talk group using DTMF. In that case no transmission will be made
on the first talk group. This feature is enabled by default.
.TP
.B MUTE_FIRST_TX_REM
Mute the first transmission after selecting a talk group due to remote
activity. This feature can be enabled to let local node users enter DTMF
commands without disturbing an active talk group. As an example, the local node
monitors a talk group that is active. However, no one on the local node
participates in the QSO and a local user want to select another talk group.
With this feature enabled it is possible to do that without transmitting into
the reflector network while entering DTMF commands.
This feature is not enabled by default since it is a bit unintuitive. If a
local user hear a call and want to answer that call, he must first make a short
transmission to "open up" the local node. This is easy to forget.
.
.SS QSO Recorder Section
.

View File

@ -134,7 +134,8 @@ 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_logic_con_in_valve(0)
m_tg_local_activity(false), m_last_qsy(0), m_logic_con_in_valve(0),
m_mute_first_tx_loc(true), m_mute_first_tx_rem(false)
{
m_reconnect_timer.expired.connect(
sigc::hide(mem_fun(*this, &ReflectorLogic::reconnect)));
@ -252,9 +253,9 @@ bool ReflectorLogic::initialize(void)
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)
cfg().getValue(name(), "MUTE_FIRST_TX_LOC", m_mute_first_tx_loc);
cfg().getValue(name(), "MUTE_FIRST_TX_REM", m_mute_first_tx_rem);
if (m_mute_first_tx_loc || m_mute_first_tx_rem)
{
m_logic_con_in_valve = new Async::AudioValve;
m_logic_con_in_valve->setOpen(false);
@ -384,7 +385,7 @@ void ReflectorLogic::remoteCmdReceived(LogicBase* src_logic,
uint32_t tg;
if (is >> tg)
{
selectTg(tg, "tg_command_activation");
selectTg(tg, "tg_command_activation", true);
m_tg_local_activity = true;
}
else
@ -394,7 +395,7 @@ void ReflectorLogic::remoteCmdReceived(LogicBase* src_logic,
}
else // Select previous TG
{
selectTg(m_previous_tg, "tg_command_activation");
selectTg(m_previous_tg, "tg_command_activation", true);
m_tg_local_activity = true;
}
}
@ -432,7 +433,7 @@ void ReflectorLogic::remoteCmdReceived(LogicBase* src_logic,
{
if ((m_last_qsy > 0) && (m_last_qsy != m_selected_tg))
{
selectTg(m_last_qsy, "tg_command_activation");
selectTg(m_last_qsy, "tg_command_activation", true);
m_tg_local_activity = true;
}
else
@ -453,7 +454,7 @@ void ReflectorLogic::remoteReceivedTgUpdated(LogicBase *logic, uint32_t tg)
// << logic->name() << " tg=" << tg << endl;
if ((m_selected_tg == 0) && (tg > 0))
{
selectTg(tg, "tg_local_activation");
selectTg(tg, "tg_local_activation", !m_mute_first_tx_loc);
m_tg_local_activity = true;
}
} /* ReflectorLogic::remoteReceivedTgUpdated */
@ -994,7 +995,7 @@ void ReflectorLogic::handleMsgTalkerStart(std::istream& is)
// Select the incoming TG if idle
if (m_tg_select_timeout_cnt == 0)
{
selectTg(msg.tg(), "tg_remote_activation");
selectTg(msg.tg(), "tg_remote_activation", !m_mute_first_tx_rem);
}
else
{
@ -1013,7 +1014,7 @@ void ReflectorLogic::handleMsgTalkerStart(std::istream& is)
{
std::cout << name() << ": Activity on prioritized TG #"
<< msg.tg() << ". Switching!" << std::endl;
selectTg(msg.tg(), "tg_remote_prio_activation");
selectTg(msg.tg(), "tg_remote_prio_activation", !m_mute_first_tx_rem);
}
}
@ -1053,7 +1054,7 @@ void ReflectorLogic::handleMsgRequestQsy(std::istream& is)
cout << name() << ": Server QSY request for TG #" << msg.tg() << endl;
if (m_tg_local_activity)
{
selectTg(msg.tg(), "tg_qsy");
selectTg(msg.tg(), "tg_qsy", true);
}
else
{
@ -1451,7 +1452,7 @@ void ReflectorLogic::onLogicConInStreamStateChanged(bool is_active,
{
if (m_default_tg > 0)
{
selectTg(m_default_tg, "tg_default_activation");
selectTg(m_default_tg, "tg_default_activation", !m_mute_first_tx_loc);
}
}
m_tg_local_activity = true;
@ -1495,13 +1496,13 @@ void ReflectorLogic::tgSelectTimerExpired(void)
if (m_logic_con_out->isIdle() && m_logic_con_in->isIdle() &&
(--m_tg_select_timeout_cnt == 0))
{
selectTg(0, "tg_selection_timeout");
selectTg(0, "tg_selection_timeout", false);
}
}
} /* ReflectorLogic::tgSelectTimerExpired */
void ReflectorLogic::selectTg(uint32_t tg, const std::string& event)
void ReflectorLogic::selectTg(uint32_t tg, const std::string& event, bool unmute)
{
cout << name() << ": Selecting TG #" << tg << endl;
@ -1522,12 +1523,13 @@ 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;
if (m_logic_con_in_valve != 0)
{
m_logic_con_in_valve->setOpen(unmute);
}
} /* ReflectorLogic::selectTg */

View File

@ -247,6 +247,8 @@ class ReflectorLogic : public LogicBase
Json::Value m_node_info;
Async::AudioSource* m_enc_endpoint;
Async::AudioValve* m_logic_con_in_valve;
bool m_mute_first_tx_loc;
bool m_mute_first_tx_rem;
ReflectorLogic(const ReflectorLogic&);
ReflectorLogic& operator=(const ReflectorLogic&);
@ -285,7 +287,7 @@ class ReflectorLogic : public LogicBase
void tgSelectTimerExpired(void);
void onLogicConInStreamStateChanged(bool is_active, bool is_idle);
void onLogicConOutStreamStateChanged(bool is_active, bool is_idle);
void selectTg(uint32_t tg, const std::string& event);
void selectTg(uint32_t tg, const std::string& event, bool unmute);
void processEvent(const std::string& event);
void processTgSelectionEvent(void);

View File

@ -95,7 +95,8 @@ 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
#MUTE_FIRST_TX_LOC=1
#MUTE_FIRST_TX_REM=1
[LinkToR4]
CONNECT_LOGICS=RepeaterLogic:94:SK3AB,SimplexLogic:92:SK3CD

View File

@ -11,7 +11,7 @@ LIBECHOLIB=1.3.3
LIBASYNC=1.6.0.99.3-reflector_tg
# SvxLink versions
SVXLINK=1.7.99.14-reflector_tg
SVXLINK=1.7.99.15-reflector_tg
MODULE_HELP=1.0.0
MODULE_PARROT=1.1.1
MODULE_ECHO_LINK=1.5.0