From 85df6218de80efe89af087060b7b0c8b51ae603c Mon Sep 17 00:00:00 2001 From: f4exb <f4exb06@gmail.com> Date: Tue, 22 May 2018 13:54:01 +0200 Subject: [PATCH] Channel analyzer NG and Projector: PSK symbol mapping projection --- sdrbase/dsp/projector.cpp | 113 ++++++++++++++++++++++++++++++++++++ sdrbase/dsp/projector.h | 5 ++ sdrgui/gui/glscopenggui.cpp | 4 ++ 3 files changed, 122 insertions(+) diff --git a/sdrbase/dsp/projector.cpp b/sdrbase/dsp/projector.cpp index a678409f7..1d9a66c86 100644 --- a/sdrbase/dsp/projector.cpp +++ b/sdrbase/dsp/projector.cpp @@ -15,6 +15,7 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // /////////////////////////////////////////////////////////////////////////////////// +#include <math.h> #include "projector.h" Projector::Projector(ProjectionType projectionType) : @@ -77,6 +78,106 @@ Real Projector::run(const Sample& s) v = dPhi; } break; + case ProjectionBPSK: + { + Real arg = std::atan2((float) s.m_imag, (float) s.m_real); + v = normalizeAngle(2*arg) / (2.0*M_PI); // generic estimation around 0 + // mapping on 2 symbols + if (arg < -M_PI/2) { + v -= 1.0/2; + } else if (arg < M_PI/2) { + v += 1.0/2; + } else if (arg < M_PI) { + v -= 1.0/2; + } + } + break; + case ProjectionQPSK: + { + Real arg = std::atan2((float) s.m_imag, (float) s.m_real); + v = normalizeAngle(4*arg) / (4.0*M_PI); // generic estimation around 0 + // mapping on 4 symbols + if (arg < -3*M_PI/4) { + v -= 3.0/4; + } else if (arg < -M_PI/4) { + v -= 1.0/4; + } else if (arg < M_PI/4) { + v += 1.0/4; + } else if (arg < 3*M_PI/4) { + v += 3.0/4; + } else if (arg < M_PI) { + v -= 3.0/4; + } + } + break; + case Projection8PSK: + { + Real arg = std::atan2((float) s.m_imag, (float) s.m_real); + v = normalizeAngle(8*arg) / (8.0*M_PI); // generic estimation around 0 + // mapping on 8 symbols + if (arg < -7*M_PI/8) { + v -= 7.0/8; + } else if (arg < -5*M_PI/8) { + v -= 5.0/8; + } else if (arg < -3*M_PI/8) { + v -= 3.0/8; + } else if (arg < -M_PI/8) { + v -= 1.0/8; + } else if (arg < M_PI/8) { + v += 1.0/8; + } else if (arg < 3*M_PI/8) { + v += 3.0/8; + } else if (arg < 5*M_PI/8) { + v += 5.0/8; + } else if (arg < 7*M_PI/8) { + v += 7.0/8; + } else if (arg < M_PI) { + v -= 7.0/8; + } + } + break; + case Projection16PSK: + { + Real arg = std::atan2((float) s.m_imag, (float) s.m_real); + v = normalizeAngle(16*arg) / (16.0*M_PI); // generic estimation around 0 + // mapping on 16 symbols + if (arg < -15*M_PI/16) { + v -= 15.0/16; + } else if (arg < -13*M_PI/16) { + v -= 13.0/6; + } else if (arg < -11*M_PI/16) { + v -= 11.0/16; + } else if (arg < -9*M_PI/16) { + v -= 9.0/16; + } else if (arg < -7*M_PI/16) { + v -= 7.0/16; + } else if (arg < -5*M_PI/16) { + v -= 5.0/16; + } else if (arg < -3*M_PI/16) { + v -= 3.0/16; + } else if (arg < -M_PI/16) { + v -= 1.0/16; + } else if (arg < M_PI/16) { + v += 1.0/16; + } else if (arg < 3.0*M_PI/16) { + v += 3.0/16; + } else if (arg < 5.0*M_PI/16) { + v += 5.0/16; + } else if (arg < 7.0*M_PI/16) { + v += 7.0/16; + } else if (arg < 9.0*M_PI/16) { + v += 9.0/16; + } else if (arg < 11.0*M_PI/16) { + v += 11.0/16; + } else if (arg < 13.0*M_PI/16) { + v += 13.0/16; + } else if (arg < 15.0*M_PI/16) { + v += 15.0/16; + } else if (arg < M_PI) { + v -= 15.0/16; + } + } + break; case ProjectionReal: default: v = s.m_real / SDR_RX_SCALEF; @@ -91,3 +192,15 @@ Real Projector::run(const Sample& s) } } +Real Projector::normalizeAngle(Real angle) +{ + while (angle <= -M_PI) { + angle += 2.0*M_PI; + } + while (angle > M_PI) { + angle -= 2.0*M_PI; + } + return angle; +} + + diff --git a/sdrbase/dsp/projector.h b/sdrbase/dsp/projector.h index b0cdf88af..094c8c592 100644 --- a/sdrbase/dsp/projector.h +++ b/sdrbase/dsp/projector.h @@ -28,6 +28,10 @@ public: ProjectionMagDB, //!< Calculate logarithmic (dB) of squared magnitude ProjectionPhase, //!< Calculate phase ProjectionDPhase, //!< Calculate phase derivative i.e. instantaneous frequency scaled to sample rate + ProjectionBPSK, //!< Phase comparator BPSK evaluation + ProjectionQPSK, //!< Phase comparator QPSK evaluation + Projection8PSK, //!< Phase comparator 8-PSK evaluation + Projection16PSK, //!< Phase comparator 16-PSK evaluation nbProjectionTypes //!< Gives the number of projections in the enum }; @@ -42,6 +46,7 @@ public: Real run(const Sample& s); private: + static Real normalizeAngle(Real angle); ProjectionType m_projectionType; Real m_prevArg; Real *m_cache; diff --git a/sdrgui/gui/glscopenggui.cpp b/sdrgui/gui/glscopenggui.cpp index 55da3719b..32087f0dc 100644 --- a/sdrgui/gui/glscopenggui.cpp +++ b/sdrgui/gui/glscopenggui.cpp @@ -1187,6 +1187,10 @@ void GLScopeNGGUI::fillProjectionCombo(QComboBox* comboBox) comboBox->addItem("MagdB", Projector::ProjectionMagDB); comboBox->addItem("Phi", Projector::ProjectionPhase); comboBox->addItem("dPhi", Projector::ProjectionDPhase); + comboBox->addItem("BPSK", Projector::ProjectionBPSK); + comboBox->addItem("QPSK", Projector::ProjectionQPSK); + comboBox->addItem("8PSK", Projector::Projection8PSK); + comboBox->addItem("16PSK", Projector::Projection16PSK); } void GLScopeNGGUI::disableLiveMode(bool disable)