mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-05-29 05:22:25 -04:00
UDP source plugin: implemented squelch gate
This commit is contained in:
parent
2c3f7fe690
commit
587d38665d
@ -30,17 +30,9 @@ MESSAGE_CLASS_DEFINITION(UDPSrc::MsgUDPSrcConfigureImmediate, Message)
|
|||||||
MESSAGE_CLASS_DEFINITION(UDPSrc::MsgUDPSrcSpectrum, Message)
|
MESSAGE_CLASS_DEFINITION(UDPSrc::MsgUDPSrcSpectrum, Message)
|
||||||
|
|
||||||
UDPSrc::UDPSrc(MessageQueue* uiMessageQueue, UDPSrcGUI* udpSrcGUI, BasebandSampleSink* spectrum) :
|
UDPSrc::UDPSrc(MessageQueue* uiMessageQueue, UDPSrcGUI* udpSrcGUI, BasebandSampleSink* spectrum) :
|
||||||
m_udpPort(9999),
|
|
||||||
m_gain(1.0),
|
|
||||||
m_audioActive(false),
|
|
||||||
m_audioStereo(false),
|
|
||||||
m_volume(20),
|
|
||||||
m_fmDeviation(2500),
|
|
||||||
m_outMovingAverage(480, 1e-10),
|
m_outMovingAverage(480, 1e-10),
|
||||||
m_inMovingAverage(480, 1e-10),
|
m_inMovingAverage(480, 1e-10),
|
||||||
m_audioFifo(4, 24000),
|
m_audioFifo(4, 24000),
|
||||||
m_squelch(1e-6),
|
|
||||||
m_squelchEnabled(true),
|
|
||||||
m_squelchOpen(false),
|
m_squelchOpen(false),
|
||||||
m_squelchOpenCount(0),
|
m_squelchOpenCount(0),
|
||||||
m_squelchCloseCount(0),
|
m_squelchCloseCount(0),
|
||||||
@ -49,22 +41,17 @@ UDPSrc::UDPSrc(MessageQueue* uiMessageQueue, UDPSrcGUI* udpSrcGUI, BasebandSampl
|
|||||||
{
|
{
|
||||||
setObjectName("UDPSrc");
|
setObjectName("UDPSrc");
|
||||||
|
|
||||||
m_udpBuffer = new UDPSink<Sample>(this, udpBlockSize, m_udpPort);
|
m_udpBuffer = new UDPSink<Sample>(this, udpBlockSize, m_config.m_udpPort);
|
||||||
m_udpBufferMono = new UDPSink<FixReal>(this, udpBlockSize, m_udpPort);
|
m_udpBufferMono = new UDPSink<FixReal>(this, udpBlockSize, m_config.m_udpPort);
|
||||||
m_audioSocket = new QUdpSocket(this);
|
m_audioSocket = new QUdpSocket(this);
|
||||||
m_udpAudioBuf = new char[m_udpAudioPayloadSize];
|
m_udpAudioBuf = new char[m_udpAudioPayloadSize];
|
||||||
|
|
||||||
m_audioBuffer.resize(1<<9);
|
m_audioBuffer.resize(1<<9);
|
||||||
m_audioBufferFill = 0;
|
m_audioBufferFill = 0;
|
||||||
|
|
||||||
m_inputSampleRate = 96000;
|
m_nco.setFreq(0, m_config.m_inputSampleRate);
|
||||||
m_sampleFormat = FormatS16LE;
|
m_interpolator.create(16, m_config.m_inputSampleRate, m_config.m_rfBandwidth / 2.0);
|
||||||
m_outputSampleRate = 48000;
|
m_sampleDistanceRemain = m_config.m_inputSampleRate / m_config.m_outputSampleRate;
|
||||||
m_rfBandwidth = 32000;
|
|
||||||
m_audioPort = m_udpPort - 1;
|
|
||||||
m_nco.setFreq(0, m_inputSampleRate);
|
|
||||||
m_interpolator.create(16, m_inputSampleRate, m_rfBandwidth / 2.0);
|
|
||||||
m_sampleDistanceRemain = m_inputSampleRate / m_outputSampleRate;
|
|
||||||
m_uiMessageQueue = uiMessageQueue;
|
m_uiMessageQueue = uiMessageQueue;
|
||||||
m_udpSrcGUI = udpSrcGUI;
|
m_udpSrcGUI = udpSrcGUI;
|
||||||
m_spectrum = spectrum;
|
m_spectrum = spectrum;
|
||||||
@ -77,13 +64,13 @@ UDPSrc::UDPSrc(MessageQueue* uiMessageQueue, UDPSrcGUI* udpSrcGUI, BasebandSampl
|
|||||||
m_scale = 0;
|
m_scale = 0;
|
||||||
m_magsq = 0;
|
m_magsq = 0;
|
||||||
m_inMagsq = 0;
|
m_inMagsq = 0;
|
||||||
UDPFilter = new fftfilt(0.0, (m_rfBandwidth / 2.0) / m_outputSampleRate, udpBlockSize);
|
UDPFilter = new fftfilt(0.0, (m_config.m_rfBandwidth / 2.0) / m_config.m_outputSampleRate, udpBlockSize);
|
||||||
|
|
||||||
m_phaseDiscri.setFMScaling((float) m_outputSampleRate / (2.0f * m_fmDeviation));
|
m_phaseDiscri.setFMScaling((float) m_config. m_outputSampleRate / (2.0f * m_config.m_fmDeviation));
|
||||||
|
|
||||||
if (m_audioSocket->bind(QHostAddress::LocalHost, m_audioPort))
|
if (m_audioSocket->bind(QHostAddress::LocalHost, m_config.m_audioPort))
|
||||||
{
|
{
|
||||||
qDebug("UDPSrc::UDPSrc: bind audio socket to port %d", m_audioPort);
|
qDebug("UDPSrc::UDPSrc: bind audio socket to port %d", m_config.m_audioPort);
|
||||||
connect(m_audioSocket, SIGNAL(readyRead()), this, SLOT(audioReadyRead()), Qt::QueuedConnection);
|
connect(m_audioSocket, SIGNAL(readyRead()), this, SLOT(audioReadyRead()), Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -101,9 +88,10 @@ UDPSrc::~UDPSrc()
|
|||||||
delete m_udpBufferMono;
|
delete m_udpBufferMono;
|
||||||
delete[] m_udpAudioBuf;
|
delete[] m_udpAudioBuf;
|
||||||
if (UDPFilter) delete UDPFilter;
|
if (UDPFilter) delete UDPFilter;
|
||||||
if (m_audioActive) DSPEngine::instance()->removeAudioSink(&m_audioFifo);
|
if (m_running.m_audioActive) DSPEngine::instance()->removeAudioSink(&m_audioFifo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** what needs the "apply" button validation */
|
||||||
void UDPSrc::configure(MessageQueue* messageQueue,
|
void UDPSrc::configure(MessageQueue* messageQueue,
|
||||||
SampleFormat sampleFormat,
|
SampleFormat sampleFormat,
|
||||||
Real outputSampleRate,
|
Real outputSampleRate,
|
||||||
@ -111,7 +99,8 @@ void UDPSrc::configure(MessageQueue* messageQueue,
|
|||||||
int fmDeviation,
|
int fmDeviation,
|
||||||
QString& udpAddress,
|
QString& udpAddress,
|
||||||
int udpPort,
|
int udpPort,
|
||||||
int audioPort)
|
int audioPort,
|
||||||
|
bool force)
|
||||||
{
|
{
|
||||||
Message* cmd = MsgUDPSrcConfigure::create(sampleFormat,
|
Message* cmd = MsgUDPSrcConfigure::create(sampleFormat,
|
||||||
outputSampleRate,
|
outputSampleRate,
|
||||||
@ -119,17 +108,21 @@ void UDPSrc::configure(MessageQueue* messageQueue,
|
|||||||
fmDeviation,
|
fmDeviation,
|
||||||
udpAddress,
|
udpAddress,
|
||||||
udpPort,
|
udpPort,
|
||||||
audioPort);
|
audioPort,
|
||||||
|
force);
|
||||||
messageQueue->push(cmd);
|
messageQueue->push(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** changes applied immediately */
|
||||||
void UDPSrc::configureImmediate(MessageQueue* messageQueue,
|
void UDPSrc::configureImmediate(MessageQueue* messageQueue,
|
||||||
bool audioActive,
|
bool audioActive,
|
||||||
bool audioStereo,
|
bool audioStereo,
|
||||||
Real boost,
|
Real boost,
|
||||||
int volume,
|
int volume,
|
||||||
Real squelchDB,
|
Real squelchDB,
|
||||||
bool squelchEnabled)
|
Real squelchGate,
|
||||||
|
bool squelchEnabled,
|
||||||
|
bool force)
|
||||||
{
|
{
|
||||||
Message* cmd = MsgUDPSrcConfigureImmediate::create(
|
Message* cmd = MsgUDPSrcConfigureImmediate::create(
|
||||||
audioActive,
|
audioActive,
|
||||||
@ -137,7 +130,9 @@ void UDPSrc::configureImmediate(MessageQueue* messageQueue,
|
|||||||
boost,
|
boost,
|
||||||
volume,
|
volume,
|
||||||
squelchDB,
|
squelchDB,
|
||||||
squelchEnabled);
|
squelchGate,
|
||||||
|
squelchEnabled,
|
||||||
|
force);
|
||||||
messageQueue->push(cmd);
|
messageQueue->push(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,11 +166,11 @@ void UDPSrc::feed(const SampleVector::const_iterator& begin, const SampleVector:
|
|||||||
Sample ss(ci.real(), ci.imag());
|
Sample ss(ci.real(), ci.imag());
|
||||||
m_sampleBuffer.push_back(ss);
|
m_sampleBuffer.push_back(ss);
|
||||||
|
|
||||||
m_sampleDistanceRemain += m_inputSampleRate / m_outputSampleRate;
|
m_sampleDistanceRemain += m_running.m_inputSampleRate / m_running.m_outputSampleRate;
|
||||||
|
|
||||||
calculateSquelch(m_inMagsq);
|
calculateSquelch(m_inMagsq);
|
||||||
|
|
||||||
if (m_sampleFormat == FormatLSB) // binaural LSB
|
if (m_running.m_sampleFormat == FormatLSB) // binaural LSB
|
||||||
{
|
{
|
||||||
int n_out = UDPFilter->runSSB(ci, &sideband, false);
|
int n_out = UDPFilter->runSSB(ci, &sideband, false);
|
||||||
|
|
||||||
@ -183,14 +178,14 @@ void UDPSrc::feed(const SampleVector::const_iterator& begin, const SampleVector:
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < n_out; i++)
|
for (int i = 0; i < n_out; i++)
|
||||||
{
|
{
|
||||||
l = m_squelchOpen ? sideband[i].real() * m_gain : 0;
|
l = m_squelchOpen ? sideband[i].real() * m_running.m_gain : 0;
|
||||||
r = m_squelchOpen ? sideband[i].imag() * m_gain : 0;
|
r = m_squelchOpen ? sideband[i].imag() * m_running.m_gain : 0;
|
||||||
m_udpBuffer->write(Sample(l, r));
|
m_udpBuffer->write(Sample(l, r));
|
||||||
m_outMovingAverage.feed((l*l + r*r) / (1<<30));
|
m_outMovingAverage.feed((l*l + r*r) / (1<<30));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_sampleFormat == FormatUSB) // binaural USB
|
if (m_running.m_sampleFormat == FormatUSB) // binaural USB
|
||||||
{
|
{
|
||||||
int n_out = UDPFilter->runSSB(ci, &sideband, true);
|
int n_out = UDPFilter->runSSB(ci, &sideband, true);
|
||||||
|
|
||||||
@ -198,26 +193,26 @@ void UDPSrc::feed(const SampleVector::const_iterator& begin, const SampleVector:
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < n_out; i++)
|
for (int i = 0; i < n_out; i++)
|
||||||
{
|
{
|
||||||
l = m_squelchOpen ? sideband[i].real() * m_gain : 0;
|
l = m_squelchOpen ? sideband[i].real() * m_running.m_gain : 0;
|
||||||
r = m_squelchOpen ? sideband[i].imag() * m_gain : 0;
|
r = m_squelchOpen ? sideband[i].imag() * m_running.m_gain : 0;
|
||||||
m_udpBuffer->write(Sample(l, r));
|
m_udpBuffer->write(Sample(l, r));
|
||||||
m_outMovingAverage.feed((l*l + r*r) / (1<<30));
|
m_outMovingAverage.feed((l*l + r*r) / (1<<30));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m_sampleFormat == FormatNFM)
|
else if (m_running.m_sampleFormat == FormatNFM)
|
||||||
{
|
{
|
||||||
double demod = m_squelchOpen ? 32768.0 * m_phaseDiscri.phaseDiscriminator(ci) * m_gain : 0;
|
double demod = m_squelchOpen ? 32768.0 * m_phaseDiscri.phaseDiscriminator(ci) * m_running.m_gain : 0;
|
||||||
m_udpBuffer->write(Sample(demod, demod));
|
m_udpBuffer->write(Sample(demod, demod));
|
||||||
m_outMovingAverage.feed((demod * demod) / (1<<30));
|
m_outMovingAverage.feed((demod * demod) / (1<<30));
|
||||||
}
|
}
|
||||||
else if (m_sampleFormat == FormatNFMMono)
|
else if (m_running.m_sampleFormat == FormatNFMMono)
|
||||||
{
|
{
|
||||||
FixReal demod = m_squelchOpen ? (FixReal) (32768.0f * m_phaseDiscri.phaseDiscriminator(ci) * m_gain) : 0;
|
FixReal demod = m_squelchOpen ? (FixReal) (32768.0f * m_phaseDiscri.phaseDiscriminator(ci) * m_running.m_gain) : 0;
|
||||||
m_udpBufferMono->write(demod);
|
m_udpBufferMono->write(demod);
|
||||||
m_outMovingAverage.feed((demod * demod) / 1073741824.0);
|
m_outMovingAverage.feed((demod * demod) / 1073741824.0);
|
||||||
}
|
}
|
||||||
else if (m_sampleFormat == FormatLSBMono) // Monaural LSB
|
else if (m_running.m_sampleFormat == FormatLSBMono) // Monaural LSB
|
||||||
{
|
{
|
||||||
int n_out = UDPFilter->runSSB(ci, &sideband, false);
|
int n_out = UDPFilter->runSSB(ci, &sideband, false);
|
||||||
|
|
||||||
@ -225,13 +220,13 @@ void UDPSrc::feed(const SampleVector::const_iterator& begin, const SampleVector:
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < n_out; i++)
|
for (int i = 0; i < n_out; i++)
|
||||||
{
|
{
|
||||||
l = m_squelchOpen ? (sideband[i].real() + sideband[i].imag()) * 0.7 * m_gain : 0;
|
l = m_squelchOpen ? (sideband[i].real() + sideband[i].imag()) * 0.7 * m_running.m_gain : 0;
|
||||||
m_udpBufferMono->write(l);
|
m_udpBufferMono->write(l);
|
||||||
m_outMovingAverage.feed((l * l) / (1<<30));
|
m_outMovingAverage.feed((l * l) / (1<<30));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m_sampleFormat == FormatUSBMono) // Monaural USB
|
else if (m_running.m_sampleFormat == FormatUSBMono) // Monaural USB
|
||||||
{
|
{
|
||||||
int n_out = UDPFilter->runSSB(ci, &sideband, true);
|
int n_out = UDPFilter->runSSB(ci, &sideband, true);
|
||||||
|
|
||||||
@ -239,15 +234,15 @@ void UDPSrc::feed(const SampleVector::const_iterator& begin, const SampleVector:
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < n_out; i++)
|
for (int i = 0; i < n_out; i++)
|
||||||
{
|
{
|
||||||
l = m_squelchOpen ? (sideband[i].real() + sideband[i].imag()) * 0.7 * m_gain : 0;
|
l = m_squelchOpen ? (sideband[i].real() + sideband[i].imag()) * 0.7 * m_running.m_gain : 0;
|
||||||
m_udpBufferMono->write(l);
|
m_udpBufferMono->write(l);
|
||||||
m_outMovingAverage.feed((l * l) / (1<<30));
|
m_outMovingAverage.feed((l * l) / (1<<30));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m_sampleFormat == FormatAMMono)
|
else if (m_running.m_sampleFormat == FormatAMMono)
|
||||||
{
|
{
|
||||||
FixReal demod = m_squelchOpen ? (FixReal) (sqrt(inMagSq) * m_gain) : 0;
|
FixReal demod = m_squelchOpen ? (FixReal) (sqrt(inMagSq) * m_running.m_gain) : 0;
|
||||||
m_udpBufferMono->write(demod);
|
m_udpBufferMono->write(demod);
|
||||||
m_outMovingAverage.feed((demod * demod) / (1<<30));
|
m_outMovingAverage.feed((demod * demod) / (1<<30));
|
||||||
}
|
}
|
||||||
@ -255,9 +250,9 @@ void UDPSrc::feed(const SampleVector::const_iterator& begin, const SampleVector:
|
|||||||
{
|
{
|
||||||
if (m_squelchOpen)
|
if (m_squelchOpen)
|
||||||
{
|
{
|
||||||
Sample s(ci.real() * m_gain, ci.imag() * m_gain);
|
Sample s(ci.real() * m_running.m_gain, ci.imag() * m_running.m_gain);
|
||||||
m_udpBuffer->write(s);
|
m_udpBuffer->write(s);
|
||||||
m_outMovingAverage.feed((inMagSq*m_gain*m_gain) / (1<<30));
|
m_outMovingAverage.feed((inMagSq*m_running.m_gain*m_running.m_gain) / (1<<30));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -298,68 +293,38 @@ bool UDPSrc::handleMessage(const Message& cmd)
|
|||||||
{
|
{
|
||||||
DownChannelizer::MsgChannelizerNotification& notif = (DownChannelizer::MsgChannelizerNotification&) cmd;
|
DownChannelizer::MsgChannelizerNotification& notif = (DownChannelizer::MsgChannelizerNotification&) cmd;
|
||||||
|
|
||||||
m_settingsMutex.lock();
|
m_config.m_inputSampleRate = notif.getSampleRate();
|
||||||
|
m_config.m_inputFrequencyOffset = notif.getFrequencyOffset();
|
||||||
|
|
||||||
m_inputSampleRate = notif.getSampleRate();
|
apply(false);
|
||||||
m_nco.setFreq(-notif.getFrequencyOffset(), m_inputSampleRate);
|
|
||||||
m_interpolator.create(16, m_inputSampleRate, m_rfBandwidth / 2.0);
|
|
||||||
m_sampleDistanceRemain = m_inputSampleRate / m_outputSampleRate;
|
|
||||||
|
|
||||||
m_settingsMutex.unlock();
|
qDebug() << "UDPSrc::handleMessage: MsgChannelizerNotification: m_inputSampleRate: " << m_config.m_inputSampleRate
|
||||||
|
<< " frequencyOffset: " << notif.getFrequencyOffset();
|
||||||
|
|
||||||
qDebug() << "UDPSrc::handleMessage: MsgChannelizerNotification: m_inputSampleRate: " << m_inputSampleRate
|
return true;
|
||||||
<< " frequencyOffset: " << notif.getFrequencyOffset();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
else if (MsgUDPSrcConfigureImmediate::match(cmd))
|
else if (MsgUDPSrcConfigureImmediate::match(cmd))
|
||||||
{
|
{
|
||||||
MsgUDPSrcConfigureImmediate& cfg = (MsgUDPSrcConfigureImmediate&) cmd;
|
MsgUDPSrcConfigureImmediate& cfg = (MsgUDPSrcConfigureImmediate&) cmd;
|
||||||
|
|
||||||
m_settingsMutex.lock();
|
m_config.m_audioActive = cfg.getAudioActive();
|
||||||
|
m_config.m_audioStereo = cfg.getAudioStereo();
|
||||||
|
m_config.m_gain = cfg.getGain();
|
||||||
|
m_config.m_volume = cfg.getVolume();
|
||||||
|
m_config.m_squelch = CalcDb::powerFromdB(cfg.getSquelchDB());
|
||||||
|
m_config.m_squelchGate = cfg.getSquelchGate();
|
||||||
|
m_config.m_squelchEnabled = cfg.getSquelchEnabled();
|
||||||
|
|
||||||
if (cfg.getAudioActive() != m_audioActive)
|
apply(cfg.getForce());
|
||||||
{
|
|
||||||
m_audioActive = cfg.getAudioActive();
|
|
||||||
|
|
||||||
if (m_audioActive)
|
|
||||||
{
|
|
||||||
m_audioBufferFill = 0;
|
|
||||||
DSPEngine::instance()->addAudioSink(&m_audioFifo);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DSPEngine::instance()->removeAudioSink(&m_audioFifo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cfg.getAudioStereo() != m_audioStereo)
|
|
||||||
{
|
|
||||||
m_audioStereo = cfg.getAudioStereo();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cfg.getGain() != m_gain)
|
|
||||||
{
|
|
||||||
m_gain = cfg.getGain();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cfg.getVolume() != m_volume)
|
|
||||||
{
|
|
||||||
m_volume = cfg.getVolume();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_squelch = CalcDb::powerFromdB(cfg.getSquelchDB());
|
|
||||||
m_squelchEnabled = cfg.getSquelchEnabled();
|
|
||||||
|
|
||||||
m_settingsMutex.unlock();
|
|
||||||
|
|
||||||
qDebug() << "UDPSrc::handleMessage: MsgUDPSrcConfigureImmediate: "
|
qDebug() << "UDPSrc::handleMessage: MsgUDPSrcConfigureImmediate: "
|
||||||
<< " m_audioActive: " << m_audioActive
|
<< " m_audioActive: " << m_config.m_audioActive
|
||||||
<< " m_audioStereo: " << m_audioStereo
|
<< " m_audioStereo: " << m_config.m_audioStereo
|
||||||
<< " m_gain: " << m_gain
|
<< " m_gain: " << m_config.m_gain
|
||||||
<< " m_squelchEnabled: " << m_squelchEnabled
|
<< " m_squelchEnabled: " << m_config.m_squelchEnabled
|
||||||
<< " m_squelch: " << m_squelch
|
<< " m_squelch: " << m_config.m_squelch
|
||||||
<< " getSquelchDB: " << cfg.getSquelchDB();
|
<< " getSquelchDB: " << cfg.getSquelchDB()
|
||||||
|
<< " m_squelchGate" << m_config.m_squelchGate;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -368,67 +333,22 @@ bool UDPSrc::handleMessage(const Message& cmd)
|
|||||||
{
|
{
|
||||||
MsgUDPSrcConfigure& cfg = (MsgUDPSrcConfigure&) cmd;
|
MsgUDPSrcConfigure& cfg = (MsgUDPSrcConfigure&) cmd;
|
||||||
|
|
||||||
m_settingsMutex.lock();
|
m_config.m_sampleFormat = cfg.getSampleFormat();
|
||||||
|
m_config.m_outputSampleRate = cfg.getOutputSampleRate();
|
||||||
|
m_config.m_rfBandwidth = cfg.getRFBandwidth();
|
||||||
|
m_config.m_udpAddressStr = cfg.getUDPAddress();
|
||||||
|
m_config.m_udpPort = cfg.getUDPPort();
|
||||||
|
m_config.m_audioPort = cfg.getAudioPort();
|
||||||
|
m_config.m_fmDeviation = cfg.getFMDeviation();
|
||||||
|
|
||||||
m_sampleFormat = cfg.getSampleFormat();
|
apply(cfg.getForce());
|
||||||
m_outputSampleRate = cfg.getOutputSampleRate();
|
|
||||||
m_rfBandwidth = cfg.getRFBandwidth();
|
|
||||||
|
|
||||||
if (cfg.getUDPAddress() != m_udpAddressStr)
|
qDebug() << "UDPSrc::handleMessage: MsgUDPSrcConfigure: m_sampleFormat: " << m_config.m_sampleFormat
|
||||||
{
|
<< " m_outputSampleRate: " << m_config.m_outputSampleRate
|
||||||
m_udpAddressStr = cfg.getUDPAddress();
|
<< " m_rfBandwidth: " << m_config.m_rfBandwidth
|
||||||
m_udpBuffer->setAddress(m_udpAddressStr);
|
<< " m_udpAddressStr: " << m_config.m_udpAddressStr
|
||||||
m_udpBufferMono->setAddress(m_udpAddressStr);
|
<< " m_udpPort: " << m_config.m_udpPort
|
||||||
}
|
<< " m_audioPort: " << m_config.m_audioPort;
|
||||||
|
|
||||||
if (cfg.getUDPPort() != m_udpPort)
|
|
||||||
{
|
|
||||||
m_udpPort = cfg.getUDPPort();
|
|
||||||
m_udpBuffer->setPort(m_udpPort);
|
|
||||||
m_udpBufferMono->setPort(m_udpPort);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cfg.getAudioPort() != m_audioPort)
|
|
||||||
{
|
|
||||||
m_audioPort = cfg.getAudioPort();
|
|
||||||
|
|
||||||
disconnect(m_audioSocket, SIGNAL(readyRead()), this, SLOT(audioReadyRead()));
|
|
||||||
delete m_audioSocket;
|
|
||||||
m_audioSocket = new QUdpSocket(this);
|
|
||||||
|
|
||||||
if (m_audioSocket->bind(QHostAddress::LocalHost, m_audioPort))
|
|
||||||
{
|
|
||||||
connect(m_audioSocket, SIGNAL(readyRead()), this, SLOT(audioReadyRead()), Qt::QueuedConnection);
|
|
||||||
qDebug("UDPSrc::handleMessage: audio socket bound to port %d", m_audioPort);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
qWarning("UDPSrc::handleMessage: cannot bind audio socket");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cfg.getFMDeviation() != m_fmDeviation)
|
|
||||||
{
|
|
||||||
m_fmDeviation = cfg.getFMDeviation();
|
|
||||||
m_phaseDiscri.setFMScaling((float) m_outputSampleRate / (2.0f * m_fmDeviation));
|
|
||||||
}
|
|
||||||
|
|
||||||
m_interpolator.create(16, m_inputSampleRate, m_rfBandwidth / 2.0);
|
|
||||||
m_sampleDistanceRemain = m_inputSampleRate / m_outputSampleRate;
|
|
||||||
UDPFilter->create_filter(0.0, (m_rfBandwidth / 2.0) / m_outputSampleRate);
|
|
||||||
|
|
||||||
m_inMovingAverage.resize(m_outputSampleRate * 0.01, 1e-10); // 10 ms
|
|
||||||
m_outMovingAverage.resize(m_outputSampleRate * 0.01, 1e-10); // 10 ms
|
|
||||||
m_squelchThreshold = m_outputSampleRate * 0.05; // 50 ms
|
|
||||||
|
|
||||||
m_settingsMutex.unlock();
|
|
||||||
|
|
||||||
qDebug() << "UDPSrc::handleMessage: MsgUDPSrcConfigure: m_sampleFormat: " << m_sampleFormat
|
|
||||||
<< " m_outputSampleRate: " << m_outputSampleRate
|
|
||||||
<< " m_rfBandwidth: " << m_rfBandwidth
|
|
||||||
<< " m_udpAddressStr: " << m_udpAddressStr
|
|
||||||
<< " m_udpPort: " << m_udpPort
|
|
||||||
<< " m_audioPort: " << m_audioPort;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -455,6 +375,83 @@ bool UDPSrc::handleMessage(const Message& cmd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UDPSrc::apply(bool force)
|
||||||
|
{
|
||||||
|
m_settingsMutex.lock();
|
||||||
|
|
||||||
|
if ((m_config.m_inputSampleRate != m_running.m_inputSampleRate) ||
|
||||||
|
(m_config.m_inputFrequencyOffset != m_running.m_inputFrequencyOffset) ||
|
||||||
|
(m_config.m_rfBandwidth != m_running.m_rfBandwidth) ||
|
||||||
|
(m_config.m_outputSampleRate != m_running.m_outputSampleRate) || force)
|
||||||
|
{
|
||||||
|
m_nco.setFreq(-m_config.m_inputFrequencyOffset, m_config.m_inputSampleRate);
|
||||||
|
m_interpolator.create(16, m_config.m_inputSampleRate, m_config.m_rfBandwidth / 2.0);
|
||||||
|
m_sampleDistanceRemain = m_config.m_inputSampleRate / m_config.m_outputSampleRate;
|
||||||
|
|
||||||
|
m_squelchThreshold = m_config.m_outputSampleRate * m_config.m_squelchGate;
|
||||||
|
initSquelch(m_squelchOpen);
|
||||||
|
|
||||||
|
m_inMovingAverage.resize(m_config.m_outputSampleRate * 0.01, 1e-10); // 10 ms
|
||||||
|
m_outMovingAverage.resize(m_config.m_outputSampleRate * 0.01, 1e-10); // 10 ms
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((m_config.m_audioActive != m_config.m_audioActive) || force)
|
||||||
|
{
|
||||||
|
if (m_config.m_audioActive)
|
||||||
|
{
|
||||||
|
m_audioBufferFill = 0;
|
||||||
|
DSPEngine::instance()->addAudioSink(&m_audioFifo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DSPEngine::instance()->removeAudioSink(&m_audioFifo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((m_config.m_squelchGate != m_running.m_squelchGate) || force)
|
||||||
|
{
|
||||||
|
m_squelchThreshold = m_config.m_outputSampleRate * m_config.m_squelchGate;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((m_config.m_udpAddressStr != m_running.m_udpAddressStr) || force)
|
||||||
|
{
|
||||||
|
m_udpBuffer->setAddress(m_config.m_udpAddressStr);
|
||||||
|
m_udpBufferMono->setAddress(m_config.m_udpAddressStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((m_config.m_udpPort != m_running.m_udpPort) || force)
|
||||||
|
{
|
||||||
|
m_udpBuffer->setPort(m_config.m_udpPort);
|
||||||
|
m_udpBufferMono->setPort(m_config.m_udpPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((m_config.m_audioPort != m_running.m_audioPort) || force)
|
||||||
|
{
|
||||||
|
disconnect(m_audioSocket, SIGNAL(readyRead()), this, SLOT(audioReadyRead()));
|
||||||
|
delete m_audioSocket;
|
||||||
|
m_audioSocket = new QUdpSocket(this);
|
||||||
|
|
||||||
|
if (m_audioSocket->bind(QHostAddress::LocalHost, m_config.m_audioPort))
|
||||||
|
{
|
||||||
|
connect(m_audioSocket, SIGNAL(readyRead()), this, SLOT(audioReadyRead()), Qt::QueuedConnection);
|
||||||
|
qDebug("UDPSrc::handleMessage: audio socket bound to port %d", m_config.m_audioPort);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qWarning("UDPSrc::handleMessage: cannot bind audio socket");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((m_config.m_fmDeviation != m_running.m_fmDeviation) || force)
|
||||||
|
{
|
||||||
|
m_phaseDiscri.setFMScaling((float) m_config.m_outputSampleRate / (2.0f * m_config.m_fmDeviation));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_settingsMutex.unlock();
|
||||||
|
|
||||||
|
m_running = m_config;
|
||||||
|
}
|
||||||
|
|
||||||
void UDPSrc::audioReadyRead()
|
void UDPSrc::audioReadyRead()
|
||||||
{
|
{
|
||||||
while (m_audioSocket->hasPendingDatagrams())
|
while (m_audioSocket->hasPendingDatagrams())
|
||||||
@ -463,16 +460,16 @@ void UDPSrc::audioReadyRead()
|
|||||||
qint64 udpReadBytes = m_audioSocket->readDatagram(m_udpAudioBuf, pendingDataSize, 0, 0);
|
qint64 udpReadBytes = m_audioSocket->readDatagram(m_udpAudioBuf, pendingDataSize, 0, 0);
|
||||||
//qDebug("UDPSrc::audioReadyRead: %lld", udpReadBytes);
|
//qDebug("UDPSrc::audioReadyRead: %lld", udpReadBytes);
|
||||||
|
|
||||||
if (m_audioActive)
|
if (m_running.m_audioActive)
|
||||||
{
|
{
|
||||||
if (m_audioStereo)
|
if (m_running.m_audioStereo)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < udpReadBytes - 3; i += 4)
|
for (int i = 0; i < udpReadBytes - 3; i += 4)
|
||||||
{
|
{
|
||||||
qint16 l_sample = (qint16) *(&m_udpAudioBuf[i]);
|
qint16 l_sample = (qint16) *(&m_udpAudioBuf[i]);
|
||||||
qint16 r_sample = (qint16) *(&m_udpAudioBuf[i+2]);
|
qint16 r_sample = (qint16) *(&m_udpAudioBuf[i+2]);
|
||||||
m_audioBuffer[m_audioBufferFill].l = l_sample * m_volume;
|
m_audioBuffer[m_audioBufferFill].l = l_sample * m_running.m_volume;
|
||||||
m_audioBuffer[m_audioBufferFill].r = r_sample * m_volume;
|
m_audioBuffer[m_audioBufferFill].r = r_sample * m_running.m_volume;
|
||||||
++m_audioBufferFill;
|
++m_audioBufferFill;
|
||||||
|
|
||||||
if (m_audioBufferFill >= m_audioBuffer.size())
|
if (m_audioBufferFill >= m_audioBuffer.size())
|
||||||
@ -493,8 +490,8 @@ void UDPSrc::audioReadyRead()
|
|||||||
for (int i = 0; i < udpReadBytes - 1; i += 2)
|
for (int i = 0; i < udpReadBytes - 1; i += 2)
|
||||||
{
|
{
|
||||||
qint16 sample = (qint16) *(&m_udpAudioBuf[i]);
|
qint16 sample = (qint16) *(&m_udpAudioBuf[i]);
|
||||||
m_audioBuffer[m_audioBufferFill].l = sample * m_volume;
|
m_audioBuffer[m_audioBufferFill].l = sample * m_running.m_volume;
|
||||||
m_audioBuffer[m_audioBufferFill].r = sample * m_volume;
|
m_audioBuffer[m_audioBufferFill].r = sample * m_running.m_volume;
|
||||||
++m_audioBufferFill;
|
++m_audioBufferFill;
|
||||||
|
|
||||||
if (m_audioBufferFill >= m_audioBuffer.size())
|
if (m_audioBufferFill >= m_audioBuffer.size())
|
||||||
|
@ -67,14 +67,17 @@ public:
|
|||||||
int fmDeviation,
|
int fmDeviation,
|
||||||
QString& udpAddress,
|
QString& udpAddress,
|
||||||
int udpPort,
|
int udpPort,
|
||||||
int audioPort);
|
int audioPort,
|
||||||
|
bool force);
|
||||||
void configureImmediate(MessageQueue* messageQueue,
|
void configureImmediate(MessageQueue* messageQueue,
|
||||||
bool audioActive,
|
bool audioActive,
|
||||||
bool audioStereo,
|
bool audioStereo,
|
||||||
Real gain,
|
Real gain,
|
||||||
int volume,
|
int volume,
|
||||||
Real squelchDB,
|
Real squelchDB,
|
||||||
bool squelchEnabled);
|
Real squelchGate,
|
||||||
|
bool squelchEnabled,
|
||||||
|
bool force);
|
||||||
void setSpectrum(MessageQueue* messageQueue, bool enabled);
|
void setSpectrum(MessageQueue* messageQueue, bool enabled);
|
||||||
double getMagSq() const { return m_magsq; }
|
double getMagSq() const { return m_magsq; }
|
||||||
double getInMagSq() const { return m_inMagsq; }
|
double getInMagSq() const { return m_inMagsq; }
|
||||||
@ -102,6 +105,7 @@ protected:
|
|||||||
const QString& getUDPAddress() const { return m_udpAddress; }
|
const QString& getUDPAddress() const { return m_udpAddress; }
|
||||||
int getUDPPort() const { return m_udpPort; }
|
int getUDPPort() const { return m_udpPort; }
|
||||||
int getAudioPort() const { return m_audioPort; }
|
int getAudioPort() const { return m_audioPort; }
|
||||||
|
bool getForce() const { return m_force; }
|
||||||
|
|
||||||
static MsgUDPSrcConfigure* create(SampleFormat
|
static MsgUDPSrcConfigure* create(SampleFormat
|
||||||
sampleFormat,
|
sampleFormat,
|
||||||
@ -110,7 +114,8 @@ protected:
|
|||||||
int fmDeviation,
|
int fmDeviation,
|
||||||
QString& udpAddress,
|
QString& udpAddress,
|
||||||
int udpPort,
|
int udpPort,
|
||||||
int audioPort)
|
int audioPort,
|
||||||
|
bool force)
|
||||||
{
|
{
|
||||||
return new MsgUDPSrcConfigure(sampleFormat,
|
return new MsgUDPSrcConfigure(sampleFormat,
|
||||||
sampleRate,
|
sampleRate,
|
||||||
@ -118,7 +123,8 @@ protected:
|
|||||||
fmDeviation,
|
fmDeviation,
|
||||||
udpAddress,
|
udpAddress,
|
||||||
udpPort,
|
udpPort,
|
||||||
audioPort);
|
audioPort,
|
||||||
|
force);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -129,6 +135,7 @@ protected:
|
|||||||
QString m_udpAddress;
|
QString m_udpAddress;
|
||||||
int m_udpPort;
|
int m_udpPort;
|
||||||
int m_audioPort;
|
int m_audioPort;
|
||||||
|
bool m_force;
|
||||||
|
|
||||||
MsgUDPSrcConfigure(SampleFormat sampleFormat,
|
MsgUDPSrcConfigure(SampleFormat sampleFormat,
|
||||||
Real outputSampleRate,
|
Real outputSampleRate,
|
||||||
@ -136,7 +143,8 @@ protected:
|
|||||||
int fmDeviation,
|
int fmDeviation,
|
||||||
QString& udpAddress,
|
QString& udpAddress,
|
||||||
int udpPort,
|
int udpPort,
|
||||||
int audioPort) :
|
int audioPort,
|
||||||
|
bool force) :
|
||||||
Message(),
|
Message(),
|
||||||
m_sampleFormat(sampleFormat),
|
m_sampleFormat(sampleFormat),
|
||||||
m_outputSampleRate(outputSampleRate),
|
m_outputSampleRate(outputSampleRate),
|
||||||
@ -144,7 +152,8 @@ protected:
|
|||||||
m_fmDeviation(fmDeviation),
|
m_fmDeviation(fmDeviation),
|
||||||
m_udpAddress(udpAddress),
|
m_udpAddress(udpAddress),
|
||||||
m_udpPort(udpPort),
|
m_udpPort(udpPort),
|
||||||
m_audioPort(audioPort)
|
m_audioPort(audioPort),
|
||||||
|
m_force(force)
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -157,7 +166,9 @@ protected:
|
|||||||
bool getAudioActive() const { return m_audioActive; }
|
bool getAudioActive() const { return m_audioActive; }
|
||||||
bool getAudioStereo() const { return m_audioStereo; }
|
bool getAudioStereo() const { return m_audioStereo; }
|
||||||
Real getSquelchDB() const { return m_squelchDB; }
|
Real getSquelchDB() const { return m_squelchDB; }
|
||||||
|
Real getSquelchGate() const { return m_squelchGate; }
|
||||||
bool getSquelchEnabled() const { return m_squelchEnabled; }
|
bool getSquelchEnabled() const { return m_squelchEnabled; }
|
||||||
|
bool getForce() const { return m_force; }
|
||||||
|
|
||||||
static MsgUDPSrcConfigureImmediate* create(
|
static MsgUDPSrcConfigureImmediate* create(
|
||||||
bool audioActive,
|
bool audioActive,
|
||||||
@ -165,7 +176,9 @@ protected:
|
|||||||
int gain,
|
int gain,
|
||||||
int volume,
|
int volume,
|
||||||
Real squelchDB,
|
Real squelchDB,
|
||||||
bool squelchEnabled)
|
Real squelchGate,
|
||||||
|
bool squelchEnabled,
|
||||||
|
bool force)
|
||||||
{
|
{
|
||||||
return new MsgUDPSrcConfigureImmediate(
|
return new MsgUDPSrcConfigureImmediate(
|
||||||
audioActive,
|
audioActive,
|
||||||
@ -173,7 +186,9 @@ protected:
|
|||||||
gain,
|
gain,
|
||||||
volume,
|
volume,
|
||||||
squelchDB,
|
squelchDB,
|
||||||
squelchEnabled);
|
squelchGate,
|
||||||
|
squelchEnabled,
|
||||||
|
force);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -182,7 +197,9 @@ protected:
|
|||||||
bool m_audioActive;
|
bool m_audioActive;
|
||||||
bool m_audioStereo;
|
bool m_audioStereo;
|
||||||
Real m_squelchDB;
|
Real m_squelchDB;
|
||||||
|
Real m_squelchGate; // seconds
|
||||||
bool m_squelchEnabled;
|
bool m_squelchEnabled;
|
||||||
|
bool m_force;
|
||||||
|
|
||||||
MsgUDPSrcConfigureImmediate(
|
MsgUDPSrcConfigureImmediate(
|
||||||
bool audioActive,
|
bool audioActive,
|
||||||
@ -190,14 +207,18 @@ protected:
|
|||||||
Real gain,
|
Real gain,
|
||||||
int volume,
|
int volume,
|
||||||
Real squelchDB,
|
Real squelchDB,
|
||||||
bool squelchEnabled) :
|
Real squelchGate,
|
||||||
|
bool squelchEnabled,
|
||||||
|
bool force) :
|
||||||
Message(),
|
Message(),
|
||||||
m_gain(gain),
|
m_gain(gain),
|
||||||
m_volume(volume),
|
m_volume(volume),
|
||||||
m_audioActive(audioActive),
|
m_audioActive(audioActive),
|
||||||
m_audioStereo(audioStereo),
|
m_audioStereo(audioStereo),
|
||||||
m_squelchDB(squelchDB),
|
m_squelchDB(squelchDB),
|
||||||
m_squelchEnabled(squelchEnabled)
|
m_squelchGate(squelchGate),
|
||||||
|
m_squelchEnabled(squelchEnabled),
|
||||||
|
m_force(force)
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -221,23 +242,54 @@ protected:
|
|||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Config {
|
||||||
|
Real m_outputSampleRate;
|
||||||
|
SampleFormat m_sampleFormat;
|
||||||
|
Real m_inputSampleRate;
|
||||||
|
qint64 m_inputFrequencyOffset;
|
||||||
|
Real m_rfBandwidth;
|
||||||
|
int m_fmDeviation;
|
||||||
|
bool m_channelMute;
|
||||||
|
Real m_gain;
|
||||||
|
Real m_squelch; //!< squared magnitude
|
||||||
|
Real m_squelchGate; //!< seconds
|
||||||
|
bool m_squelchEnabled;
|
||||||
|
bool m_audioActive;
|
||||||
|
bool m_audioStereo;
|
||||||
|
int m_volume;
|
||||||
|
|
||||||
|
QString m_udpAddressStr;
|
||||||
|
quint16 m_udpPort;
|
||||||
|
quint16 m_audioPort;
|
||||||
|
|
||||||
|
Config() :
|
||||||
|
m_outputSampleRate(48000),
|
||||||
|
m_sampleFormat(FormatS16LE),
|
||||||
|
m_inputSampleRate(48000),
|
||||||
|
m_inputFrequencyOffset(0),
|
||||||
|
m_rfBandwidth(12500),
|
||||||
|
m_fmDeviation(2500),
|
||||||
|
m_channelMute(false),
|
||||||
|
m_gain(1.0),
|
||||||
|
m_squelch(1e-6),
|
||||||
|
m_squelchGate(0.0),
|
||||||
|
m_squelchEnabled(true),
|
||||||
|
m_audioActive(false),
|
||||||
|
m_audioStereo(false),
|
||||||
|
m_volume(20),
|
||||||
|
m_udpAddressStr("127.0.0.1"),
|
||||||
|
m_udpPort(9999),
|
||||||
|
m_audioPort(9998)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
Config m_config;
|
||||||
|
Config m_running;
|
||||||
|
|
||||||
MessageQueue* m_uiMessageQueue;
|
MessageQueue* m_uiMessageQueue;
|
||||||
UDPSrcGUI* m_udpSrcGUI;
|
UDPSrcGUI* m_udpSrcGUI;
|
||||||
QUdpSocket *m_audioSocket;
|
QUdpSocket *m_audioSocket;
|
||||||
|
|
||||||
int m_inputSampleRate;
|
|
||||||
|
|
||||||
int m_sampleFormat;
|
|
||||||
Real m_outputSampleRate;
|
|
||||||
Real m_rfBandwidth;
|
|
||||||
QString m_udpAddressStr;
|
|
||||||
quint16 m_udpPort;
|
|
||||||
quint16 m_audioPort;
|
|
||||||
Real m_gain;
|
|
||||||
bool m_audioActive;
|
|
||||||
bool m_audioStereo;
|
|
||||||
int m_volume;
|
|
||||||
int m_fmDeviation;
|
|
||||||
double m_magsq;
|
double m_magsq;
|
||||||
double m_inMagsq;
|
double m_inMagsq;
|
||||||
MovingAverage<double> m_outMovingAverage;
|
MovingAverage<double> m_outMovingAverage;
|
||||||
@ -270,34 +322,54 @@ protected:
|
|||||||
|
|
||||||
PhaseDiscriminators m_phaseDiscri;
|
PhaseDiscriminators m_phaseDiscri;
|
||||||
|
|
||||||
Real m_squelch; //!< squared magnitude
|
|
||||||
bool m_squelchEnabled;
|
|
||||||
bool m_squelchOpen;
|
bool m_squelchOpen;
|
||||||
int m_squelchOpenCount;
|
int m_squelchOpenCount;
|
||||||
int m_squelchCloseCount;
|
int m_squelchCloseCount;
|
||||||
int m_squelchThreshold;
|
int m_squelchThreshold; //!< number of samples computed from given gate
|
||||||
|
|
||||||
QMutex m_settingsMutex;
|
QMutex m_settingsMutex;
|
||||||
|
|
||||||
|
void apply(bool force);
|
||||||
|
|
||||||
inline void calculateSquelch(double value)
|
inline void calculateSquelch(double value)
|
||||||
{
|
{
|
||||||
if ((!m_squelchEnabled) || (value > m_squelch))
|
if ((!m_running.m_squelchEnabled) || (value > m_running.m_squelch))
|
||||||
{
|
{
|
||||||
if (m_squelchOpenCount < m_squelchThreshold) {
|
if (m_squelchThreshold == 0)
|
||||||
m_squelchOpenCount++;
|
{
|
||||||
} else {
|
|
||||||
m_squelchCloseCount = m_squelchThreshold;
|
|
||||||
m_squelchOpen = true;
|
m_squelchOpen = true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (m_squelchOpenCount < m_squelchThreshold)
|
||||||
|
{
|
||||||
|
m_squelchOpenCount++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_squelchCloseCount = m_squelchThreshold;
|
||||||
|
m_squelchOpen = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (m_squelchCloseCount > 0) {
|
if (m_squelchThreshold == 0)
|
||||||
m_squelchCloseCount--;
|
{
|
||||||
} else {
|
|
||||||
m_squelchOpenCount = 0;
|
|
||||||
m_squelchOpen = false;
|
m_squelchOpen = false;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (m_squelchCloseCount > 0)
|
||||||
|
{
|
||||||
|
m_squelchCloseCount--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_squelchOpenCount = 0;
|
||||||
|
m_squelchOpen = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,8 +197,8 @@ bool UDPSrcGUI::deserialize(const QByteArray& data)
|
|||||||
blockApplySettings(false);
|
blockApplySettings(false);
|
||||||
m_channelMarker.blockSignals(false);
|
m_channelMarker.blockSignals(false);
|
||||||
|
|
||||||
applySettingsImmediate();
|
applySettingsImmediate(true);
|
||||||
applySettings();
|
applySettings(true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -297,8 +297,8 @@ UDPSrcGUI::UDPSrcGUI(PluginAPI* pluginAPI, DeviceSourceAPI *deviceAPI, QWidget*
|
|||||||
ui->spectrumGUI->setBuddies(m_spectrumVis->getInputMessageQueue(), m_spectrumVis, ui->glSpectrum);
|
ui->spectrumGUI->setBuddies(m_spectrumVis->getInputMessageQueue(), m_spectrumVis, ui->glSpectrum);
|
||||||
|
|
||||||
displaySettings();
|
displaySettings();
|
||||||
applySettingsImmediate();
|
applySettingsImmediate(true);
|
||||||
applySettings();
|
applySettings(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
UDPSrcGUI::~UDPSrcGUI()
|
UDPSrcGUI::~UDPSrcGUI()
|
||||||
@ -323,9 +323,10 @@ void UDPSrcGUI::displaySettings()
|
|||||||
ui->gainText->setText(tr("%1").arg(ui->gain->value()/10.0, 0, 'f', 1));
|
ui->gainText->setText(tr("%1").arg(ui->gain->value()/10.0, 0, 'f', 1));
|
||||||
ui->volumeText->setText(QString("%1").arg(ui->volume->value()));
|
ui->volumeText->setText(QString("%1").arg(ui->volume->value()));
|
||||||
ui->squelchText->setText(tr("%1").arg(ui->squelch->value()*1.0, 0, 'f', 0));
|
ui->squelchText->setText(tr("%1").arg(ui->squelch->value()*1.0, 0, 'f', 0));
|
||||||
|
ui->squelchGateText->setText(tr("%1").arg(ui->squelchGate->value()*10.0, 0, 'f', 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void UDPSrcGUI::applySettingsImmediate()
|
void UDPSrcGUI::applySettingsImmediate(bool force)
|
||||||
{
|
{
|
||||||
if (m_doApplySettings)
|
if (m_doApplySettings)
|
||||||
{
|
{
|
||||||
@ -340,12 +341,14 @@ void UDPSrcGUI::applySettingsImmediate()
|
|||||||
m_gain,
|
m_gain,
|
||||||
m_volume,
|
m_volume,
|
||||||
ui->squelch->value() * 1.0f,
|
ui->squelch->value() * 1.0f,
|
||||||
ui->squelch->value() != -100);
|
ui->squelchGate->value() * 0.01f,
|
||||||
|
ui->squelch->value() != -100,
|
||||||
|
force);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void UDPSrcGUI::applySettings()
|
void UDPSrcGUI::applySettings(bool force)
|
||||||
{
|
{
|
||||||
if (m_doApplySettings)
|
if (m_doApplySettings)
|
||||||
{
|
{
|
||||||
@ -461,7 +464,8 @@ void UDPSrcGUI::applySettings()
|
|||||||
fmDeviation,
|
fmDeviation,
|
||||||
m_udpAddress,
|
m_udpAddress,
|
||||||
udpPort,
|
udpPort,
|
||||||
audioPort);
|
audioPort,
|
||||||
|
force);
|
||||||
|
|
||||||
ui->applyBtn->setEnabled(false);
|
ui->applyBtn->setEnabled(false);
|
||||||
}
|
}
|
||||||
@ -554,6 +558,12 @@ void UDPSrcGUI::on_squelch_valueChanged(int value)
|
|||||||
applySettingsImmediate();
|
applySettingsImmediate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UDPSrcGUI::on_squelchGate_valueChanged(int value)
|
||||||
|
{
|
||||||
|
ui->squelchGateText->setText(tr("%1").arg(value*10.0, 0, 'f', 0));
|
||||||
|
applySettingsImmediate();
|
||||||
|
}
|
||||||
|
|
||||||
void UDPSrcGUI::onWidgetRolled(QWidget* widget, bool rollDown)
|
void UDPSrcGUI::onWidgetRolled(QWidget* widget, bool rollDown)
|
||||||
{
|
{
|
||||||
if ((widget == ui->spectrumBox) && (m_udpSrc != 0))
|
if ((widget == ui->spectrumBox) && (m_udpSrc != 0))
|
||||||
|
@ -75,6 +75,7 @@ private slots:
|
|||||||
void on_gain_valueChanged(int value);
|
void on_gain_valueChanged(int value);
|
||||||
void on_volume_valueChanged(int value);
|
void on_volume_valueChanged(int value);
|
||||||
void on_squelch_valueChanged(int value);
|
void on_squelch_valueChanged(int value);
|
||||||
|
void on_squelchGate_valueChanged(int value);
|
||||||
void tick();
|
void tick();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -111,8 +112,8 @@ private:
|
|||||||
virtual ~UDPSrcGUI();
|
virtual ~UDPSrcGUI();
|
||||||
|
|
||||||
void blockApplySettings(bool block);
|
void blockApplySettings(bool block);
|
||||||
void applySettings();
|
void applySettings(bool force = false);
|
||||||
void applySettingsImmediate();
|
void applySettingsImmediate(bool force = false);
|
||||||
void displaySettings();
|
void displaySettings();
|
||||||
|
|
||||||
void leaveEvent(QEvent*);
|
void leaveEvent(QEvent*);
|
||||||
|
@ -236,6 +236,38 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="inputPower">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Input power (dB) to which squelch applies</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>-100.0</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="0">
|
<item row="6" column="0">
|
||||||
@ -637,18 +669,40 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="inputPower">
|
<widget class="QDial" name="squelchGate">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>22</width>
|
||||||
|
<height>22</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Squelch gate (ms)</string>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>50</number>
|
||||||
|
</property>
|
||||||
|
<property name="pageStep">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="squelchGateText">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>40</width>
|
<width>24</width>
|
||||||
<height>0</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Input power (dB) to which squelch applies</string>
|
<string>Squelch gate (ms)</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>-100.0</string>
|
<string>000</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user