diff --git a/debian/changelog b/debian/changelog index 3da824284..7a90116b6 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,6 +3,7 @@ sdrangel (4.0.1-1) unstable; urgency=medium * DSD demod: added NXDN support * DATV demod: include it only if FFmpeg > 3.1 is installed * Fixes for Arch. Manual merge of pull request #183 + * Scope: new magnitude squared projection mainly for radioastronomy -- Edouard Griffiths, F4EXB Sat, 23 Jun 2018 09:14:18 +0200 diff --git a/plugins/channelrx/chanalyzer/chanalyzerplugin.cpp b/plugins/channelrx/chanalyzer/chanalyzerplugin.cpp index ee0b9df73..475029110 100644 --- a/plugins/channelrx/chanalyzer/chanalyzerplugin.cpp +++ b/plugins/channelrx/chanalyzer/chanalyzerplugin.cpp @@ -23,7 +23,7 @@ const PluginDescriptor ChannelAnalyzerPlugin::m_pluginDescriptor = { QString("Channel Analyzer"), - QString("4.0.0"), + QString("4.0.1"), QString("(c) Edouard Griffiths, F4EXB"), QString("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/channelrx/chanalyzer/readme.md b/plugins/channelrx/chanalyzer/readme.md index 5deb96ab7..653c76896 100644 --- a/plugins/channelrx/chanalyzer/readme.md +++ b/plugins/channelrx/chanalyzer/readme.md @@ -9,9 +9,14 @@ This plugin can be used to analyze the complex signal received in its passband. - Real part - Imaginary part - Magnitude linear + - Power i.e. squared magnitude linear - Power i.e. squared magnitude log (dB) - Phase - Phase derivative (instant frequency) + - BPSK symbol mapping + - QPSK symbol mapping + - 8-PSK symbol mapping + - 16-PSK symbol mapping The same waveforms can be used to trigger the scope trace @@ -211,6 +216,7 @@ To construct a trace which represents real values the incoming complex signal mu - Real: take the real part - Imag: take the imaginary part - Mag: calculate magnitude in linear representation. This is just the module of the complex sample + - MagSq: calculate power in linear representation. This is the squared module of the complex sample - MagDB: calculate power in log representation as 10*log10(x) or decibel (dB) representation. This is the squared module of the complex sample expressed in decibels - Phi: instantaneous phase. This is the argument of the complex sample. - dPhi: instantaneous derivative of the phase. This is the difference of arguments between successive samples thus represents the instantaneous frequency. @@ -283,6 +289,7 @@ The top slider is a coarse adjustment. Each step moves the trace by an amount th - Real, Imag: 0.01 - Mag: 0.005 + - MagSq: 0.005 - MagDB: 1 dB - Phi, dPhi: 0.01 @@ -290,6 +297,7 @@ The bottom slider is a fine adjustment. Each step moves the trace by an amount t - Real, Imag: 50.0E-6 - Mag: 25.0sE-6 + - MagSq: 25.0sE-6 - MagDB: 0.01 dB - Phi, dPhi: 50.0E-6 @@ -370,6 +378,7 @@ The top slider is a coarse adjustment. Each step moves the trigger level by an a - Real, Imag: 0.01 - Mag: 0.005 + - MagSq: 0.005 - MagDB: 1 dB - Phi, dPhi: 0.01 @@ -377,6 +386,7 @@ The bottom slider is a fine adjustment. Each step moves the trigger level by an - Real, Imag: 50.0E-6 - Mag: 25.0sE-6 + - MagSq: 25.0sE-6 - MagDB: 0.01 dB - Phi, dPhi: 50.0E-6 diff --git a/sdrbase/dsp/projector.cpp b/sdrbase/dsp/projector.cpp index 1d9a66c86..887be37c0 100644 --- a/sdrbase/dsp/projector.cpp +++ b/sdrbase/dsp/projector.cpp @@ -52,6 +52,13 @@ Real Projector::run(const Sample& s) v = std::sqrt(magsq); } break; + case ProjectionMagSq: + { + Real re = s.m_real / SDR_RX_SCALEF; + Real im = s.m_imag / SDR_RX_SCALEF; + v = re*re + im*im; + } + break; case ProjectionMagDB: { Real re = s.m_real / SDR_RX_SCALEF; diff --git a/sdrbase/dsp/projector.h b/sdrbase/dsp/projector.h index 094c8c592..3e2f65602 100644 --- a/sdrbase/dsp/projector.h +++ b/sdrbase/dsp/projector.h @@ -25,6 +25,7 @@ public: ProjectionReal = 0, //!< Extract real part ProjectionImag, //!< Extract imaginary part ProjectionMagLin, //!< Calculate linear magnitude or modulus + ProjectionMagSq, //!< Calculate linear squared magnitude or power ProjectionMagDB, //!< Calculate logarithmic (dB) of squared magnitude ProjectionPhase, //!< Calculate phase ProjectionDPhase, //!< Calculate phase derivative i.e. instantaneous frequency scaled to sample rate diff --git a/sdrgui/dsp/scopevisng.cpp b/sdrgui/dsp/scopevisng.cpp index ed01d81f0..70a8044c3 100644 --- a/sdrgui/dsp/scopevisng.cpp +++ b/sdrgui/dsp/scopevisng.cpp @@ -463,6 +463,11 @@ int ScopeVisNG::processTraces(const SampleVector::const_iterator& cbegin, const { v = ((*itCtl)->m_projector.run(*begin) - itData->m_ofs)*itData->m_amp - 1.0f; } + else if (projectionType == Projector::ProjectionMagSq) + { + v = ((*itCtl)->m_projector.run(*begin) - itData->m_ofs)*itData->m_amp - 1.0f; + // TODO: power display overlay for squared magnitude + } else if (projectionType == Projector::ProjectionMagDB) { Real re = begin->m_real / SDR_RX_SCALEF; diff --git a/sdrgui/gui/glscopeng.cpp b/sdrgui/gui/glscopeng.cpp index e2cae6be7..a802313b9 100644 --- a/sdrgui/gui/glscopeng.cpp +++ b/sdrgui/gui/glscopeng.cpp @@ -1877,6 +1877,7 @@ void GLScopeNG::setYScale(ScaleEngine& scale, uint32_t highlightedTraceIndex) scale.setRange(Unit::Decibel, pow_floor, pow_floor + pow_range); break; case Projector::ProjectionMagLin: + case Projector::ProjectionMagSq: if (amp_range < 2.0) { scale.setRange(Unit::None, amp_ofs * 1000.0, amp_range * 1000.0 + amp_ofs * 1000.0); } else { diff --git a/sdrgui/gui/glscopenggui.cpp b/sdrgui/gui/glscopenggui.cpp index 32087f0dc..425d45f2f 100644 --- a/sdrgui/gui/glscopenggui.cpp +++ b/sdrgui/gui/glscopenggui.cpp @@ -1021,7 +1021,7 @@ void GLScopeNGGUI::setAmpOfsDisplay() { double a; - if (projectionType == Projector::ProjectionMagLin) + if ((projectionType == Projector::ProjectionMagLin) || (projectionType == Projector::ProjectionMagSq)) { a = o/2000.0f; } @@ -1087,7 +1087,7 @@ void GLScopeNGGUI::setTrigLevelDisplay() { double a; - if (projectionType == Projector::ProjectionMagLin) { + if ((projectionType == Projector::ProjectionMagLin) || (projectionType == Projector::ProjectionMagSq)) { a = 1.0 + t; } else { a = t; @@ -1184,6 +1184,7 @@ void GLScopeNGGUI::fillProjectionCombo(QComboBox* comboBox) comboBox->addItem("Real", Projector::ProjectionReal); comboBox->addItem("Imag", Projector::ProjectionImag); comboBox->addItem("Mag", Projector::ProjectionMagLin); + comboBox->addItem("MagSq", Projector::ProjectionMagSq); comboBox->addItem("MagdB", Projector::ProjectionMagDB); comboBox->addItem("Phi", Projector::ProjectionPhase); comboBox->addItem("dPhi", Projector::ProjectionDPhase); @@ -1225,7 +1226,7 @@ void GLScopeNGGUI::fillTraceData(ScopeVisNG::TraceData& traceData) traceData.m_ofsCoarse = ui->ofsCoarse->value(); traceData.m_ofsFine = ui->ofsFine->value(); - if (traceData.m_projectionType == Projector::ProjectionMagLin) { + if ((traceData.m_projectionType == Projector::ProjectionMagLin) || (traceData.m_projectionType == Projector::ProjectionMagSq)) { traceData.m_ofs = ((10.0 * ui->ofsCoarse->value()) + (ui->ofsFine->value() / 20.0)) / 2000.0f; } else { traceData.m_ofs = ((10.0 * ui->ofsCoarse->value()) + (ui->ofsFine->value() / 20.0)) / 1000.0f;