mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-15 12:51:49 -05:00
Channel analyzer NG: use settings
This commit is contained in:
parent
d6f5de1ad7
commit
524c7fbe7c
@ -48,13 +48,15 @@ ChannelAnalyzerNG::ChannelAnalyzerNG(DeviceSourceAPI *deviceAPI) :
|
||||
m_useInterpolator = false;
|
||||
m_interpolatorDistance = 1.0f;
|
||||
m_interpolatorDistanceRemain = 0.0f;
|
||||
SSBFilter = new fftfilt(m_config.m_LowCutoff / m_config.m_inputSampleRate, m_config.m_Bandwidth / m_config.m_inputSampleRate, ssbFftLen);
|
||||
DSBFilter = new fftfilt(m_config.m_Bandwidth / m_config.m_inputSampleRate, 2*ssbFftLen);
|
||||
m_inputSampleRate = 48000;
|
||||
m_inputFrequencyOffset = 0;
|
||||
SSBFilter = new fftfilt(m_settings.m_lowCutoff / m_inputSampleRate, m_settings.m_bandwidth / m_inputSampleRate, ssbFftLen);
|
||||
DSBFilter = new fftfilt(m_settings.m_bandwidth / m_inputSampleRate, 2*ssbFftLen);
|
||||
//m_pll.computeCoefficients(0.05f, 0.707f, 1000.0f); // bandwidth, damping factor, loop gain
|
||||
m_pll.computeCoefficients(0.002f, 0.5f, 10.0f); // bandwidth, damping factor, loop gain
|
||||
m_fll.setSampleRate(48000);
|
||||
|
||||
apply(true);
|
||||
applyChannelSettings(m_inputSampleRate, m_inputFrequencyOffset, true);
|
||||
applySettings(m_settings, true);
|
||||
|
||||
m_channelizer = new DownChannelizer(this);
|
||||
m_threadedChannelizer = new ThreadedBasebandSampleSink(m_channelizer, this);
|
||||
@ -114,7 +116,7 @@ void ChannelAnalyzerNG::feed(const SampleVector::const_iterator& begin, const Sa
|
||||
|
||||
if(m_sampleSink != 0)
|
||||
{
|
||||
m_sampleSink->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), m_running.m_ssb); // m_ssb = positive only
|
||||
m_sampleSink->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), m_settings.m_ssb); // m_ssb = positive only
|
||||
}
|
||||
|
||||
m_sampleBuffer.clear();
|
||||
@ -122,8 +124,81 @@ void ChannelAnalyzerNG::feed(const SampleVector::const_iterator& begin, const Sa
|
||||
m_settingsMutex.unlock();
|
||||
}
|
||||
|
||||
void ChannelAnalyzerNG::processOneSample(Complex& c, fftfilt::cmplx *sideband)
|
||||
{
|
||||
int n_out;
|
||||
int decim = 1<<m_settings.m_spanLog2;
|
||||
|
||||
if (m_settings.m_ssb) {
|
||||
n_out = SSBFilter->runSSB(c, &sideband, m_usb);
|
||||
} else {
|
||||
n_out = DSBFilter->runDSB(c, &sideband);
|
||||
}
|
||||
|
||||
for (int i = 0; i < n_out; i++)
|
||||
{
|
||||
// Downsample by 2^(m_scaleLog2 - 1) for SSB band spectrum display
|
||||
// smart decimation with bit gain using float arithmetic (23 bits significand)
|
||||
|
||||
m_sum += sideband[i];
|
||||
|
||||
if (!(m_undersampleCount++ & (decim - 1))) // counter LSB bit mask for decimation by 2^(m_scaleLog2 - 1)
|
||||
{
|
||||
m_sum /= decim;
|
||||
Real re = m_sum.real() / SDR_RX_SCALED;
|
||||
Real im = m_sum.imag() / SDR_RX_SCALED;
|
||||
m_magsq = re*re + im*im;
|
||||
Real mixI = 1.0f;
|
||||
Real mixQ = 0.0f;
|
||||
|
||||
if (m_settings.m_pll)
|
||||
{
|
||||
if (m_settings.m_fll)
|
||||
{
|
||||
m_fll.feed(re, im);
|
||||
// Use -fPLL to mix (exchange PLL real and image in the complex multiplication)
|
||||
mixI = m_sum.real() * m_fll.getImag() - m_sum.imag() * m_fll.getReal();
|
||||
mixQ = m_sum.real() * m_fll.getReal() + m_sum.imag() * m_fll.getImag();
|
||||
// mixI = m_fll.getReal() * SDR_RX_SCALED;
|
||||
// mixQ = m_fll.getImag() * SDR_RX_SCALED;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pll.feed(re, im);
|
||||
// Use -fPLL to mix (exchange PLL real and image in the complex multiplication)
|
||||
mixI = m_sum.real() * m_pll.getImag() - m_sum.imag() * m_pll.getReal();
|
||||
mixQ = m_sum.real() * m_pll.getReal() + m_sum.imag() * m_pll.getImag();
|
||||
}
|
||||
|
||||
if (m_settings.m_ssb & !m_usb)
|
||||
{ // invert spectrum for LSB
|
||||
m_sampleBuffer.push_back(Sample(mixQ, mixI));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sampleBuffer.push_back(Sample(mixI, mixQ));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_settings.m_ssb & !m_usb)
|
||||
{ // invert spectrum for LSB
|
||||
m_sampleBuffer.push_back(Sample(m_sum.imag(), m_sum.real()));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sampleBuffer.push_back(Sample(m_sum.real(), m_sum.imag()));
|
||||
}
|
||||
}
|
||||
|
||||
m_sum = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ChannelAnalyzerNG::start()
|
||||
{
|
||||
applyChannelSettings(m_inputSampleRate, m_inputFrequencyOffset, true);
|
||||
}
|
||||
|
||||
void ChannelAnalyzerNG::stop()
|
||||
@ -132,20 +207,14 @@ void ChannelAnalyzerNG::stop()
|
||||
|
||||
bool ChannelAnalyzerNG::handleMessage(const Message& cmd)
|
||||
{
|
||||
qDebug() << "ChannelAnalyzerNG::handleMessage: " << cmd.getIdentifier();
|
||||
|
||||
if (DownChannelizer::MsgChannelizerNotification::match(cmd))
|
||||
{
|
||||
DownChannelizer::MsgChannelizerNotification& notif = (DownChannelizer::MsgChannelizerNotification&) cmd;
|
||||
qDebug() << "ChannelAnalyzerNG::handleMessage: DownChannelizer::MsgChannelizerNotification:"
|
||||
<< " sampleRate: " << notif.getSampleRate()
|
||||
<< " frequencyOffset: " << notif.getFrequencyOffset();
|
||||
|
||||
m_config.m_inputSampleRate = notif.getSampleRate();
|
||||
m_config.m_frequency = notif.getFrequencyOffset();
|
||||
|
||||
qDebug() << "ChannelAnalyzerNG::handleMessage: MsgChannelizerNotification:"
|
||||
<< " m_sampleRate: " << m_config.m_inputSampleRate
|
||||
<< " frequencyOffset: " << m_config.m_frequency;
|
||||
|
||||
apply();
|
||||
applyChannelSettings(notif.getSampleRate(), notif.getFrequencyOffset());
|
||||
|
||||
if (getMessageQueueToGUI())
|
||||
{
|
||||
@ -158,37 +227,25 @@ bool ChannelAnalyzerNG::handleMessage(const Message& cmd)
|
||||
else if (MsgConfigureChannelizer::match(cmd))
|
||||
{
|
||||
MsgConfigureChannelizer& cfg = (MsgConfigureChannelizer&) cmd;
|
||||
qDebug() << "ChannelAnalyzerNG::handleMessage: MsgConfigureChannelizer:"
|
||||
<< " sampleRate: " << cfg.getSampleRate()
|
||||
<< " centerFrequency: " << cfg.getCenterFrequency();
|
||||
|
||||
m_channelizer->configure(m_channelizer->getInputMessageQueue(),
|
||||
cfg.getSampleRate(),
|
||||
cfg.getCenterFrequency());
|
||||
cfg.getSampleRate(),
|
||||
cfg.getCenterFrequency());
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (MsgConfigureChannelAnalyzerOld::match(cmd))
|
||||
{
|
||||
MsgConfigureChannelAnalyzerOld& cfg = (MsgConfigureChannelAnalyzerOld&) cmd;
|
||||
else if (MsgConfigureChannelAnalyzer::match(cmd))
|
||||
{
|
||||
qDebug("ChannelAnalyzerNG::handleMessage: MsgConfigureChannelAnalyzer");
|
||||
MsgConfigureChannelAnalyzer& cfg = (MsgConfigureChannelAnalyzer&) cmd;
|
||||
|
||||
m_config.m_channelSampleRate = cfg.getChannelSampleRate();
|
||||
m_config.m_Bandwidth = cfg.getBandwidth();
|
||||
m_config.m_LowCutoff = cfg.getLoCutoff();
|
||||
m_config.m_spanLog2 = cfg.getSpanLog2();
|
||||
m_config.m_ssb = cfg.getSSB();
|
||||
m_config.m_pll = cfg.getPLL();
|
||||
m_config.m_fll = cfg.getFLL();
|
||||
m_config.m_pllPskOrder = cfg.getPLLPSKOrder();
|
||||
applySettings(cfg.getSettings(), cfg.getForce());
|
||||
|
||||
qDebug() << "ChannelAnalyzerNG::handleMessage: MsgConfigureChannelAnalyzer:"
|
||||
<< " m_channelSampleRate: " << m_config.m_channelSampleRate
|
||||
<< " m_Bandwidth: " << m_config.m_Bandwidth
|
||||
<< " m_LowCutoff: " << m_config.m_LowCutoff
|
||||
<< " m_spanLog2: " << m_config.m_spanLog2
|
||||
<< " m_ssb: " << m_config.m_ssb
|
||||
<< " m_pll: " << m_config.m_pll
|
||||
<< " m_fll: " << m_config.m_fll
|
||||
<< " m_pllPskOrder: " << m_config.m_pllPskOrder;
|
||||
|
||||
apply();
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_sampleSink != 0)
|
||||
@ -202,106 +259,6 @@ bool ChannelAnalyzerNG::handleMessage(const Message& cmd)
|
||||
}
|
||||
}
|
||||
|
||||
void ChannelAnalyzerNG::apply(bool force)
|
||||
{
|
||||
if ((m_running.m_frequency != m_config.m_frequency) ||
|
||||
(m_running.m_inputSampleRate != m_config.m_inputSampleRate) ||
|
||||
force)
|
||||
{
|
||||
m_nco.setFreq(-m_config.m_frequency, m_config.m_inputSampleRate);
|
||||
}
|
||||
|
||||
if ((m_running.m_inputSampleRate != m_config.m_inputSampleRate) ||
|
||||
(m_running.m_channelSampleRate != m_config.m_channelSampleRate) ||
|
||||
force)
|
||||
{
|
||||
m_settingsMutex.lock();
|
||||
m_interpolator.create(16, m_config.m_inputSampleRate, m_config.m_inputSampleRate / 2.2);
|
||||
m_interpolatorDistanceRemain = 0.0f;
|
||||
m_interpolatorDistance = (Real) m_config.m_inputSampleRate / (Real) m_config.m_channelSampleRate;
|
||||
m_useInterpolator = (m_config.m_inputSampleRate != m_config.m_channelSampleRate); // optim
|
||||
m_settingsMutex.unlock();
|
||||
}
|
||||
|
||||
if ((m_running.m_channelSampleRate != m_config.m_channelSampleRate) ||
|
||||
(m_running.m_Bandwidth != m_config.m_Bandwidth) ||
|
||||
(m_running.m_LowCutoff != m_config.m_LowCutoff) ||
|
||||
force)
|
||||
{
|
||||
float bandwidth = m_config.m_Bandwidth;
|
||||
float lowCutoff = m_config.m_LowCutoff;
|
||||
|
||||
if (bandwidth < 0)
|
||||
{
|
||||
bandwidth = -bandwidth;
|
||||
lowCutoff = -lowCutoff;
|
||||
m_usb = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_usb = true;
|
||||
}
|
||||
|
||||
if (bandwidth < 100.0f)
|
||||
{
|
||||
bandwidth = 100.0f;
|
||||
lowCutoff = 0;
|
||||
}
|
||||
|
||||
m_settingsMutex.lock();
|
||||
|
||||
SSBFilter->create_filter(lowCutoff / m_config.m_channelSampleRate, bandwidth / m_config.m_channelSampleRate);
|
||||
DSBFilter->create_dsb_filter(bandwidth / m_config.m_channelSampleRate);
|
||||
|
||||
m_settingsMutex.unlock();
|
||||
}
|
||||
|
||||
if ((m_running.m_channelSampleRate != m_config.m_channelSampleRate) ||
|
||||
(m_running.m_spanLog2 != m_config.m_spanLog2) || force)
|
||||
{
|
||||
int sampleRate = m_running.m_channelSampleRate / (1<<m_running.m_spanLog2);
|
||||
m_pll.setSampleRate(sampleRate);
|
||||
m_fll.setSampleRate(sampleRate);
|
||||
}
|
||||
|
||||
if (m_running.m_pll != m_config.m_pll || force)
|
||||
{
|
||||
if (m_config.m_pll)
|
||||
{
|
||||
m_pll.reset();
|
||||
m_fll.reset();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_running.m_fll != m_config.m_fll || force)
|
||||
{
|
||||
if (m_config.m_fll) {
|
||||
m_fll.reset();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_running.m_pllPskOrder != m_config.m_pllPskOrder || force)
|
||||
{
|
||||
if (m_config.m_pllPskOrder < 5) {
|
||||
m_pll.setPskOrder(m_config.m_pllPskOrder);
|
||||
}
|
||||
}
|
||||
|
||||
m_running.m_frequency = m_config.m_frequency;
|
||||
m_running.m_channelSampleRate = m_config.m_channelSampleRate;
|
||||
m_running.m_inputSampleRate = m_config.m_inputSampleRate;
|
||||
m_running.m_Bandwidth = m_config.m_Bandwidth;
|
||||
m_running.m_LowCutoff = m_config.m_LowCutoff;
|
||||
|
||||
//m_settingsMutex.lock();
|
||||
m_running.m_spanLog2 = m_config.m_spanLog2;
|
||||
m_running.m_ssb = m_config.m_ssb;
|
||||
m_running.m_pll = m_config.m_pll;
|
||||
m_running.m_fll = m_config.m_fll;
|
||||
m_running.m_pllPskOrder = m_config.m_pllPskOrder;
|
||||
//m_settingsMutex.unlock();
|
||||
}
|
||||
|
||||
void ChannelAnalyzerNG::applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force)
|
||||
{
|
||||
qDebug() << "ChannelAnalyzerNG::applyChannelSettings:"
|
||||
@ -338,6 +295,9 @@ void ChannelAnalyzerNG::applyChannelSettings(int inputSampleRate, int inputFrequ
|
||||
|
||||
void ChannelAnalyzerNG::setFilters(int sampleRate, float bandwidth, float lowCutoff)
|
||||
{
|
||||
qDebug("ChannelAnalyzerNG::setFilters: sampleRate: %d bandwidth: %f lowCutoff: %f",
|
||||
sampleRate, bandwidth, lowCutoff);
|
||||
|
||||
if (bandwidth < 0)
|
||||
{
|
||||
bandwidth = -bandwidth;
|
||||
@ -361,6 +321,17 @@ void ChannelAnalyzerNG::setFilters(int sampleRate, float bandwidth, float lowCut
|
||||
|
||||
void ChannelAnalyzerNG::applySettings(const ChannelAnalyzerNGSettings& settings, bool force)
|
||||
{
|
||||
qDebug() << "ChannelAnalyzerNG::applySettings:"
|
||||
<< " m_downSample: " << settings.m_downSample
|
||||
<< " m_downSampleRate: " << settings.m_downSampleRate
|
||||
<< " m_bandwidth: " << settings.m_bandwidth
|
||||
<< " m_lowCutoff: " << settings.m_lowCutoff
|
||||
<< " m_spanLog2: " << settings.m_spanLog2
|
||||
<< " m_ssb: " << settings.m_ssb
|
||||
<< " m_pll: " << settings.m_pll
|
||||
<< " m_fll: " << settings.m_fll
|
||||
<< " m_pllPskOrder: " << settings.m_pllPskOrder;
|
||||
|
||||
if ((settings.m_downSampleRate != m_settings.m_downSampleRate) || force)
|
||||
{
|
||||
m_settingsMutex.lock();
|
||||
@ -392,7 +363,7 @@ void ChannelAnalyzerNG::applySettings(const ChannelAnalyzerNGSettings& settings,
|
||||
|
||||
if ((settings.m_spanLog2 != m_settings.m_spanLog2) || force)
|
||||
{
|
||||
int sampleRate = (settings.m_downSample ? settings.m_downSampleRate : m_inputSampleRate) / (1<<m_running.m_spanLog2);
|
||||
int sampleRate = (settings.m_downSample ? settings.m_downSampleRate : m_inputSampleRate) / (1<<m_settings.m_spanLog2);
|
||||
m_pll.setSampleRate(sampleRate);
|
||||
m_fll.setSampleRate(sampleRate);
|
||||
}
|
||||
|
@ -184,10 +184,10 @@ public:
|
||||
unsigned int pllPskOrder);
|
||||
|
||||
DownChannelizer *getChannelizer() { return m_channelizer; }
|
||||
int getInputSampleRate() const { return m_running.m_inputSampleRate; }
|
||||
int getChannelSampleRate() const { return m_running.m_channelSampleRate; }
|
||||
int getInputSampleRate() const { return m_inputSampleRate; }
|
||||
int getChannelSampleRate() const { return m_settings.m_downSample ? m_settings.m_downSampleRate : m_inputSampleRate; }
|
||||
double getMagSq() const { return m_magsq; }
|
||||
bool isPllLocked() const { return m_running.m_pll && m_pll.locked(); }
|
||||
bool isPllLocked() const { return m_settings.m_pll && m_pll.locked(); }
|
||||
Real getPllFrequency() const { return m_pll.getFreq(); }
|
||||
Real getPllDeltaPhase() const { return m_pll.getDeltaPhi(); }
|
||||
Real getPllPhase() const { return m_pll.getPhiHat(); }
|
||||
@ -199,7 +199,7 @@ public:
|
||||
|
||||
virtual void getIdentifier(QString& id) { id = objectName(); }
|
||||
virtual void getTitle(QString& title) { title = objectName(); }
|
||||
virtual qint64 getCenterFrequency() const { return m_running.m_frequency; }
|
||||
virtual qint64 getCenterFrequency() const { return m_settings.m_frequency; }
|
||||
|
||||
virtual QByteArray serialize() const { return QByteArray(); }
|
||||
virtual bool deserialize(const QByteArray& data __attribute__((unused))) { return false; }
|
||||
@ -208,37 +208,6 @@ public:
|
||||
static const QString m_channelId;
|
||||
|
||||
private:
|
||||
|
||||
struct Config
|
||||
{
|
||||
int m_frequency;
|
||||
int m_inputSampleRate;
|
||||
int m_channelSampleRate;
|
||||
Real m_Bandwidth;
|
||||
Real m_LowCutoff;
|
||||
int m_spanLog2;
|
||||
bool m_ssb;
|
||||
bool m_pll;
|
||||
bool m_fll;
|
||||
unsigned int m_pllPskOrder;
|
||||
|
||||
Config() :
|
||||
m_frequency(0),
|
||||
m_inputSampleRate(96000),
|
||||
m_channelSampleRate(96000),
|
||||
m_Bandwidth(5000),
|
||||
m_LowCutoff(300),
|
||||
m_spanLog2(3),
|
||||
m_ssb(false),
|
||||
m_pll(false),
|
||||
m_fll(false),
|
||||
m_pllPskOrder(1)
|
||||
{}
|
||||
};
|
||||
|
||||
Config m_config;
|
||||
Config m_running;
|
||||
|
||||
DeviceSourceAPI *m_deviceAPI;
|
||||
ThreadedBasebandSampleSink* m_threadedChannelizer;
|
||||
DownChannelizer* m_channelizer;
|
||||
@ -266,85 +235,11 @@ private:
|
||||
SampleVector m_sampleBuffer;
|
||||
QMutex m_settingsMutex;
|
||||
|
||||
void apply(bool force = false);
|
||||
void applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force);
|
||||
// void apply(bool force = false);
|
||||
void applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force = false);
|
||||
void applySettings(const ChannelAnalyzerNGSettings& settings, bool force = false);
|
||||
void setFilters(int sampleRate, float bandwidth, float lowCutoff);
|
||||
|
||||
void processOneSample(Complex& c, fftfilt::cmplx *sideband)
|
||||
{
|
||||
int n_out;
|
||||
int decim = 1<<m_running.m_spanLog2;
|
||||
|
||||
if (m_running.m_ssb)
|
||||
{
|
||||
n_out = SSBFilter->runSSB(c, &sideband, m_usb);
|
||||
}
|
||||
else
|
||||
{
|
||||
n_out = DSBFilter->runDSB(c, &sideband);
|
||||
}
|
||||
|
||||
for (int i = 0; i < n_out; i++)
|
||||
{
|
||||
// Downsample by 2^(m_scaleLog2 - 1) for SSB band spectrum display
|
||||
// smart decimation with bit gain using float arithmetic (23 bits significand)
|
||||
|
||||
m_sum += sideband[i];
|
||||
|
||||
if (!(m_undersampleCount++ & (decim - 1))) // counter LSB bit mask for decimation by 2^(m_scaleLog2 - 1)
|
||||
{
|
||||
m_sum /= decim;
|
||||
Real re = m_sum.real() / SDR_RX_SCALED;
|
||||
Real im = m_sum.imag() / SDR_RX_SCALED;
|
||||
m_magsq = re*re + im*im;
|
||||
Real mixI = 1.0f;
|
||||
Real mixQ = 0.0f;
|
||||
|
||||
if (m_running.m_pll)
|
||||
{
|
||||
if (m_running.m_fll)
|
||||
{
|
||||
m_fll.feed(re, im);
|
||||
// Use -fPLL to mix (exchange PLL real and image in the complex multiplication)
|
||||
mixI = m_sum.real() * m_fll.getImag() - m_sum.imag() * m_fll.getReal();
|
||||
mixQ = m_sum.real() * m_fll.getReal() + m_sum.imag() * m_fll.getImag();
|
||||
// mixI = m_fll.getReal() * SDR_RX_SCALED;
|
||||
// mixQ = m_fll.getImag() * SDR_RX_SCALED;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pll.feed(re, im);
|
||||
// Use -fPLL to mix (exchange PLL real and image in the complex multiplication)
|
||||
mixI = m_sum.real() * m_pll.getImag() - m_sum.imag() * m_pll.getReal();
|
||||
mixQ = m_sum.real() * m_pll.getReal() + m_sum.imag() * m_pll.getImag();
|
||||
}
|
||||
|
||||
if (m_running.m_ssb & !m_usb)
|
||||
{ // invert spectrum for LSB
|
||||
m_sampleBuffer.push_back(Sample(mixQ, mixI));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sampleBuffer.push_back(Sample(mixI, mixQ));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_running.m_ssb & !m_usb)
|
||||
{ // invert spectrum for LSB
|
||||
m_sampleBuffer.push_back(Sample(m_sum.imag(), m_sum.real()));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sampleBuffer.push_back(Sample(m_sum.real(), m_sum.imag()));
|
||||
}
|
||||
}
|
||||
|
||||
m_sum = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
void processOneSample(Complex& c, fftfilt::cmplx *sideband);
|
||||
};
|
||||
|
||||
#endif // INCLUDE_CHANALYZERNG_H
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "dsp/scopevis.h"
|
||||
#include "gui/glspectrum.h"
|
||||
#include "gui/glscopeng.h"
|
||||
#include "gui/basicchannelsettingsdialog.h"
|
||||
#include "plugin/pluginapi.h"
|
||||
#include "util/simpleserializer.h"
|
||||
#include "util/db.h"
|
||||
@ -66,133 +67,103 @@ qint64 ChannelAnalyzerNGGUI::getCenterFrequency() const
|
||||
void ChannelAnalyzerNGGUI::setCenterFrequency(qint64 centerFrequency)
|
||||
{
|
||||
m_channelMarker.setCenterFrequency(centerFrequency);
|
||||
m_settings.m_frequency = m_channelMarker.getCenterFrequency();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void ChannelAnalyzerNGGUI::resetToDefaults()
|
||||
{
|
||||
blockApplySettings(true);
|
||||
m_settings.resetToDefaults();
|
||||
}
|
||||
|
||||
ui->useRationalDownsampler->setChecked(false);
|
||||
ui->BW->setValue(30);
|
||||
ui->deltaFrequency->setValue(0);
|
||||
ui->spanLog2->setCurrentIndex(3);
|
||||
void ChannelAnalyzerNGGUI::displaySettings()
|
||||
{
|
||||
m_channelMarker.blockSignals(true);
|
||||
m_channelMarker.setCenterFrequency(m_settings.m_frequency);
|
||||
m_channelMarker.setBandwidth(m_settings.m_bandwidth * 2);
|
||||
m_channelMarker.setTitle(m_settings.m_title);
|
||||
m_channelMarker.setLowCutoff(m_settings.m_lowCutoff);
|
||||
|
||||
blockApplySettings(false);
|
||||
applySettings();
|
||||
if (m_settings.m_ssb)
|
||||
{
|
||||
if (m_settings.m_bandwidth < 0) {
|
||||
m_channelMarker.setSidebands(ChannelMarker::lsb);
|
||||
} else {
|
||||
m_channelMarker.setSidebands(ChannelMarker::usb);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_channelMarker.setSidebands(ChannelMarker::dsb);
|
||||
}
|
||||
|
||||
m_channelMarker.blockSignals(false);
|
||||
m_channelMarker.setColor(m_settings.m_rgbColor); // activate signal on the last setting only
|
||||
|
||||
setTitleColor(m_settings.m_rgbColor);
|
||||
setWindowTitle(m_channelMarker.getTitle());
|
||||
|
||||
blockApplySettings(true);
|
||||
|
||||
ui->useRationalDownsampler->setChecked(m_settings.m_downSample);
|
||||
ui->BW->setValue(m_settings.m_bandwidth/100);
|
||||
ui->lowCut->setValue(m_settings.m_lowCutoff/100);
|
||||
ui->deltaFrequency->setValue(m_settings.m_frequency);
|
||||
ui->spanLog2->setCurrentIndex(m_settings.m_spanLog2);
|
||||
|
||||
blockApplySettings(false);
|
||||
|
||||
setNewFinalRate();
|
||||
}
|
||||
|
||||
void ChannelAnalyzerNGGUI::setSpectrumDisplay()
|
||||
{
|
||||
qDebug("ChannelAnalyzerNGGUI::setSpectrumDisplay: m_rate: %d", m_rate);
|
||||
if (m_settings.m_ssb)
|
||||
{
|
||||
ui->glSpectrum->setCenterFrequency(m_rate/4);
|
||||
ui->glSpectrum->setSampleRate(m_rate/2);
|
||||
ui->glSpectrum->setSsbSpectrum(true);
|
||||
ui->glSpectrum->setLsbDisplay(ui->BW->value() < 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->glSpectrum->setCenterFrequency(0);
|
||||
ui->glSpectrum->setSampleRate(m_rate);
|
||||
ui->glSpectrum->setSsbSpectrum(false);
|
||||
ui->glSpectrum->setLsbDisplay(false);
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray ChannelAnalyzerNGGUI::serialize() const
|
||||
{
|
||||
SimpleSerializer s(1);
|
||||
s.writeS32(1, m_channelMarker.getCenterFrequency());
|
||||
s.writeS32(2, ui->BW->value());
|
||||
s.writeBlob(3, ui->spectrumGUI->serialize());
|
||||
s.writeU32(4, m_channelMarker.getColor().rgb());
|
||||
s.writeS32(5, ui->lowCut->value());
|
||||
s.writeS32(6, ui->spanLog2->currentIndex());
|
||||
s.writeBool(7, ui->ssb->isChecked());
|
||||
s.writeBlob(8, ui->scopeGUI->serialize());
|
||||
s.writeU64(9, ui->channelSampleRate->getValueNew());
|
||||
return s.final();
|
||||
return m_settings.serialize();
|
||||
}
|
||||
|
||||
bool ChannelAnalyzerNGGUI::deserialize(const QByteArray& data)
|
||||
{
|
||||
SimpleDeserializer d(data);
|
||||
|
||||
if(!d.isValid())
|
||||
if(m_settings.deserialize(data))
|
||||
{
|
||||
resetToDefaults();
|
||||
return false;
|
||||
}
|
||||
|
||||
if(d.getVersion() == 1)
|
||||
{
|
||||
QByteArray bytetmp;
|
||||
quint32 u32tmp;
|
||||
quint64 u64tmp;
|
||||
qint32 tmp, spanLog2, bw, lowCut;
|
||||
bool tmpBool;
|
||||
|
||||
blockApplySettings(true);
|
||||
m_channelMarker.blockSignals(true);
|
||||
|
||||
d.readS32(1, &tmp, 0);
|
||||
m_channelMarker.setCenterFrequency(tmp);
|
||||
ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency());
|
||||
d.readS32(2, &bw, 30);
|
||||
d.readBlob(3, &bytetmp);
|
||||
ui->spectrumGUI->deserialize(bytetmp);
|
||||
|
||||
if(d.readU32(4, &u32tmp))
|
||||
{
|
||||
m_channelMarker.setColor(u32tmp);
|
||||
}
|
||||
|
||||
d.readS32(5, &lowCut, 3);
|
||||
d.readS32(6, &spanLog2, 3);
|
||||
d.readBool(7, &tmpBool, false);
|
||||
ui->ssb->setChecked(tmpBool);
|
||||
d.readBlob(8, &bytetmp);
|
||||
ui->scopeGUI->deserialize(bytetmp);
|
||||
d.readU64(9, &u64tmp, 2000U);
|
||||
ui->channelSampleRate->setValue(u64tmp);
|
||||
|
||||
blockApplySettings(false);
|
||||
m_channelMarker.blockSignals(false);
|
||||
m_channelMarker.emitChangedByAPI();
|
||||
|
||||
ui->spanLog2->setCurrentIndex(spanLog2);
|
||||
setNewFinalRate(spanLog2);
|
||||
ui->BW->setValue(bw);
|
||||
ui->lowCut->setValue(lowCut); // does applySettings();
|
||||
|
||||
return true;
|
||||
}
|
||||
displaySettings();
|
||||
applySettings(true); // will have true
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
resetToDefaults();
|
||||
return false;
|
||||
}
|
||||
m_settings.resetToDefaults();
|
||||
displaySettings();
|
||||
applySettings(true); // will have true
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ChannelAnalyzerNGGUI::handleMessage(const Message& message)
|
||||
{
|
||||
if (ChannelAnalyzerNG::MsgReportChannelSampleRateChanged::match(message))
|
||||
{
|
||||
int newRate = getRequestedChannelSampleRate() / (1<<m_spanLog2);
|
||||
|
||||
qDebug() << "ChannelAnalyzerNGGUI::handleMessage: MsgReportChannelSampleRateChanged:"
|
||||
<< "m_rate: " << m_rate
|
||||
<< " newRate: " << newRate;
|
||||
|
||||
m_rate = newRate;
|
||||
|
||||
blockApplySettings(true);
|
||||
setFiltersUIBoundaries();
|
||||
blockApplySettings(false);
|
||||
|
||||
if (ui->ssb->isChecked())
|
||||
{
|
||||
QString s = QString::number(ui->BW->value()/10.0, 'f', 1);
|
||||
ui->BWText->setText(tr("%1k").arg(s));
|
||||
}
|
||||
else
|
||||
{
|
||||
QString s = QString::number(ui->BW->value()/5.0, 'f', 1); // BW = value * 2
|
||||
ui->BWText->setText(tr("%1k").arg(s));
|
||||
}
|
||||
|
||||
QString s = QString::number(ui->lowCut->value()/10.0, 'f', 1);
|
||||
ui->lowCutText->setText(tr("%1k").arg(s));
|
||||
|
||||
s = QString::number(m_rate/1000.0, 'f', 1);
|
||||
ui->spanText->setText(tr("%1 kS/s").arg(s));
|
||||
|
||||
ui->glScope->setSampleRate(m_rate);
|
||||
|
||||
displayBandwidth(); // sets ui->glSpectrum sample rate
|
||||
qDebug() << "ChannelAnalyzerNGGUI::handleMessage: MsgReportChannelSampleRateChanged";
|
||||
ui->channelSampleRate->setValueRange(7, 2000U, m_channelAnalyzer->getInputSampleRate());
|
||||
setNewFinalRate();
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -247,14 +218,9 @@ void ChannelAnalyzerNGGUI::tick()
|
||||
|
||||
void ChannelAnalyzerNGGUI::on_channelSampleRate_changed(quint64 value)
|
||||
{
|
||||
ui->channelSampleRate->setValueRange(7, 2000U, m_channelAnalyzer->getInputSampleRate());
|
||||
|
||||
if (ui->useRationalDownsampler->isChecked())
|
||||
{
|
||||
qDebug("ChannelAnalyzerNGGUI::on_channelSampleRate_changed: %llu", value);
|
||||
setNewFinalRate(m_spanLog2);
|
||||
applySettings();
|
||||
}
|
||||
m_settings.m_downSampleRate = value;
|
||||
setNewFinalRate();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void ChannelAnalyzerNGGUI::on_pll_toggled(bool checked)
|
||||
@ -266,14 +232,19 @@ void ChannelAnalyzerNGGUI::on_pll_toggled(bool checked)
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void ChannelAnalyzerNGGUI::on_pllPskOrder_currentIndexChanged(int index __attribute__((unused)))
|
||||
void ChannelAnalyzerNGGUI::on_pllPskOrder_currentIndexChanged(int index)
|
||||
{
|
||||
applySettings();
|
||||
if (index < 5)
|
||||
{
|
||||
m_settings.m_pllPskOrder = (1<<index);
|
||||
applySettings();
|
||||
}
|
||||
}
|
||||
|
||||
void ChannelAnalyzerNGGUI::on_useRationalDownsampler_toggled(bool checked __attribute__((unused)))
|
||||
void ChannelAnalyzerNGGUI::on_useRationalDownsampler_toggled(bool checked)
|
||||
{
|
||||
setNewFinalRate(m_spanLog2);
|
||||
m_settings.m_downSample = checked;
|
||||
setNewFinalRate();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
@ -289,115 +260,62 @@ int ChannelAnalyzerNGGUI::getRequestedChannelSampleRate()
|
||||
void ChannelAnalyzerNGGUI::on_deltaFrequency_changed(qint64 value)
|
||||
{
|
||||
m_channelMarker.setCenterFrequency(value);
|
||||
m_settings.m_frequency = m_channelMarker.getCenterFrequency();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void ChannelAnalyzerNGGUI::on_BW_valueChanged(int value)
|
||||
void ChannelAnalyzerNGGUI::on_BW_valueChanged(int value __attribute__((unused)))
|
||||
{
|
||||
// m_channelMarker.setBandwidth(value * 100 * 2);
|
||||
|
||||
if (ui->ssb->isChecked())
|
||||
{
|
||||
QString s = QString::number(value/10.0, 'f', 1);
|
||||
ui->BWText->setText(tr("%1k").arg(s));
|
||||
}
|
||||
else
|
||||
{
|
||||
QString s = QString::number(value/5.0, 'f', 1); // BW = value * 2
|
||||
ui->BWText->setText(tr("%1k").arg(s));
|
||||
}
|
||||
|
||||
displayBandwidth();
|
||||
on_lowCut_valueChanged(m_channelMarker.getLowCutoff()/100); // does apply settings
|
||||
setFiltersUIBoundaries();
|
||||
m_settings.m_bandwidth = ui->BW->value() * 100;
|
||||
m_settings.m_lowCutoff = ui->lowCut->value() * 100;
|
||||
applySettings();
|
||||
}
|
||||
|
||||
int ChannelAnalyzerNGGUI::getEffectiveLowCutoff(int lowCutoff)
|
||||
void ChannelAnalyzerNGGUI::on_lowCut_valueChanged(int value __attribute__((unused)))
|
||||
{
|
||||
int ssbBW = m_channelMarker.getBandwidth() / 2;
|
||||
int effectiveLowCutoff = lowCutoff;
|
||||
const int guard = 100;
|
||||
|
||||
if (ssbBW < 0) {
|
||||
if (effectiveLowCutoff < ssbBW + guard) {
|
||||
effectiveLowCutoff = ssbBW + guard;
|
||||
}
|
||||
if (effectiveLowCutoff > 0) {
|
||||
effectiveLowCutoff = 0;
|
||||
}
|
||||
} else {
|
||||
if (effectiveLowCutoff > ssbBW - guard) {
|
||||
effectiveLowCutoff = ssbBW - guard;
|
||||
}
|
||||
if (effectiveLowCutoff < 0) {
|
||||
effectiveLowCutoff = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return effectiveLowCutoff;
|
||||
}
|
||||
|
||||
void ChannelAnalyzerNGGUI::on_lowCut_valueChanged(int value)
|
||||
{
|
||||
blockApplySettings(true);
|
||||
int lowCutoff = getEffectiveLowCutoff(value * 100);
|
||||
m_channelMarker.setLowCutoff(lowCutoff);
|
||||
QString s = QString::number(lowCutoff/1000.0, 'f', 1);
|
||||
ui->lowCutText->setText(tr("%1k").arg(s));
|
||||
ui->lowCut->setValue(lowCutoff/100);
|
||||
blockApplySettings(false);
|
||||
setFiltersUIBoundaries();
|
||||
m_settings.m_bandwidth = ui->BW->value() * 100;
|
||||
m_settings.m_lowCutoff = ui->lowCut->value() * 100;
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void ChannelAnalyzerNGGUI::on_spanLog2_currentIndexChanged(int index)
|
||||
{
|
||||
if (setNewFinalRate(index)) {
|
||||
applySettings();
|
||||
}
|
||||
if ((index < 0) || (index > 6)) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_settings.m_spanLog2 = index;
|
||||
setNewFinalRate();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void ChannelAnalyzerNGGUI::on_ssb_toggled(bool checked)
|
||||
{
|
||||
//int bw = m_channelMarker.getBandwidth();
|
||||
|
||||
if (checked)
|
||||
{
|
||||
setFiltersUIBoundaries();
|
||||
|
||||
ui->BWLabel->setText("LP");
|
||||
QString s = QString::number(ui->BW->value()/10.0, 'f', 1); // bw/2
|
||||
ui->BWText->setText(tr("%1k").arg(s));
|
||||
|
||||
on_lowCut_valueChanged(m_channelMarker.getLowCutoff()/100);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ui->BW->value() < 0) {
|
||||
ui->BW->setValue(-ui->BW->value());
|
||||
}
|
||||
|
||||
setFiltersUIBoundaries();
|
||||
//m_channelMarker.setBandwidth(ui->BW->value() * 200.0);
|
||||
|
||||
ui->BWLabel->setText("BP");
|
||||
QString s = QString::number(ui->BW->value()/5.0, 'f', 1); // bw
|
||||
ui->BWText->setText(tr("%1k").arg(s));
|
||||
|
||||
ui->lowCut->setEnabled(false);
|
||||
ui->lowCut->setValue(0);
|
||||
ui->lowCutText->setText("0.0k");
|
||||
}
|
||||
|
||||
m_settings.m_ssb = checked;
|
||||
setFiltersUIBoundaries();
|
||||
applySettings();
|
||||
displayBandwidth();
|
||||
}
|
||||
|
||||
void ChannelAnalyzerNGGUI::onWidgetRolled(QWidget* widget __attribute__((unused)), bool rollDown __attribute__((unused)))
|
||||
{
|
||||
/*
|
||||
if((widget == ui->spectrumContainer) && (m_ssbDemod != NULL))
|
||||
m_ssbDemod->setSpectrum(m_threadedSampleSink->getMessageQueue(), rollDown);
|
||||
*/
|
||||
}
|
||||
|
||||
void ChannelAnalyzerNGGUI::onMenuDialogCalled(const QPoint& p)
|
||||
{
|
||||
BasicChannelSettingsDialog dialog(&m_channelMarker, this);
|
||||
dialog.move(p);
|
||||
dialog.exec();
|
||||
|
||||
m_settings.m_frequency = m_channelMarker.getCenterFrequency();
|
||||
m_settings.m_rgbColor = m_channelMarker.getColor().rgb();
|
||||
m_settings.m_title = m_channelMarker.getTitle();
|
||||
|
||||
setWindowTitle(m_settings.m_title);
|
||||
setTitleColor(m_settings.m_rgbColor);
|
||||
|
||||
applySettings();
|
||||
}
|
||||
|
||||
ChannelAnalyzerNGGUI::ChannelAnalyzerNGGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget* parent) :
|
||||
@ -407,12 +325,12 @@ ChannelAnalyzerNGGUI::ChannelAnalyzerNGGUI(PluginAPI* pluginAPI, DeviceUISet *de
|
||||
m_deviceUISet(deviceUISet),
|
||||
m_channelMarker(this),
|
||||
m_doApplySettings(true),
|
||||
m_rate(6000),
|
||||
m_spanLog2(0)
|
||||
m_rate(48000)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool)));
|
||||
connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &)));
|
||||
|
||||
m_spectrumVis = new SpectrumVis(SDR_RX_SCALEF, ui->glSpectrum);
|
||||
m_scopeVis = new ScopeVisNG(ui->glScope);
|
||||
@ -456,12 +374,16 @@ ChannelAnalyzerNGGUI::ChannelAnalyzerNGGUI(PluginAPI* pluginAPI, DeviceUISet *de
|
||||
ui->spectrumGUI->setBuddies(m_spectrumVis->getInputMessageQueue(), m_spectrumVis, ui->glSpectrum);
|
||||
ui->scopeGUI->setBuddies(m_scopeVis->getInputMessageQueue(), m_scopeVis, ui->glScope);
|
||||
|
||||
m_settings.setChannelMarker(&m_channelMarker);
|
||||
m_settings.setSpectrumGUI(ui->spectrumGUI);
|
||||
m_settings.setScopeGUI(ui->scopeGUI);
|
||||
|
||||
connect(&m_channelMarker, SIGNAL(changedByCursor()), this, SLOT(channelMarkerChangedByCursor()));
|
||||
connect(&m_channelMarker, SIGNAL(highlightedByCursor()), this, SLOT(channelMarkerHighlightedByCursor()));
|
||||
connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
|
||||
|
||||
applySettings();
|
||||
setNewFinalRate(m_spanLog2);
|
||||
displaySettings();
|
||||
applySettings(true);
|
||||
}
|
||||
|
||||
ChannelAnalyzerNGGUI::~ChannelAnalyzerNGGUI()
|
||||
@ -474,101 +396,79 @@ ChannelAnalyzerNGGUI::~ChannelAnalyzerNGGUI()
|
||||
delete ui;
|
||||
}
|
||||
|
||||
bool ChannelAnalyzerNGGUI::setNewFinalRate(int spanLog2)
|
||||
void ChannelAnalyzerNGGUI::setNewFinalRate()
|
||||
{
|
||||
qDebug("ChannelAnalyzerNGGUI::setNewRate");
|
||||
|
||||
if ((spanLog2 < 0) || (spanLog2 > 6)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_spanLog2 = spanLog2;
|
||||
m_rate = getRequestedChannelSampleRate() / (1<<spanLog2);
|
||||
|
||||
m_rate = getRequestedChannelSampleRate() / (1<<m_settings.m_spanLog2);
|
||||
if (m_rate == 0) {
|
||||
m_rate = 6000;
|
||||
m_rate = 48000;
|
||||
}
|
||||
qDebug("ChannelAnalyzerNGGUI::setNewFinalRate: %d m_spanLog2: %d", m_rate, m_settings.m_spanLog2);
|
||||
|
||||
setFiltersUIBoundaries();
|
||||
|
||||
QString s = QString::number(m_rate/1000.0, 'f', 1);
|
||||
ui->spanText->setText(tr("%1 kS/s").arg(s));
|
||||
|
||||
displayBandwidth();
|
||||
|
||||
ui->glScope->setSampleRate(m_rate);
|
||||
ui->glSpectrum->setSampleRate(m_rate);
|
||||
m_scopeVis->setSampleRate(m_rate);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ChannelAnalyzerNGGUI::displayBandwidth()
|
||||
{
|
||||
blockApplySettings(true);
|
||||
|
||||
m_channelMarker.setBandwidth(ui->BW->value() * 100 * 2);
|
||||
|
||||
if (ui->ssb->isChecked())
|
||||
{
|
||||
if (ui->BW->value() < 0)
|
||||
{
|
||||
m_channelMarker.setSidebands(ChannelMarker::lsb);
|
||||
ui->glSpectrum->setLsbDisplay(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_channelMarker.setSidebands(ChannelMarker::usb);
|
||||
ui->glSpectrum->setLsbDisplay(false);
|
||||
}
|
||||
|
||||
m_channelMarker.setLowCutoff(ui->lowCut->value()*100);
|
||||
ui->glSpectrum->setSampleRate(m_rate/2);
|
||||
ui->glSpectrum->setCenterFrequency(m_rate/4);
|
||||
ui->glSpectrum->setSsbSpectrum(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_channelMarker.setSidebands(ChannelMarker::dsb);
|
||||
|
||||
ui->glSpectrum->setCenterFrequency(0);
|
||||
ui->glSpectrum->setSampleRate(m_rate);
|
||||
ui->glSpectrum->setLsbDisplay(false);
|
||||
ui->glSpectrum->setSsbSpectrum(false);
|
||||
}
|
||||
|
||||
blockApplySettings(false);
|
||||
}
|
||||
|
||||
void ChannelAnalyzerNGGUI::setFiltersUIBoundaries()
|
||||
{
|
||||
if (ui->BW->value() < -m_rate/200) {
|
||||
ui->BW->setValue(-m_rate/200);
|
||||
m_channelMarker.setBandwidth(-m_rate*2);
|
||||
} else if (ui->BW->value() > m_rate/200) {
|
||||
ui->BW->setValue(m_rate/200);
|
||||
m_channelMarker.setBandwidth(m_rate*2);
|
||||
}
|
||||
bool dsb = !ui->ssb->isChecked();
|
||||
int bw = ui->BW->value();
|
||||
int lw = ui->lowCut->value();
|
||||
int bwMax = m_rate / 200;
|
||||
|
||||
if (ui->lowCut->value() < -m_rate/200) {
|
||||
ui->lowCut->setValue(-m_rate/200);
|
||||
m_channelMarker.setLowCutoff(-m_rate);
|
||||
} else if (ui->lowCut->value() > m_rate/200) {
|
||||
ui->lowCut->setValue(m_rate/200);
|
||||
m_channelMarker.setLowCutoff(m_rate);
|
||||
}
|
||||
bw = bw < -bwMax ? -bwMax : bw > bwMax ? bwMax : bw;
|
||||
|
||||
if (ui->ssb->isChecked()) {
|
||||
ui->BW->setMinimum(-m_rate/200);
|
||||
ui->lowCut->setMinimum(-m_rate/200);
|
||||
if (bw < 0) {
|
||||
lw = lw < bw+1 ? bw+1 : lw < 0 ? lw : 0;
|
||||
} else if (bw > 0) {
|
||||
lw = lw > bw-1 ? bw-1 : lw < 0 ? 0 : lw;
|
||||
} else {
|
||||
ui->BW->setMinimum(0);
|
||||
ui->lowCut->setMinimum(-m_rate/200);
|
||||
ui->lowCut->setValue(0);
|
||||
lw = 0;
|
||||
}
|
||||
|
||||
ui->BW->setMaximum(m_rate/200);
|
||||
ui->lowCut->setMaximum(m_rate/200);
|
||||
if (dsb)
|
||||
{
|
||||
bw = bw < 0 ? -bw : bw;
|
||||
lw = 0;
|
||||
}
|
||||
|
||||
QString bwStr = QString::number(bw/10.0, 'f', 1);
|
||||
QString lwStr = QString::number(lw/10.0, 'f', 1);
|
||||
|
||||
if (dsb) {
|
||||
ui->BWText->setText(tr("%1%2k").arg(QChar(0xB1, 0x00)).arg(bwStr));
|
||||
} else {
|
||||
ui->BWText->setText(tr("%1k").arg(bwStr));
|
||||
}
|
||||
|
||||
ui->lowCutText->setText(tr("%1k").arg(lwStr));
|
||||
|
||||
ui->BW->blockSignals(true);
|
||||
ui->lowCut->blockSignals(true);
|
||||
|
||||
ui->BW->setMaximum(bwMax);
|
||||
ui->BW->setMinimum(dsb ? 0 : -bwMax);
|
||||
ui->BW->setValue(bw);
|
||||
|
||||
ui->lowCut->setMaximum(dsb ? 0 : bw);
|
||||
ui->lowCut->setMinimum(dsb ? 0 : -bw);
|
||||
ui->lowCut->setValue(lw);
|
||||
|
||||
ui->lowCut->blockSignals(false);
|
||||
ui->BW->blockSignals(false);
|
||||
|
||||
setSpectrumDisplay();
|
||||
|
||||
m_channelMarker.setBandwidth(bw * 200);
|
||||
m_channelMarker.setSidebands(dsb ? ChannelMarker::dsb : bw < 0 ? ChannelMarker::lsb : ChannelMarker::usb);
|
||||
|
||||
if (!dsb) {
|
||||
m_channelMarker.setLowCutoff(lw * 100);
|
||||
}
|
||||
}
|
||||
|
||||
void ChannelAnalyzerNGGUI::blockApplySettings(bool block)
|
||||
@ -578,30 +478,23 @@ void ChannelAnalyzerNGGUI::blockApplySettings(bool block)
|
||||
m_doApplySettings = !block;
|
||||
}
|
||||
|
||||
void ChannelAnalyzerNGGUI::applySettings()
|
||||
void ChannelAnalyzerNGGUI::applySettings(bool force)
|
||||
{
|
||||
if (m_doApplySettings)
|
||||
{
|
||||
int sampleRate = getRequestedChannelSampleRate();
|
||||
|
||||
ChannelAnalyzerNG::MsgConfigureChannelizer *msgChannelizer = ChannelAnalyzerNG::MsgConfigureChannelizer::create(sampleRate, m_channelMarker.getCenterFrequency());
|
||||
ChannelAnalyzerNG::MsgConfigureChannelizer *msgChannelizer =
|
||||
ChannelAnalyzerNG::MsgConfigureChannelizer::create(sampleRate, m_channelMarker.getCenterFrequency());
|
||||
m_channelAnalyzer->getInputMessageQueue()->push(msgChannelizer);
|
||||
|
||||
ChannelAnalyzerNG::MsgConfigureChannelizer *msg =
|
||||
ChannelAnalyzerNG::MsgConfigureChannelizer::create(
|
||||
sampleRate,
|
||||
m_channelMarker.getCenterFrequency());
|
||||
ChannelAnalyzerNG::MsgConfigureChannelizer::create(sampleRate, m_channelMarker.getCenterFrequency());
|
||||
m_channelAnalyzer->getInputMessageQueue()->push(msg);
|
||||
|
||||
m_channelAnalyzer->configure(m_channelAnalyzer->getInputMessageQueue(),
|
||||
sampleRate,
|
||||
ui->BW->value() * 100.0,
|
||||
ui->lowCut->value() * 100.0,
|
||||
m_spanLog2,
|
||||
ui->ssb->isChecked(),
|
||||
ui->pll->isChecked(),
|
||||
ui->pllPskOrder->currentIndex() == 5,
|
||||
1<<ui->pllPskOrder->currentIndex());
|
||||
ChannelAnalyzerNG::MsgConfigureChannelAnalyzer* message =
|
||||
ChannelAnalyzerNG::MsgConfigureChannelAnalyzer::create( m_settings, force);
|
||||
m_channelAnalyzer->getInputMessageQueue()->push(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,13 +17,15 @@
|
||||
#ifndef INCLUDE_CHANNELANALYZERNGGUI_H
|
||||
#define INCLUDE_CHANNELANALYZERNGGUI_H
|
||||
|
||||
#include <plugin/plugininstancegui.h>
|
||||
#include "plugin/plugininstancegui.h"
|
||||
#include "gui/rollupwidget.h"
|
||||
#include "dsp/channelmarker.h"
|
||||
#include "dsp/dsptypes.h"
|
||||
#include "util/movingaverage.h"
|
||||
#include "util/messagequeue.h"
|
||||
|
||||
#include "chanalyzerngsettings.h"
|
||||
|
||||
class PluginAPI;
|
||||
class DeviceUISet;
|
||||
class BasebandSampleSink;
|
||||
@ -63,9 +65,9 @@ private:
|
||||
PluginAPI* m_pluginAPI;
|
||||
DeviceUISet* m_deviceUISet;
|
||||
ChannelMarker m_channelMarker;
|
||||
ChannelAnalyzerNGSettings m_settings;
|
||||
bool m_doApplySettings;
|
||||
int m_rate; //!< sample rate after final in-channel decimation (spanlog2)
|
||||
int m_spanLog2;
|
||||
MovingAverageUtil<Real, double, 40> m_channelPowerDbAvg;
|
||||
|
||||
ChannelAnalyzerNG* m_channelAnalyzer;
|
||||
@ -78,13 +80,13 @@ private:
|
||||
virtual ~ChannelAnalyzerNGGUI();
|
||||
|
||||
int getRequestedChannelSampleRate();
|
||||
int getEffectiveLowCutoff(int lowCutoff);
|
||||
bool setNewFinalRate(int spanLog2); //!< set sample rate after final in-channel decimation
|
||||
void setNewFinalRate(); //!< set sample rate after final in-channel decimation
|
||||
void setFiltersUIBoundaries();
|
||||
|
||||
void blockApplySettings(bool block);
|
||||
void applySettings();
|
||||
void displayBandwidth();
|
||||
void applySettings(bool force = false);
|
||||
void displaySettings();
|
||||
void setSpectrumDisplay();
|
||||
|
||||
void leaveEvent(QEvent*);
|
||||
void enterEvent(QEvent*);
|
||||
@ -100,6 +102,7 @@ private slots:
|
||||
void on_spanLog2_currentIndexChanged(int index);
|
||||
void on_ssb_toggled(bool checked);
|
||||
void onWidgetRolled(QWidget* widget, bool rollDown);
|
||||
void onMenuDialogCalled(const QPoint& p);
|
||||
void handleInputMessages();
|
||||
void tick();
|
||||
};
|
||||
|
@ -22,7 +22,9 @@
|
||||
#include "chanalyzerngsettings.h"
|
||||
|
||||
ChannelAnalyzerNGSettings::ChannelAnalyzerNGSettings() :
|
||||
m_channelMarker(0)
|
||||
m_channelMarker(0),
|
||||
m_spectrumGUI(0),
|
||||
m_scopeGUI(0)
|
||||
{
|
||||
resetToDefaults();
|
||||
}
|
||||
@ -34,11 +36,12 @@ void ChannelAnalyzerNGSettings::resetToDefaults()
|
||||
m_downSampleRate = 0;
|
||||
m_bandwidth = 5000;
|
||||
m_lowCutoff = 300;
|
||||
m_spanLog2 = 3;
|
||||
m_spanLog2 = 0;
|
||||
m_ssb = false;
|
||||
m_pll = false;
|
||||
m_fll = false;
|
||||
m_pllPskOrder = 1;
|
||||
m_rgbColor = QColor(128, 128, 128).rgb();
|
||||
}
|
||||
|
||||
QByteArray ChannelAnalyzerNGSettings::serialize() const
|
||||
@ -86,7 +89,7 @@ bool ChannelAnalyzerNGSettings::deserialize(const QByteArray& data)
|
||||
|
||||
d.readU32(4, &m_rgbColor);
|
||||
d.readS32(5, &m_lowCutoff, 3);
|
||||
d.readS32(6, &m_spanLog2, 3);
|
||||
d.readS32(6, &m_spanLog2, 0);
|
||||
d.readBool(7, &m_ssb, false);
|
||||
|
||||
if (m_scopeGUI) {
|
||||
|
@ -42,6 +42,8 @@ struct ChannelAnalyzerNGSettings
|
||||
ChannelAnalyzerNGSettings();
|
||||
void resetToDefaults();
|
||||
void setChannelMarker(Serializable *channelMarker) { m_channelMarker = channelMarker; }
|
||||
void setSpectrumGUI(Serializable *spectrumGUI) { m_spectrumGUI = spectrumGUI; }
|
||||
void setScopeGUI(Serializable *scopeGUI) { m_scopeGUI = scopeGUI; }
|
||||
QByteArray serialize() const;
|
||||
bool deserialize(const QByteArray& data);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user