1
0
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:
f4exb 2018-05-20 01:10:08 +02:00
parent d6f5de1ad7
commit 524c7fbe7c
6 changed files with 326 additions and 559 deletions

View File

@ -48,13 +48,15 @@ ChannelAnalyzerNG::ChannelAnalyzerNG(DeviceSourceAPI *deviceAPI) :
m_useInterpolator = false; m_useInterpolator = false;
m_interpolatorDistance = 1.0f; m_interpolatorDistance = 1.0f;
m_interpolatorDistanceRemain = 0.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); m_inputSampleRate = 48000;
DSBFilter = new fftfilt(m_config.m_Bandwidth / m_config.m_inputSampleRate, 2*ssbFftLen); 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.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_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_channelizer = new DownChannelizer(this);
m_threadedChannelizer = new ThreadedBasebandSampleSink(m_channelizer, 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) 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(); m_sampleBuffer.clear();
@ -122,8 +124,81 @@ void ChannelAnalyzerNG::feed(const SampleVector::const_iterator& begin, const Sa
m_settingsMutex.unlock(); 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() void ChannelAnalyzerNG::start()
{ {
applyChannelSettings(m_inputSampleRate, m_inputFrequencyOffset, true);
} }
void ChannelAnalyzerNG::stop() void ChannelAnalyzerNG::stop()
@ -132,20 +207,14 @@ void ChannelAnalyzerNG::stop()
bool ChannelAnalyzerNG::handleMessage(const Message& cmd) bool ChannelAnalyzerNG::handleMessage(const Message& cmd)
{ {
qDebug() << "ChannelAnalyzerNG::handleMessage: " << cmd.getIdentifier();
if (DownChannelizer::MsgChannelizerNotification::match(cmd)) if (DownChannelizer::MsgChannelizerNotification::match(cmd))
{ {
DownChannelizer::MsgChannelizerNotification& notif = (DownChannelizer::MsgChannelizerNotification&) cmd; DownChannelizer::MsgChannelizerNotification& notif = (DownChannelizer::MsgChannelizerNotification&) cmd;
qDebug() << "ChannelAnalyzerNG::handleMessage: DownChannelizer::MsgChannelizerNotification:"
<< " sampleRate: " << notif.getSampleRate()
<< " frequencyOffset: " << notif.getFrequencyOffset();
m_config.m_inputSampleRate = notif.getSampleRate(); applyChannelSettings(notif.getSampleRate(), notif.getFrequencyOffset());
m_config.m_frequency = notif.getFrequencyOffset();
qDebug() << "ChannelAnalyzerNG::handleMessage: MsgChannelizerNotification:"
<< " m_sampleRate: " << m_config.m_inputSampleRate
<< " frequencyOffset: " << m_config.m_frequency;
apply();
if (getMessageQueueToGUI()) if (getMessageQueueToGUI())
{ {
@ -158,35 +227,23 @@ bool ChannelAnalyzerNG::handleMessage(const Message& cmd)
else if (MsgConfigureChannelizer::match(cmd)) else if (MsgConfigureChannelizer::match(cmd))
{ {
MsgConfigureChannelizer& cfg = (MsgConfigureChannelizer&) cmd; MsgConfigureChannelizer& cfg = (MsgConfigureChannelizer&) cmd;
qDebug() << "ChannelAnalyzerNG::handleMessage: MsgConfigureChannelizer:"
<< " sampleRate: " << cfg.getSampleRate()
<< " centerFrequency: " << cfg.getCenterFrequency();
m_channelizer->configure(m_channelizer->getInputMessageQueue(), m_channelizer->configure(m_channelizer->getInputMessageQueue(),
cfg.getSampleRate(), cfg.getSampleRate(),
cfg.getCenterFrequency()); cfg.getCenterFrequency());
return true; return true;
} }
else if (MsgConfigureChannelAnalyzerOld::match(cmd)) else if (MsgConfigureChannelAnalyzer::match(cmd))
{ {
MsgConfigureChannelAnalyzerOld& cfg = (MsgConfigureChannelAnalyzerOld&) cmd; qDebug("ChannelAnalyzerNG::handleMessage: MsgConfigureChannelAnalyzer");
MsgConfigureChannelAnalyzer& cfg = (MsgConfigureChannelAnalyzer&) cmd;
m_config.m_channelSampleRate = cfg.getChannelSampleRate(); applySettings(cfg.getSettings(), cfg.getForce());
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();
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 else
@ -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) void ChannelAnalyzerNG::applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force)
{ {
qDebug() << "ChannelAnalyzerNG::applyChannelSettings:" qDebug() << "ChannelAnalyzerNG::applyChannelSettings:"
@ -338,6 +295,9 @@ void ChannelAnalyzerNG::applyChannelSettings(int inputSampleRate, int inputFrequ
void ChannelAnalyzerNG::setFilters(int sampleRate, float bandwidth, float lowCutoff) void ChannelAnalyzerNG::setFilters(int sampleRate, float bandwidth, float lowCutoff)
{ {
qDebug("ChannelAnalyzerNG::setFilters: sampleRate: %d bandwidth: %f lowCutoff: %f",
sampleRate, bandwidth, lowCutoff);
if (bandwidth < 0) if (bandwidth < 0)
{ {
bandwidth = -bandwidth; bandwidth = -bandwidth;
@ -361,6 +321,17 @@ void ChannelAnalyzerNG::setFilters(int sampleRate, float bandwidth, float lowCut
void ChannelAnalyzerNG::applySettings(const ChannelAnalyzerNGSettings& settings, bool force) 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) if ((settings.m_downSampleRate != m_settings.m_downSampleRate) || force)
{ {
m_settingsMutex.lock(); m_settingsMutex.lock();
@ -392,7 +363,7 @@ void ChannelAnalyzerNG::applySettings(const ChannelAnalyzerNGSettings& settings,
if ((settings.m_spanLog2 != m_settings.m_spanLog2) || force) 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_pll.setSampleRate(sampleRate);
m_fll.setSampleRate(sampleRate); m_fll.setSampleRate(sampleRate);
} }

View File

@ -184,10 +184,10 @@ public:
unsigned int pllPskOrder); unsigned int pllPskOrder);
DownChannelizer *getChannelizer() { return m_channelizer; } DownChannelizer *getChannelizer() { return m_channelizer; }
int getInputSampleRate() const { return m_running.m_inputSampleRate; } int getInputSampleRate() const { return m_inputSampleRate; }
int getChannelSampleRate() const { return m_running.m_channelSampleRate; } int getChannelSampleRate() const { return m_settings.m_downSample ? m_settings.m_downSampleRate : m_inputSampleRate; }
double getMagSq() const { return m_magsq; } 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 getPllFrequency() const { return m_pll.getFreq(); }
Real getPllDeltaPhase() const { return m_pll.getDeltaPhi(); } Real getPllDeltaPhase() const { return m_pll.getDeltaPhi(); }
Real getPllPhase() const { return m_pll.getPhiHat(); } Real getPllPhase() const { return m_pll.getPhiHat(); }
@ -199,7 +199,7 @@ public:
virtual void getIdentifier(QString& id) { id = objectName(); } virtual void getIdentifier(QString& id) { id = objectName(); }
virtual void getTitle(QString& title) { title = 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 QByteArray serialize() const { return QByteArray(); }
virtual bool deserialize(const QByteArray& data __attribute__((unused))) { return false; } virtual bool deserialize(const QByteArray& data __attribute__((unused))) { return false; }
@ -208,37 +208,6 @@ public:
static const QString m_channelId; static const QString m_channelId;
private: 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; DeviceSourceAPI *m_deviceAPI;
ThreadedBasebandSampleSink* m_threadedChannelizer; ThreadedBasebandSampleSink* m_threadedChannelizer;
DownChannelizer* m_channelizer; DownChannelizer* m_channelizer;
@ -266,85 +235,11 @@ private:
SampleVector m_sampleBuffer; SampleVector m_sampleBuffer;
QMutex m_settingsMutex; QMutex m_settingsMutex;
void apply(bool force = false); // void apply(bool force = false);
void applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force); void applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force = false);
void applySettings(const ChannelAnalyzerNGSettings& settings, bool force = false); void applySettings(const ChannelAnalyzerNGSettings& settings, bool force = false);
void setFilters(int sampleRate, float bandwidth, float lowCutoff); void setFilters(int sampleRate, float bandwidth, float lowCutoff);
void processOneSample(Complex& c, fftfilt::cmplx *sideband);
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;
}
}
}
}; };
#endif // INCLUDE_CHANALYZERNG_H #endif // INCLUDE_CHANALYZERNG_H

View File

@ -29,6 +29,7 @@
#include "dsp/scopevis.h" #include "dsp/scopevis.h"
#include "gui/glspectrum.h" #include "gui/glspectrum.h"
#include "gui/glscopeng.h" #include "gui/glscopeng.h"
#include "gui/basicchannelsettingsdialog.h"
#include "plugin/pluginapi.h" #include "plugin/pluginapi.h"
#include "util/simpleserializer.h" #include "util/simpleserializer.h"
#include "util/db.h" #include "util/db.h"
@ -66,93 +67,92 @@ qint64 ChannelAnalyzerNGGUI::getCenterFrequency() const
void ChannelAnalyzerNGGUI::setCenterFrequency(qint64 centerFrequency) void ChannelAnalyzerNGGUI::setCenterFrequency(qint64 centerFrequency)
{ {
m_channelMarker.setCenterFrequency(centerFrequency); m_channelMarker.setCenterFrequency(centerFrequency);
m_settings.m_frequency = m_channelMarker.getCenterFrequency();
applySettings(); applySettings();
} }
void ChannelAnalyzerNGGUI::resetToDefaults() void ChannelAnalyzerNGGUI::resetToDefaults()
{ {
m_settings.resetToDefaults();
}
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);
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); blockApplySettings(true);
ui->useRationalDownsampler->setChecked(false); ui->useRationalDownsampler->setChecked(m_settings.m_downSample);
ui->BW->setValue(30); ui->BW->setValue(m_settings.m_bandwidth/100);
ui->deltaFrequency->setValue(0); ui->lowCut->setValue(m_settings.m_lowCutoff/100);
ui->spanLog2->setCurrentIndex(3); ui->deltaFrequency->setValue(m_settings.m_frequency);
ui->spanLog2->setCurrentIndex(m_settings.m_spanLog2);
blockApplySettings(false); blockApplySettings(false);
applySettings();
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 QByteArray ChannelAnalyzerNGGUI::serialize() const
{ {
SimpleSerializer s(1); return m_settings.serialize();
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();
} }
bool ChannelAnalyzerNGGUI::deserialize(const QByteArray& data) bool ChannelAnalyzerNGGUI::deserialize(const QByteArray& data)
{ {
SimpleDeserializer d(data); if(m_settings.deserialize(data))
if(!d.isValid())
{ {
resetToDefaults(); displaySettings();
return false; applySettings(true); // will have true
}
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; return true;
} }
else else
{ {
resetToDefaults(); m_settings.resetToDefaults();
displaySettings();
applySettings(true); // will have true
return false; return false;
} }
} }
@ -161,38 +161,9 @@ bool ChannelAnalyzerNGGUI::handleMessage(const Message& message)
{ {
if (ChannelAnalyzerNG::MsgReportChannelSampleRateChanged::match(message)) if (ChannelAnalyzerNG::MsgReportChannelSampleRateChanged::match(message))
{ {
int newRate = getRequestedChannelSampleRate() / (1<<m_spanLog2); qDebug() << "ChannelAnalyzerNGGUI::handleMessage: MsgReportChannelSampleRateChanged";
ui->channelSampleRate->setValueRange(7, 2000U, m_channelAnalyzer->getInputSampleRate());
qDebug() << "ChannelAnalyzerNGGUI::handleMessage: MsgReportChannelSampleRateChanged:" setNewFinalRate();
<< "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
return true; return true;
} }
@ -247,15 +218,10 @@ void ChannelAnalyzerNGGUI::tick()
void ChannelAnalyzerNGGUI::on_channelSampleRate_changed(quint64 value) void ChannelAnalyzerNGGUI::on_channelSampleRate_changed(quint64 value)
{ {
ui->channelSampleRate->setValueRange(7, 2000U, m_channelAnalyzer->getInputSampleRate()); m_settings.m_downSampleRate = value;
setNewFinalRate();
if (ui->useRationalDownsampler->isChecked())
{
qDebug("ChannelAnalyzerNGGUI::on_channelSampleRate_changed: %llu", value);
setNewFinalRate(m_spanLog2);
applySettings(); applySettings();
} }
}
void ChannelAnalyzerNGGUI::on_pll_toggled(bool checked) void ChannelAnalyzerNGGUI::on_pll_toggled(bool checked)
{ {
@ -266,14 +232,19 @@ void ChannelAnalyzerNGGUI::on_pll_toggled(bool checked)
applySettings(); applySettings();
} }
void ChannelAnalyzerNGGUI::on_pllPskOrder_currentIndexChanged(int index __attribute__((unused))) void ChannelAnalyzerNGGUI::on_pllPskOrder_currentIndexChanged(int index)
{ {
if (index < 5)
{
m_settings.m_pllPskOrder = (1<<index);
applySettings(); 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(); applySettings();
} }
@ -289,115 +260,62 @@ int ChannelAnalyzerNGGUI::getRequestedChannelSampleRate()
void ChannelAnalyzerNGGUI::on_deltaFrequency_changed(qint64 value) void ChannelAnalyzerNGGUI::on_deltaFrequency_changed(qint64 value)
{ {
m_channelMarker.setCenterFrequency(value); m_channelMarker.setCenterFrequency(value);
m_settings.m_frequency = m_channelMarker.getCenterFrequency();
applySettings(); applySettings();
} }
void ChannelAnalyzerNGGUI::on_BW_valueChanged(int value) void ChannelAnalyzerNGGUI::on_BW_valueChanged(int value __attribute__((unused)))
{ {
// m_channelMarker.setBandwidth(value * 100 * 2); setFiltersUIBoundaries();
m_settings.m_bandwidth = ui->BW->value() * 100;
m_settings.m_lowCutoff = ui->lowCut->value() * 100;
applySettings();
}
if (ui->ssb->isChecked()) void ChannelAnalyzerNGGUI::on_lowCut_valueChanged(int value __attribute__((unused)))
{ {
QString s = QString::number(value/10.0, 'f', 1); setFiltersUIBoundaries();
ui->BWText->setText(tr("%1k").arg(s)); m_settings.m_bandwidth = ui->BW->value() * 100;
} m_settings.m_lowCutoff = ui->lowCut->value() * 100;
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
}
int ChannelAnalyzerNGGUI::getEffectiveLowCutoff(int lowCutoff)
{
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);
applySettings(); applySettings();
} }
void ChannelAnalyzerNGGUI::on_spanLog2_currentIndexChanged(int index) void ChannelAnalyzerNGGUI::on_spanLog2_currentIndexChanged(int index)
{ {
if (setNewFinalRate(index)) { if ((index < 0) || (index > 6)) {
applySettings(); return;
} }
m_settings.m_spanLog2 = index;
setNewFinalRate();
applySettings();
} }
void ChannelAnalyzerNGGUI::on_ssb_toggled(bool checked) void ChannelAnalyzerNGGUI::on_ssb_toggled(bool checked)
{ {
//int bw = m_channelMarker.getBandwidth(); m_settings.m_ssb = checked;
if (checked)
{
setFiltersUIBoundaries(); 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");
}
applySettings(); applySettings();
displayBandwidth();
} }
void ChannelAnalyzerNGGUI::onWidgetRolled(QWidget* widget __attribute__((unused)), bool rollDown __attribute__((unused))) 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) : ChannelAnalyzerNGGUI::ChannelAnalyzerNGGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget* parent) :
@ -407,12 +325,12 @@ ChannelAnalyzerNGGUI::ChannelAnalyzerNGGUI(PluginAPI* pluginAPI, DeviceUISet *de
m_deviceUISet(deviceUISet), m_deviceUISet(deviceUISet),
m_channelMarker(this), m_channelMarker(this),
m_doApplySettings(true), m_doApplySettings(true),
m_rate(6000), m_rate(48000)
m_spanLog2(0)
{ {
ui->setupUi(this); ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose, true); setAttribute(Qt::WA_DeleteOnClose, true);
connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool))); 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_spectrumVis = new SpectrumVis(SDR_RX_SCALEF, ui->glSpectrum);
m_scopeVis = new ScopeVisNG(ui->glScope); 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->spectrumGUI->setBuddies(m_spectrumVis->getInputMessageQueue(), m_spectrumVis, ui->glSpectrum);
ui->scopeGUI->setBuddies(m_scopeVis->getInputMessageQueue(), m_scopeVis, ui->glScope); 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(changedByCursor()), this, SLOT(channelMarkerChangedByCursor()));
connect(&m_channelMarker, SIGNAL(highlightedByCursor()), this, SLOT(channelMarkerHighlightedByCursor())); connect(&m_channelMarker, SIGNAL(highlightedByCursor()), this, SLOT(channelMarkerHighlightedByCursor()));
connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
applySettings(); displaySettings();
setNewFinalRate(m_spanLog2); applySettings(true);
} }
ChannelAnalyzerNGGUI::~ChannelAnalyzerNGGUI() ChannelAnalyzerNGGUI::~ChannelAnalyzerNGGUI()
@ -474,101 +396,79 @@ ChannelAnalyzerNGGUI::~ChannelAnalyzerNGGUI()
delete ui; delete ui;
} }
bool ChannelAnalyzerNGGUI::setNewFinalRate(int spanLog2) void ChannelAnalyzerNGGUI::setNewFinalRate()
{ {
qDebug("ChannelAnalyzerNGGUI::setNewRate"); m_rate = getRequestedChannelSampleRate() / (1<<m_settings.m_spanLog2);
if ((spanLog2 < 0) || (spanLog2 > 6)) {
return false;
}
m_spanLog2 = spanLog2;
m_rate = getRequestedChannelSampleRate() / (1<<spanLog2);
if (m_rate == 0) { if (m_rate == 0) {
m_rate = 6000; m_rate = 48000;
} }
qDebug("ChannelAnalyzerNGGUI::setNewFinalRate: %d m_spanLog2: %d", m_rate, m_settings.m_spanLog2);
setFiltersUIBoundaries(); setFiltersUIBoundaries();
QString s = QString::number(m_rate/1000.0, 'f', 1); QString s = QString::number(m_rate/1000.0, 'f', 1);
ui->spanText->setText(tr("%1 kS/s").arg(s)); ui->spanText->setText(tr("%1 kS/s").arg(s));
displayBandwidth();
ui->glScope->setSampleRate(m_rate); ui->glScope->setSampleRate(m_rate);
ui->glSpectrum->setSampleRate(m_rate);
m_scopeVis->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() void ChannelAnalyzerNGGUI::setFiltersUIBoundaries()
{ {
if (ui->BW->value() < -m_rate/200) { bool dsb = !ui->ssb->isChecked();
ui->BW->setValue(-m_rate/200); int bw = ui->BW->value();
m_channelMarker.setBandwidth(-m_rate*2); int lw = ui->lowCut->value();
} else if (ui->BW->value() > m_rate/200) { int bwMax = m_rate / 200;
ui->BW->setValue(m_rate/200);
m_channelMarker.setBandwidth(m_rate*2);
}
if (ui->lowCut->value() < -m_rate/200) { bw = bw < -bwMax ? -bwMax : bw > bwMax ? bwMax : bw;
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);
}
if (ui->ssb->isChecked()) { if (bw < 0) {
ui->BW->setMinimum(-m_rate/200); lw = lw < bw+1 ? bw+1 : lw < 0 ? lw : 0;
ui->lowCut->setMinimum(-m_rate/200); } else if (bw > 0) {
lw = lw > bw-1 ? bw-1 : lw < 0 ? 0 : lw;
} else { } else {
ui->BW->setMinimum(0); lw = 0;
ui->lowCut->setMinimum(-m_rate/200);
ui->lowCut->setValue(0);
} }
ui->BW->setMaximum(m_rate/200); if (dsb)
ui->lowCut->setMaximum(m_rate/200); {
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) void ChannelAnalyzerNGGUI::blockApplySettings(bool block)
@ -578,30 +478,23 @@ void ChannelAnalyzerNGGUI::blockApplySettings(bool block)
m_doApplySettings = !block; m_doApplySettings = !block;
} }
void ChannelAnalyzerNGGUI::applySettings() void ChannelAnalyzerNGGUI::applySettings(bool force)
{ {
if (m_doApplySettings) if (m_doApplySettings)
{ {
int sampleRate = getRequestedChannelSampleRate(); 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); m_channelAnalyzer->getInputMessageQueue()->push(msgChannelizer);
ChannelAnalyzerNG::MsgConfigureChannelizer *msg = ChannelAnalyzerNG::MsgConfigureChannelizer *msg =
ChannelAnalyzerNG::MsgConfigureChannelizer::create( ChannelAnalyzerNG::MsgConfigureChannelizer::create(sampleRate, m_channelMarker.getCenterFrequency());
sampleRate,
m_channelMarker.getCenterFrequency());
m_channelAnalyzer->getInputMessageQueue()->push(msg); m_channelAnalyzer->getInputMessageQueue()->push(msg);
m_channelAnalyzer->configure(m_channelAnalyzer->getInputMessageQueue(), ChannelAnalyzerNG::MsgConfigureChannelAnalyzer* message =
sampleRate, ChannelAnalyzerNG::MsgConfigureChannelAnalyzer::create( m_settings, force);
ui->BW->value() * 100.0, m_channelAnalyzer->getInputMessageQueue()->push(message);
ui->lowCut->value() * 100.0,
m_spanLog2,
ui->ssb->isChecked(),
ui->pll->isChecked(),
ui->pllPskOrder->currentIndex() == 5,
1<<ui->pllPskOrder->currentIndex());
} }
} }

View File

@ -17,13 +17,15 @@
#ifndef INCLUDE_CHANNELANALYZERNGGUI_H #ifndef INCLUDE_CHANNELANALYZERNGGUI_H
#define INCLUDE_CHANNELANALYZERNGGUI_H #define INCLUDE_CHANNELANALYZERNGGUI_H
#include <plugin/plugininstancegui.h> #include "plugin/plugininstancegui.h"
#include "gui/rollupwidget.h" #include "gui/rollupwidget.h"
#include "dsp/channelmarker.h" #include "dsp/channelmarker.h"
#include "dsp/dsptypes.h" #include "dsp/dsptypes.h"
#include "util/movingaverage.h" #include "util/movingaverage.h"
#include "util/messagequeue.h" #include "util/messagequeue.h"
#include "chanalyzerngsettings.h"
class PluginAPI; class PluginAPI;
class DeviceUISet; class DeviceUISet;
class BasebandSampleSink; class BasebandSampleSink;
@ -63,9 +65,9 @@ private:
PluginAPI* m_pluginAPI; PluginAPI* m_pluginAPI;
DeviceUISet* m_deviceUISet; DeviceUISet* m_deviceUISet;
ChannelMarker m_channelMarker; ChannelMarker m_channelMarker;
ChannelAnalyzerNGSettings m_settings;
bool m_doApplySettings; bool m_doApplySettings;
int m_rate; //!< sample rate after final in-channel decimation (spanlog2) int m_rate; //!< sample rate after final in-channel decimation (spanlog2)
int m_spanLog2;
MovingAverageUtil<Real, double, 40> m_channelPowerDbAvg; MovingAverageUtil<Real, double, 40> m_channelPowerDbAvg;
ChannelAnalyzerNG* m_channelAnalyzer; ChannelAnalyzerNG* m_channelAnalyzer;
@ -78,13 +80,13 @@ private:
virtual ~ChannelAnalyzerNGGUI(); virtual ~ChannelAnalyzerNGGUI();
int getRequestedChannelSampleRate(); int getRequestedChannelSampleRate();
int getEffectiveLowCutoff(int lowCutoff); void setNewFinalRate(); //!< set sample rate after final in-channel decimation
bool setNewFinalRate(int spanLog2); //!< set sample rate after final in-channel decimation
void setFiltersUIBoundaries(); void setFiltersUIBoundaries();
void blockApplySettings(bool block); void blockApplySettings(bool block);
void applySettings(); void applySettings(bool force = false);
void displayBandwidth(); void displaySettings();
void setSpectrumDisplay();
void leaveEvent(QEvent*); void leaveEvent(QEvent*);
void enterEvent(QEvent*); void enterEvent(QEvent*);
@ -100,6 +102,7 @@ private slots:
void on_spanLog2_currentIndexChanged(int index); void on_spanLog2_currentIndexChanged(int index);
void on_ssb_toggled(bool checked); void on_ssb_toggled(bool checked);
void onWidgetRolled(QWidget* widget, bool rollDown); void onWidgetRolled(QWidget* widget, bool rollDown);
void onMenuDialogCalled(const QPoint& p);
void handleInputMessages(); void handleInputMessages();
void tick(); void tick();
}; };

View File

@ -22,7 +22,9 @@
#include "chanalyzerngsettings.h" #include "chanalyzerngsettings.h"
ChannelAnalyzerNGSettings::ChannelAnalyzerNGSettings() : ChannelAnalyzerNGSettings::ChannelAnalyzerNGSettings() :
m_channelMarker(0) m_channelMarker(0),
m_spectrumGUI(0),
m_scopeGUI(0)
{ {
resetToDefaults(); resetToDefaults();
} }
@ -34,11 +36,12 @@ void ChannelAnalyzerNGSettings::resetToDefaults()
m_downSampleRate = 0; m_downSampleRate = 0;
m_bandwidth = 5000; m_bandwidth = 5000;
m_lowCutoff = 300; m_lowCutoff = 300;
m_spanLog2 = 3; m_spanLog2 = 0;
m_ssb = false; m_ssb = false;
m_pll = false; m_pll = false;
m_fll = false; m_fll = false;
m_pllPskOrder = 1; m_pllPskOrder = 1;
m_rgbColor = QColor(128, 128, 128).rgb();
} }
QByteArray ChannelAnalyzerNGSettings::serialize() const QByteArray ChannelAnalyzerNGSettings::serialize() const
@ -86,7 +89,7 @@ bool ChannelAnalyzerNGSettings::deserialize(const QByteArray& data)
d.readU32(4, &m_rgbColor); d.readU32(4, &m_rgbColor);
d.readS32(5, &m_lowCutoff, 3); d.readS32(5, &m_lowCutoff, 3);
d.readS32(6, &m_spanLog2, 3); d.readS32(6, &m_spanLog2, 0);
d.readBool(7, &m_ssb, false); d.readBool(7, &m_ssb, false);
if (m_scopeGUI) { if (m_scopeGUI) {

View File

@ -42,6 +42,8 @@ struct ChannelAnalyzerNGSettings
ChannelAnalyzerNGSettings(); ChannelAnalyzerNGSettings();
void resetToDefaults(); void resetToDefaults();
void setChannelMarker(Serializable *channelMarker) { m_channelMarker = channelMarker; } void setChannelMarker(Serializable *channelMarker) { m_channelMarker = channelMarker; }
void setSpectrumGUI(Serializable *spectrumGUI) { m_spectrumGUI = spectrumGUI; }
void setScopeGUI(Serializable *scopeGUI) { m_scopeGUI = scopeGUI; }
QByteArray serialize() const; QByteArray serialize() const;
bool deserialize(const QByteArray& data); bool deserialize(const QByteArray& data);
}; };