- Use C++ Equalizer DFE and CMA

git-svn-id: http://moon:8086/svn/software/trunk/projects/mpsk_rx_gui@91 b431acfa-c32f-4a4a-93f1-934dc6c82436
This commit is contained in:
2014-12-20 17:57:31 +00:00
parent 2bf059a84a
commit 8943af5976
3 changed files with 111 additions and 115 deletions
+57 -55
View File
@@ -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);
}