From 524c7fbe7cf552c95a742258f1cd13ec8109d412 Mon Sep 17 00:00:00 2001 From: f4exb Date: Sun, 20 May 2018 01:10:08 +0200 Subject: [PATCH] Channel analyzer NG: use settings --- .../channelrx/chanalyzerng/chanalyzerng.cpp | 255 ++++----- plugins/channelrx/chanalyzerng/chanalyzerng.h | 119 +---- .../chanalyzerng/chanalyzernggui.cpp | 485 +++++++----------- .../channelrx/chanalyzerng/chanalyzernggui.h | 15 +- .../chanalyzerng/chanalyzerngsettings.cpp | 9 +- .../chanalyzerng/chanalyzerngsettings.h | 2 + 6 files changed, 326 insertions(+), 559 deletions(-) diff --git a/plugins/channelrx/chanalyzerng/chanalyzerng.cpp b/plugins/channelrx/chanalyzerng/chanalyzerng.cpp index b45a436d2..95c2cfcaa 100644 --- a/plugins/channelrx/chanalyzerng/chanalyzerng.cpp +++ b/plugins/channelrx/chanalyzerng/chanalyzerng.cpp @@ -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<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<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 diff --git a/plugins/channelrx/chanalyzerng/chanalyzernggui.cpp b/plugins/channelrx/chanalyzerng/chanalyzernggui.cpp index 586f22612..73278162a 100644 --- a/plugins/channelrx/chanalyzerng/chanalyzernggui.cpp +++ b/plugins/channelrx/chanalyzerng/chanalyzernggui.cpp @@ -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<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; } @@ -238,7 +209,7 @@ void ChannelAnalyzerNGGUI::tick() ui->pll->setStyleSheet("QToolButton { background:rgb(79,79,79); }"); } - if (ui->pll->isChecked()) + if (ui->pll->isChecked()) { int freq = (m_channelAnalyzer->getPllFrequency() * m_channelAnalyzer->getChannelSampleRate()) / (2.0*M_PI); ui->pll->setToolTip(tr("PLL lock. Freq = %1 Hz").arg(freq)); @@ -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<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<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<pllPskOrder->currentIndex()); + ChannelAnalyzerNG::MsgConfigureChannelAnalyzer* message = + ChannelAnalyzerNG::MsgConfigureChannelAnalyzer::create( m_settings, force); + m_channelAnalyzer->getInputMessageQueue()->push(message); } } diff --git a/plugins/channelrx/chanalyzerng/chanalyzernggui.h b/plugins/channelrx/chanalyzerng/chanalyzernggui.h index 8b58f92a2..5538d5cf1 100644 --- a/plugins/channelrx/chanalyzerng/chanalyzernggui.h +++ b/plugins/channelrx/chanalyzerng/chanalyzernggui.h @@ -17,13 +17,15 @@ #ifndef INCLUDE_CHANNELANALYZERNGGUI_H #define INCLUDE_CHANNELANALYZERNGGUI_H -#include +#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 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(); }; diff --git a/plugins/channelrx/chanalyzerng/chanalyzerngsettings.cpp b/plugins/channelrx/chanalyzerng/chanalyzerngsettings.cpp index 5873cf0f2..c282220f1 100644 --- a/plugins/channelrx/chanalyzerng/chanalyzerngsettings.cpp +++ b/plugins/channelrx/chanalyzerng/chanalyzerngsettings.cpp @@ -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) { diff --git a/plugins/channelrx/chanalyzerng/chanalyzerngsettings.h b/plugins/channelrx/chanalyzerng/chanalyzerngsettings.h index 0ec677e76..a030ba943 100644 --- a/plugins/channelrx/chanalyzerng/chanalyzerngsettings.h +++ b/plugins/channelrx/chanalyzerng/chanalyzerngsettings.h @@ -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); };