diff --git a/Source/GraphComponent.cpp b/Source/GraphComponent.cpp index 8bfe3e3..eee0141 100644 --- a/Source/GraphComponent.cpp +++ b/Source/GraphComponent.cpp @@ -122,8 +122,6 @@ void GraphComponent::mouseDown (const MouseEvent& e) void GraphComponent::receiverStatusChanged(ReceiverInterface *pReceiver) { uint32_t i, j; - uint32_t N; - const cpx_t *pW; float minX = 1000; float maxX = -1000; @@ -131,50 +129,52 @@ void GraphComponent::receiverStatusChanged(ReceiverInterface *pReceiver) float maxY = -1000; j = 0; - N = pReceiver->getNumWeightsCMA(); - pW = pReceiver->getWeightsCMA(); - for (i=0; i < N; i++) { - m_pCurves[j].m_pPointArray[i].x = (float)i; - m_pCurves[j].m_pPointArray[i].y = CpxMagS(pW[i]); + const CVec &w = pReceiver->getWeightsCMA(); + for (i=0; i < w.size(); i++) + { + m_pCurves[j].m_pPointArray[i].x = (float)i; + m_pCurves[j].m_pPointArray[i].y = abs(w(i)); - if (m_pCurves[j].m_pPointArray[i].y < minY) - { - minY = m_pCurves[j].m_pPointArray[i].y; - } - if (m_pCurves[j].m_pPointArray[i].y > maxY) - { - maxY = m_pCurves[j].m_pPointArray[i].y; + if (m_pCurves[j].m_pPointArray[i].y < minY) + { + minY = m_pCurves[j].m_pPointArray[i].y; + } + if (m_pCurves[j].m_pPointArray[i].y > maxY) + { + maxY = m_pCurves[j].m_pPointArray[i].y; + } } + m_pCurves[j].m_numPoints = w.size(); + maxX = (float)(w.size()-1); } - m_pCurves[j].m_numPoints = N; - maxX = (float)(N-1); j = 1; - N = pReceiver->getNumWeightsDFE(); - pW = pReceiver->getWeightsDFE(); - for (i=0; i < N; i++) { - m_pCurves[j].m_pPointArray[i].x = (float)i; - m_pCurves[j].m_pPointArray[i].y = CpxMagS(pW[i]); - - if (m_pCurves[j].m_pPointArray[i].y < minY) + const CVec &w = pReceiver->getWeightsDFE(); + for (i=0; i < w.size(); i++) { - minY = m_pCurves[j].m_pPointArray[i].y; - } - if (m_pCurves[j].m_pPointArray[i].y > maxY) - { - maxY = m_pCurves[j].m_pPointArray[i].y; - } - } - m_pCurves[j].m_numPoints = N; + m_pCurves[j].m_pPointArray[i].x = (float)i; + m_pCurves[j].m_pPointArray[i].y = abs(w(i)); - minY = 0; - minX = 0; - maxY = ceil(maxY); - if (N > maxX) - { - maxX = (float)(N-1); + if (m_pCurves[j].m_pPointArray[i].y < minY) + { + minY = m_pCurves[j].m_pPointArray[i].y; + } + if (m_pCurves[j].m_pPointArray[i].y > maxY) + { + maxY = m_pCurves[j].m_pPointArray[i].y; + } + } + m_pCurves[j].m_numPoints = w.size(); + + minY = 0; + minX = 0; + maxY = ceil(maxY); + if (w.size() > maxX) + { + maxX = (float)(w.size()-1); + } } setGraphBounds(minX, maxX, minY, maxY); diff --git a/Source/Receiver.cpp b/Source/Receiver.cpp index 8ffd94b..3dc07ea 100644 --- a/Source/Receiver.cpp +++ b/Source/Receiver.cpp @@ -55,6 +55,7 @@ Receiver::Receiver(LogHandler *pLogHandler) , m_pPolyphaseInterpolator(0) , m_pLagrangeInterpolator(0) , m_pFarrowInterpolator(0) + { m_stateArm_I = nullptr; m_stateArm_Q = nullptr; @@ -165,10 +166,10 @@ void Receiver::initDefaultParams() } #if 0 -void UpdateWeigths(ComplexVector &x, ComplexVector &e, ComplexVector &w, ComplexVector &w_conj, radio_float_t mu) +void UpdateWeigths(CVec &x, CVec &e, CVec &w, CVec &w_conj, radio_float_t mu) { - e *= ComplexVector(mu, 0); + e *= CVec(mu, 0); e.print("e * mu"); w += x * e.conj(); @@ -219,9 +220,10 @@ void Receiver::init() AGC_Init(&agcBlind, EQ_UPD_INTERVAL, AGC_INITIAL_VALUE); // Channel estimation filter - DFEComplexInit(&m_dfe_off, EQ_DFE_K); - DFEComplexInit(&m_dfe_on, EQ_DFE_K); - CMAInit(&m_cma, 2*EQ_DFE_K+1); + m_cma2.init(2*EQ_DFE_K+1); + m_dfe_off2.init(EQ_DFE_K); + m_dfe_on2.init(EQ_DFE_K); + m_dfe_e_cpx.real = m_dfe_e_cpx.imag = 0.f; cmaReset(); @@ -372,20 +374,20 @@ void Receiver::init() //--------------------------- // ComplexVector //--------------------------- - ComplexVector cv1(4); - ComplexVector cv2(4); - ComplexVector cv3(4); + CVec cv1(4); + CVec cv2(4); + CVec cv3(4); - cv1.at(0) = ComplexVector(1,2); - cv1.at(1) = ComplexVector(3,4); - cv1.at(2) = ComplexVector(5,6); - cv1.at(3) = ComplexVector(7,8); - cv2.at(0) = ComplexVector(11,12); - cv2.at(1) = ComplexVector(13,14); - cv2.at(2) = ComplexVector(15,16); - cv2.at(3) = ComplexVector(17,18); + cv1.at(0) = CVec(1,2); + cv1.at(1) = CVec(3,4); + cv1.at(2) = CVec(5,6); + cv1.at(3) = CVec(7,8); + cv2.at(0) = CVec(11,12); + cv2.at(1) = CVec(13,14); + cv2.at(2) = CVec(15,16); + cv2.at(3) = CVec(17,18); - const ComplexVector &c = -cv1; + const CVec &c = -cv1; cv3 = c; //--------------------------- @@ -711,18 +713,18 @@ void Receiver::init() //--------------------------- // Test //--------------------------- - ComplexVector w(32); - ComplexVector w_conj(32); - ComplexVector e(32); - ComplexVector x(32); + CVec w(32); + CVec w_conj(32); + CVec e(32); + CVec x(32); - w = ComplexVector(1, 1); - w_conj = ComplexVector(0.f, 0.f); - e = ComplexVector (0.5f, 0.4f); - x = ComplexVector(2.f, 2.f); - x *= ComplexVector(10.f, 0); - x += ComplexVector(0.5f, 0); - x -= ComplexVector(5.f, 0); + w = CVec(1, 1); + w_conj = CVec(0.f, 0.f); + e = CVec (0.5f, 0.4f); + x = CVec(2.f, 2.f); + x *= CVec(10.f, 0); + x += CVec(0.5f, 0); + x -= CVec(5.f, 0); x += w + w_conj; w.print("w"); @@ -733,14 +735,14 @@ void Receiver::init() //--------------------------- // RealVector //--------------------------- - RealVector rv1(4, 0); - RealVector rv2(4, 0); - RealVector rv3(4, 0); + RVec rv1(4, 0); + RVec rv2(4, 0); + RVec rv3(4, 0); rv1 = 10.f; rv2 = 20.f; - const RealVector &r = -rv1; + const RVec &r = -rv1; rv3 = r; rv3 = -rv1; rv3 = -rv1 * rv2 * rv2; @@ -947,11 +949,6 @@ void Receiver::free() // AGC AGC_Free(&agcBlind); - // Channel estimation filter - DFEComplexFree(&m_dfe_off); - DFEComplexFree(&m_dfe_on); - CMAFree(&m_cma); - } // The Receiver Controller @@ -1160,9 +1157,12 @@ void Receiver::processBaseband(cpx_t *pIF, uint32_t len) // Equalizer Process samples // ----------------------------------------------------- SlidingVarGet(&m_statistics.I_CPR); - IQ_cma = CMAProcess(&m_cma, IQ_cpr); - IQ_dfeOn = DFEComplexProcess(&m_dfe_on, IQ_cpr, IQ_hard_last); - + ComplexScalar __IQ_cma = m_cma2.process(toComplexScalar(IQ_cpr)); + IQ_cma = toCpx(__IQ_cma); + + ComplexScalar __IQ_dfeOn = m_dfe_on2.process(toComplexScalar(IQ_cpr), toComplexScalar(IQ_hard_last)); + IQ_dfeOn = toCpx(__IQ_dfeOn); + IQ_eq = IQ_cpr; if (m_params.eq_mode == eq_mode_cma) { @@ -1206,32 +1206,34 @@ void Receiver::processBaseband(cpx_t *pIF, uint32_t len) if (m_params.cmaType == cma_type_cma) { // CMA: Train - CMATrainGodard(&m_cma, IQ_cma, CpxMagS(sym_cma.rect), m_pSymMapper->R2_cma, m_params.eqMuCma); + m_cma2.trainGodard(__IQ_cma, CpxMagS(sym_cma.rect), m_pSymMapper->R2_cma, m_params.eqMuCma); } if (m_params.cmaType == cma_type_mma) { // MMA: Train - MMATrain(&m_cma, IQ_cma, m_pSymMapper->R_mma, m_params.eqMuCma); + m_cma2.trainMma(__IQ_cma, toComplexScalar(m_pSymMapper->R_mma), m_params.eqMuCma); } if (m_params.cmaType == cma_type_smma) { // S-MMA: Train - SMMATrain(&m_cma, IQ_cma, CpxMagS(sym_cma.rect), m_pSymMapper->R_smma, m_params.eqMuCma); + m_cma2.trainSmma(__IQ_cma, CpxMagS(sym_cma.rect), toComplexScalar(m_pSymMapper->R_smma), m_params.eqMuCma); } } if (m_params.dfeMode == dfe_mode_training_enabled) { // DFE: LMS Update coefficients - DFEAdaptLMS(&m_dfe_off, m_dfe_e_cpx, m_params.eqMuDfe); // last dfe_e_cpx + m_dfe_off2.train(toComplexScalar(m_dfe_e_cpx), m_params.eqMuDfe); // DFE: Calc offline response - IQ_dfeOff = DFEComplexProcess(&m_dfe_off, IQ_cpr, sym_dfe_off.rect); - + ComplexScalar __IQ_dfeOff = m_dfe_off2.process(toComplexScalar(IQ_cpr), toComplexScalar(sym_dfe_off.rect)); + IQ_dfeOff = toCpx(__IQ_dfeOff); + sym_dfe_off = SymMapGetSymbolInfo(m_pSymMapper, SymMapDemap(m_pSymMapper, IQ_soft)); // DFE: Calculate current error - m_dfe_e_cpx = CpxSubS(sym_dfe_off.rect, IQ_dfeOff); + ComplexScalar __dfe_e_cpx = toComplexScalar(sym_dfe_off.rect) - __IQ_dfeOff; + m_dfe_e_cpx = toCpx(__dfe_e_cpx); } // Calculate current error @@ -1576,6 +1578,9 @@ status_t& Receiver::getStatus() radio_float_t powerSoft_dB; radio_float_t powerHard_dB; + if (!m_pSymMapper) + return status; + status.frameStatRx = m_frameReceiver.getStats(); status.numSymbolsReceived = m_sym_stat.sym_cnt; status.noiseStr = powerDB(SlidingVarGet(&m_statistics.noise_str), 1.0f); @@ -1639,28 +1644,25 @@ void Receiver::cprReset() void Receiver::dfeReset() { - CoeffComplexUnitAt(m_dfe_off.eq.pW, m_dfe_off.N, EQ_GROUP_DELAY); - CoeffComplexUnitAt(m_dfe_on.eq.pW, m_dfe_on.N, EQ_GROUP_DELAY); - CoeffComplexUnitAt(m_dfe_off.eq.pW_conj, m_dfe_off.N, EQ_GROUP_DELAY); - CoeffComplexUnitAt(m_dfe_on.eq.pW_conj, m_dfe_on.N, EQ_GROUP_DELAY); + m_dfe_on2.setUnit(EQ_GROUP_DELAY); + m_dfe_off2.setUnit(EQ_GROUP_DELAY); m_statusListeners.call(&ReceiverStatusListener::receiverStatusChanged, this); } void Receiver::cmaReset() { - CoeffComplexUnitAt(m_cma.eq.pW, m_cma.N, EQ_GROUP_DELAY); + m_cma2.setUnit(EQ_GROUP_DELAY); m_statusListeners.call(&ReceiverStatusListener::receiverStatusChanged, this); } void Receiver::dfeOffUpdateFromCma() { - memcpy(m_dfe_off.eq.pW, m_cma.eq.pW, m_cma.N*sizeof(cpx_t)); + (Equalizer::AEqualizer &)m_dfe_off2 = (Equalizer::AEqualizer const &)m_cma2; m_statusListeners.call(&ReceiverStatusListener::receiverStatusChanged, this); } void Receiver::dfeOnUpdateFromDfeOff() { - memcpy(m_dfe_on.eq.pW, m_dfe_off.eq.pW, m_dfe_on.eq.N*sizeof(cpx_t)); - memcpy(m_dfe_on.eq.pW_conj, m_dfe_off.eq.pW_conj, m_dfe_on.eq.N*sizeof(cpx_t)); + m_dfe_on2 = m_dfe_off2; m_statusListeners.call(&ReceiverStatusListener::receiverStatusChanged, this); } diff --git a/Source/Receiver.h b/Source/Receiver.h index 1bc4bbb..bd17d26 100644 --- a/Source/Receiver.h +++ b/Source/Receiver.h @@ -14,6 +14,11 @@ #include "JuceHeader.h" #include "LogComponent.h" +#include +#include + +using namespace Radio; + // --------------------------------------------------- #define NUM_PASSBAND_SAMPLES_PER_SYM 4 #define NUM_BASEBAND_SAMPLES_PER_SYM 2 @@ -241,10 +246,8 @@ public: virtual void dfeReset() = 0; virtual void dfeOffUpdateFromCma() = 0; virtual void dfeOnUpdateFromDfeOff() = 0; - virtual const uint32_t getNumWeightsCMA() = 0; - virtual const cpx_t* getWeightsCMA() = 0; - virtual const uint32_t getNumWeightsDFE() = 0; - virtual const cpx_t* getWeightsDFE() = 0; + virtual const CVec& getWeightsCMA() = 0; + virtual const CVec& getWeightsDFE() = 0; }; @@ -334,13 +337,15 @@ private: // Equalizer // Decision directed EQ - dfe_cpx_t m_dfe_on; - dfe_cpx_t m_dfe_off; + Equalizer::Dfe m_dfe_on2; + Equalizer::Dfe m_dfe_off2; + cpx_t m_dfe_e_cpx; // Blind EQ - cma_t m_cma; - + Equalizer::Cma m_cma2; + + // Symbol demapper sym_map_t *m_pSymMapper; @@ -423,27 +428,16 @@ private: (void)size; } - const uint32_t getNumWeightsCMA() override + const CVec& getWeightsCMA() override { - return m_cma.eq.N; + return m_cma2.getWeights(); } - const cpx_t* getWeightsCMA() override + const CVec& getWeightsDFE() override { - return m_cma.eq.pW; + return m_dfe_off2.getWeights(); } - const uint32_t getNumWeightsDFE() override - { - return m_dfe_off.eq.N; - } - - const cpx_t* getWeightsDFE() override - { - return m_dfe_off.eq.pW; - } - - trace_t m_trace; };