From 04170f264862cd2e42d27587bbc5587926b62798 Mon Sep 17 00:00:00 2001 From: f4exb Date: Wed, 23 Jun 2021 15:53:28 +0200 Subject: [PATCH] Scope on complex: Projector with complex input --- sdrbase/dsp/projector.cpp | 173 ++++++++++++++++++++++++++++++++++++++ sdrbase/dsp/projector.h | 1 + 2 files changed, 174 insertions(+) diff --git a/sdrbase/dsp/projector.cpp b/sdrbase/dsp/projector.cpp index 1add3dcf0..016d06f04 100644 --- a/sdrbase/dsp/projector.cpp +++ b/sdrbase/dsp/projector.cpp @@ -215,6 +215,179 @@ Real Projector::run(const Sample& s) } } +Real Projector::run(const std::complex& s) +{ + Real v; + + if ((m_cache) && !m_cacheMaster) { + return m_cache[(int) m_projectionType]; + } + else + { + switch (m_projectionType) + { + case ProjectionImag: + v = s.imag(); + break; + case ProjectionMagLin: + v = std::abs(s); + break; + case ProjectionMagSq: + v = std::norm(s); + break; + case ProjectionMagDB: + { + Real magsq = std::norm(s); + v = log10f(magsq) * 10.0f; + } + break; + case ProjectionPhase: + v = std::arg(s) / M_PI; // normalize + break; + case ProjectionDOAP: + { + // calculate phase. Assume phase difference between two sources at half wavelength distance with sources axis as reference (positive side) + // cos(theta) = phi / 2*pi*k + Real p = std::arg(s); // do not mormalize phi (phi in -pi..+pi) + v = acos(p/M_PI) / M_PI; // normalize theta + } + break; + case ProjectionDOAN: + { + // calculate phase. Assume phase difference between two sources at half wavelength distance with sources axis as reference (negative source) + Real p = std::arg(s); // do not mormalize phi (phi in -pi..+pi) + v = -acos(p/M_PI) / M_PI; // normalize theta + } + break; + case ProjectionDPhase: + { + Real curArg = std::arg(s); + Real dPhi = (curArg - m_prevArg) / M_PI; + m_prevArg = curArg; + + if (dPhi < -1.0f) { + dPhi += 2.0f; + } else if (dPhi > 1.0f) { + dPhi -= 2.0f; + } + + v = dPhi; + } + break; + case ProjectionBPSK: + { + Real arg = std::arg(s); + 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::arg(s); + 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::arg(s); + 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::arg(s); + 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.real(); + break; + } + + if (m_cache) { + m_cache[(int) m_projectionType] = v; + } + + return v; + } +} + Real Projector::normalizeAngle(Real angle) { while (angle <= -M_PI) { diff --git a/sdrbase/dsp/projector.h b/sdrbase/dsp/projector.h index b5568a6f2..b731eb076 100644 --- a/sdrbase/dsp/projector.h +++ b/sdrbase/dsp/projector.h @@ -52,6 +52,7 @@ public: void setCacheMaster(bool cacheMaster) { m_cacheMaster = cacheMaster; } Real run(const Sample& s); + Real run(const std::complex& s); private: static Real normalizeAngle(Real angle);