Merge remote-tracking branch 'sm0svx/master' into coder-init
This commit is contained in:
commit
e7f68a27b5
|
|
@ -918,6 +918,14 @@ close it when it does not have to be open anymore. This may cause problems in
|
|||
some applications or with some sound hardware. Set this variable to 1 to force
|
||||
SvxLink to keep the audio device open from application start to exit.
|
||||
.TP
|
||||
.B LIMITER_THRESH
|
||||
Set the threshold, in dBFS, for the audio limiter. The audio limiter really is
|
||||
a compressor with a very steep compression ratio like 10:1. The limiter is
|
||||
used to help keeping down the audio level for overmodulating stations. For a
|
||||
properly calibrated SvxLink node max FM deviation is -6dBFS. A good value to
|
||||
start with for this parameter is then -6 but try to lower it further (like -9
|
||||
to -12) if it does not affect audio quality negatively.
|
||||
.TP
|
||||
.B SQL_DET
|
||||
Specify the type of squelch detector to use. Possible values are: VOX, CTCSS,
|
||||
SERIAL, EVDEV, SIGLEV, PTY, GPIO, HIDRAW or COMBINE.
|
||||
|
|
@ -2001,6 +2009,14 @@ close it when it does not have to be open anymore. This may cause problems in
|
|||
some applications or with some sound hardware. Set this variable to 1 to force
|
||||
SvxLink to keep the audio device open from application start to exit.
|
||||
.TP
|
||||
.B LIMITER_THRESH
|
||||
Set the threshold, in dBFS, for the audio limiter. The audio limiter really is
|
||||
a compressor with a very steep compression ratio like 10:1. The limiter is
|
||||
used to help keeping down the audio level to not overmodulate the transmitter.
|
||||
For a properly calibrated SvxLink node max FM deviation is -6dBFS. A good value
|
||||
to start with for this parameter is then -6 but try to lower it further (like
|
||||
-9 to -12) if it does not affect audio quality negatively.
|
||||
.TP
|
||||
.B PTT_TYPE
|
||||
Use this configuration variable to specify which type of hardware to use to
|
||||
control the PTT. Specify "SerialPin" for using a pin in the serial port,
|
||||
|
|
|
|||
|
|
@ -84,6 +84,23 @@
|
|||
* Use the new configuration variable COMMAND_PTY to set up a PTY that can be
|
||||
used to send commands to a logic core.
|
||||
|
||||
* Filter out CTCSS band for voice output. Interference on CTCSS transmission
|
||||
could be caused by low frequency content in audio clips or incoming audio on
|
||||
Echolink for example.
|
||||
|
||||
* Ignore prioritized talkgroups qfter QSY if there have been local node
|
||||
activity prior to the QSY. This fix a problem where a node would switch to a
|
||||
prioritized talkgroup after a QSY to a lower priority talkgroup, if there
|
||||
have been no local activity after the QSY. Priority will be honored again
|
||||
after the node have switched to TG#0.
|
||||
|
||||
* Make the audio limiter threshold in the receiver configurable using the
|
||||
LIMITER_THRESH configuration variable in a receiver configuration section.
|
||||
|
||||
* Add an audio limiter to the transmitted audio path. The threshold may be set
|
||||
using the LIMITER_THRESH configuration variable in a TX configuration
|
||||
section.
|
||||
|
||||
|
||||
|
||||
1.7.0 -- 01 Sep 2019
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ TYPE=Local
|
|||
#RX_ID=?
|
||||
AUDIO_DEV=alsa:plughw:0
|
||||
AUDIO_CHANNEL=0
|
||||
LIMITER_THRESH=-6
|
||||
SQL_DET=VOX
|
||||
SQL_START_DELAY=0
|
||||
SQL_DELAY=0
|
||||
|
|
@ -121,6 +122,7 @@ DTMF_SERIAL=/dev/ttyS0
|
|||
TYPE=Local
|
||||
AUDIO_DEV=alsa:plughw:0
|
||||
AUDIO_CHANNEL=0
|
||||
LIMITER_THRESH=-6
|
||||
PTT_TYPE=NONE
|
||||
PTT_PORT=/dev/ttyS0
|
||||
PTT_PIN=DTRRTS
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ ReflectorLogic::ReflectorLogic(Async::Config& cfg, const std::string& name)
|
|||
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_tmp_monitor_timer(1000, Async::Timer::TYPE_PERIODIC),
|
||||
m_tmp_monitor_timeout(DEFAULT_TMP_MONITOR_TIMEOUT)
|
||||
m_tmp_monitor_timeout(DEFAULT_TMP_MONITOR_TIMEOUT), m_use_prio(true)
|
||||
{
|
||||
m_reconnect_timer.expired.connect(
|
||||
sigc::hide(mem_fun(*this, &ReflectorLogic::reconnect)));
|
||||
|
|
@ -400,6 +400,7 @@ void ReflectorLogic::remoteCmdReceived(LogicBase* src_logic,
|
|||
{
|
||||
selectTg(tg, "tg_command_activation", true);
|
||||
m_tg_local_activity = true;
|
||||
m_use_prio = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -410,6 +411,7 @@ void ReflectorLogic::remoteCmdReceived(LogicBase* src_logic,
|
|||
{
|
||||
selectTg(m_previous_tg, "tg_command_activation", true);
|
||||
m_tg_local_activity = true;
|
||||
m_use_prio = false;
|
||||
}
|
||||
}
|
||||
else if (cmd[0] == '2') // QSY
|
||||
|
|
@ -448,6 +450,7 @@ void ReflectorLogic::remoteCmdReceived(LogicBase* src_logic,
|
|||
{
|
||||
selectTg(m_last_qsy, "tg_command_activation", true);
|
||||
m_tg_local_activity = true;
|
||||
m_use_prio = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -510,6 +513,7 @@ void ReflectorLogic::remoteReceivedTgUpdated(LogicBase *logic, uint32_t tg)
|
|||
{
|
||||
selectTg(tg, "tg_local_activation", !m_mute_first_tx_loc);
|
||||
m_tg_local_activity = true;
|
||||
m_use_prio = false;
|
||||
}
|
||||
} /* ReflectorLogic::remoteReceivedTgUpdated */
|
||||
|
||||
|
|
@ -1051,7 +1055,7 @@ void ReflectorLogic::handleMsgTalkerStart(std::istream& is)
|
|||
{
|
||||
selectTg(msg.tg(), "tg_remote_activation", !m_mute_first_tx_rem);
|
||||
}
|
||||
else
|
||||
else if (m_use_prio)
|
||||
{
|
||||
uint32_t selected_tg_prio = 0;
|
||||
MonitorTgsSet::const_iterator selected_tg_it =
|
||||
|
|
@ -1063,8 +1067,7 @@ void ReflectorLogic::handleMsgTalkerStart(std::istream& is)
|
|||
MonitorTgsSet::const_iterator talker_tg_it =
|
||||
m_monitor_tgs.find(MonitorTgEntry(msg.tg()));
|
||||
if ((talker_tg_it != m_monitor_tgs.end()) &&
|
||||
(talker_tg_it->prio > selected_tg_prio) &&
|
||||
!m_tg_local_activity)
|
||||
(talker_tg_it->prio > selected_tg_prio))
|
||||
{
|
||||
std::cout << name() << ": Activity on prioritized TG #"
|
||||
<< msg.tg() << ". Switching!" << std::endl;
|
||||
|
|
@ -1516,6 +1519,7 @@ void ReflectorLogic::onLogicConInStreamStateChanged(bool is_active,
|
|||
}
|
||||
}
|
||||
m_tg_local_activity = true;
|
||||
m_use_prio = false;
|
||||
m_tg_select_timeout_cnt = m_tg_select_timeout;
|
||||
}
|
||||
|
||||
|
|
@ -1580,7 +1584,15 @@ void ReflectorLogic::selectTg(uint32_t tg, const std::string& event, bool unmute
|
|||
m_previous_tg = m_selected_tg;
|
||||
}
|
||||
m_selected_tg = tg;
|
||||
m_tg_local_activity = false;
|
||||
if (tg == 0)
|
||||
{
|
||||
m_tg_local_activity = false;
|
||||
m_use_prio = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_tg_local_activity = !m_logic_con_in->isIdle();
|
||||
}
|
||||
m_event_handler->setVariable(name() + "::selected_tg", m_selected_tg);
|
||||
m_event_handler->setVariable(name() + "::previous_tg", m_previous_tg);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -254,6 +254,7 @@ class ReflectorLogic : public LogicBase
|
|||
bool m_mute_first_tx_rem;
|
||||
Async::Timer m_tmp_monitor_timer;
|
||||
int m_tmp_monitor_timeout;
|
||||
bool m_use_prio;
|
||||
|
||||
ReflectorLogic(const ReflectorLogic&);
|
||||
ReflectorLogic& operator=(const ReflectorLogic&);
|
||||
|
|
|
|||
|
|
@ -186,6 +186,7 @@ TYPE=Local
|
|||
AUDIO_DEV=alsa:plughw:0
|
||||
AUDIO_CHANNEL=0
|
||||
#AUDIO_DEV_KEEP_OPEN=0
|
||||
LIMITER_THRESH=-6
|
||||
SQL_DET=VOX
|
||||
SQL_START_DELAY=0
|
||||
SQL_DELAY=0
|
||||
|
|
@ -258,6 +259,7 @@ TX_ID=T
|
|||
AUDIO_DEV=alsa:plughw:0
|
||||
AUDIO_CHANNEL=0
|
||||
#AUDIO_DEV_KEEP_OPEN=0
|
||||
LIMITER_THRESH=-6
|
||||
PTT_TYPE=NONE
|
||||
PTT_PORT=/dev/ttyS0
|
||||
PTT_PIN=DTRRTS
|
||||
|
|
|
|||
|
|
@ -103,9 +103,10 @@ using namespace Async;
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#define DTMF_MUTING_POST 200
|
||||
#define TONE_1750_MUTING_PRE 75
|
||||
#define TONE_1750_MUTING_POST 100
|
||||
#define DTMF_MUTING_POST 200
|
||||
#define TONE_1750_MUTING_PRE 75
|
||||
#define TONE_1750_MUTING_POST 100
|
||||
#define DEFAULT_LIMITER_THRESH -1.0
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -593,15 +594,20 @@ bool LocalRxBase::initialize(void)
|
|||
prev_src = delay;
|
||||
}
|
||||
|
||||
// Add a limiter to smoothly limiting the audio before hard clipping it
|
||||
AudioCompressor *limit = new AudioCompressor;
|
||||
limit->setThreshold(-1);
|
||||
limit->setRatio(0.1);
|
||||
limit->setAttack(2);
|
||||
limit->setDecay(20);
|
||||
limit->setOutputGain(1);
|
||||
prev_src->registerSink(limit, true);
|
||||
prev_src = limit;
|
||||
// Add a limiter to smoothly limit the audio before hard clipping it
|
||||
double limiter_thresh = DEFAULT_LIMITER_THRESH;
|
||||
cfg().getValue(name(), "LIMITER_THRESH", limiter_thresh);
|
||||
if (limiter_thresh != 0.0)
|
||||
{
|
||||
AudioCompressor *limit = new AudioCompressor;
|
||||
limit->setThreshold(limiter_thresh);
|
||||
limit->setRatio(0.1);
|
||||
limit->setAttack(2);
|
||||
limit->setDecay(20);
|
||||
limit->setOutputGain(1);
|
||||
prev_src->registerSink(limit, true);
|
||||
prev_src = limit;
|
||||
}
|
||||
|
||||
// Clip audio to limit its amplitude
|
||||
AudioClipper *clipper = new AudioClipper;
|
||||
|
|
|
|||
|
|
@ -112,7 +112,8 @@ using namespace SvxLink;
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#define USE_AUDIO_VALVE 0
|
||||
#define USE_AUDIO_VALVE 0
|
||||
#define DEFAULT_LIMITER_THRESH 0.0
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -471,24 +472,28 @@ bool LocalTx::initialize(void)
|
|||
prev_src->registerSink(preemph, true);
|
||||
prev_src = preemph;
|
||||
}
|
||||
|
||||
/*
|
||||
AudioCompressor *limit = new AudioCompressor;
|
||||
limit->setThreshold(-1);
|
||||
limit->setRatio(0.1);
|
||||
limit->setAttack(2);
|
||||
limit->setDecay(20);
|
||||
limit->setOutputGain(1);
|
||||
prev_src->registerSink(limit, true);
|
||||
prev_src = limit;
|
||||
*/
|
||||
|
||||
|
||||
// Add a limiter to smoothly limit the audio before hard clipping it
|
||||
double limiter_thresh = DEFAULT_LIMITER_THRESH;
|
||||
cfg.getValue(name(), "LIMITER_THRESH", limiter_thresh);
|
||||
if (limiter_thresh != 0.0)
|
||||
{
|
||||
AudioCompressor *limit = new AudioCompressor;
|
||||
limit->setThreshold(limiter_thresh);
|
||||
limit->setRatio(0.1);
|
||||
limit->setAttack(2);
|
||||
limit->setDecay(20);
|
||||
limit->setOutputGain(1);
|
||||
prev_src->registerSink(limit, true);
|
||||
prev_src = limit;
|
||||
}
|
||||
|
||||
// Clip audio to limit its amplitude
|
||||
AudioClipper *clipper = new AudioClipper;
|
||||
prev_src->registerSink(clipper, true);
|
||||
prev_src = clipper;
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
// Filter out high frequencies generated by the previous clipping
|
||||
#if (INTERNAL_SAMPLE_RATE == 16000)
|
||||
//AudioFilter *splatter_filter = new AudioFilter("LpBu10/5500");
|
||||
|
|
@ -499,7 +504,17 @@ bool LocalTx::initialize(void)
|
|||
prev_src->registerSink(splatter_filter, true);
|
||||
prev_src = splatter_filter;
|
||||
#endif
|
||||
|
||||
|
||||
#if (INTERNAL_SAMPLE_RATE == 16000)
|
||||
AudioFilter *voiceband_filter =
|
||||
new AudioFilter("LpCh9/-0.05/5500 x HpCh12/-0.05/300");
|
||||
#else
|
||||
AudioFilter *voiceband_filter =
|
||||
new AudioFilter("LpBu20/3500 x HpCh12/-0.05/300");
|
||||
#endif
|
||||
prev_src->registerSink(voiceband_filter, true);
|
||||
prev_src = voiceband_filter;
|
||||
|
||||
// Create a valve so that we can control when to transmit audio
|
||||
#if USE_AUDIO_VALVE
|
||||
audio_valve = new AudioValve;
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ LIBECHOLIB=1.3.3
|
|||
LIBASYNC=1.6.0.99.11
|
||||
|
||||
# SvxLink versions
|
||||
SVXLINK=1.7.99.26
|
||||
SVXLINK=1.7.99.29
|
||||
MODULE_HELP=1.0.0
|
||||
MODULE_PARROT=1.1.1
|
||||
MODULE_ECHO_LINK=1.5.99.0
|
||||
|
|
|
|||
Loading…
Reference in New Issue