mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-05-23 18:52:28 -04:00
Channel analyzer NG and Projector: PSK symbol mapping projection
This commit is contained in:
parent
c69d203bd0
commit
85df6218de
@ -15,6 +15,7 @@
|
|||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
#include "projector.h"
|
#include "projector.h"
|
||||||
|
|
||||||
Projector::Projector(ProjectionType projectionType) :
|
Projector::Projector(ProjectionType projectionType) :
|
||||||
@ -77,6 +78,106 @@ Real Projector::run(const Sample& s)
|
|||||||
v = dPhi;
|
v = dPhi;
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case ProjectionReal:
|
||||||
default:
|
default:
|
||||||
v = s.m_real / SDR_RX_SCALEF;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,6 +28,10 @@ public:
|
|||||||
ProjectionMagDB, //!< Calculate logarithmic (dB) of squared magnitude
|
ProjectionMagDB, //!< Calculate logarithmic (dB) of squared magnitude
|
||||||
ProjectionPhase, //!< Calculate phase
|
ProjectionPhase, //!< Calculate phase
|
||||||
ProjectionDPhase, //!< Calculate phase derivative i.e. instantaneous frequency scaled to sample rate
|
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
|
nbProjectionTypes //!< Gives the number of projections in the enum
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -42,6 +46,7 @@ public:
|
|||||||
Real run(const Sample& s);
|
Real run(const Sample& s);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static Real normalizeAngle(Real angle);
|
||||||
ProjectionType m_projectionType;
|
ProjectionType m_projectionType;
|
||||||
Real m_prevArg;
|
Real m_prevArg;
|
||||||
Real *m_cache;
|
Real *m_cache;
|
||||||
|
@ -1187,6 +1187,10 @@ void GLScopeNGGUI::fillProjectionCombo(QComboBox* comboBox)
|
|||||||
comboBox->addItem("MagdB", Projector::ProjectionMagDB);
|
comboBox->addItem("MagdB", Projector::ProjectionMagDB);
|
||||||
comboBox->addItem("Phi", Projector::ProjectionPhase);
|
comboBox->addItem("Phi", Projector::ProjectionPhase);
|
||||||
comboBox->addItem("dPhi", Projector::ProjectionDPhase);
|
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)
|
void GLScopeNGGUI::disableLiveMode(bool disable)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user