Scope and channel analyzer: new squared magnitude (linear power) projection mainly for radioastronomy

This commit is contained in:
f4exb 2018-06-26 00:43:19 +02:00
parent facb282c23
commit 80b7829bf7
8 changed files with 30 additions and 4 deletions

1
debian/changelog vendored
View File

@ -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 <f4exb06@gmail.com> Sat, 23 Jun 2018 09:14:18 +0200

View File

@ -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,

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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 {

View File

@ -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;