- moved Interpolator out of big loop into tight processing loop
git-svn-id: http://moon:8086/svn/software/trunk/projects/mpsk_rx_gui@1000 b431acfa-c32f-4a4a-93f1-934dc6c82436
This commit is contained in:
+23
-47
@@ -138,6 +138,7 @@ void Receiver::initDefaultParams()
|
||||
LeadLagSetCoeff(&m_params.str_loopfilter_coeff[0], STR_GAIN_LEAD_AQU, STR_GAIN_LAG_AQU);
|
||||
LeadLagSetCoeff(&m_params.str_loopfilter_coeff[1], STR_GAIN_LEAD_TRK, STR_GAIN_LAG_TRK);
|
||||
m_params.str_loopfilter_coeff_index = 0;
|
||||
m_timingGenerator.loopFilterSetup(&m_loop_filter_str, &m_params.str_loopfilter_coeff[m_params.str_loopfilter_coeff_index]);
|
||||
|
||||
m_params.cprState = cpr_state_acquisition;
|
||||
m_params.cpr_mode = cpr_mode_enabled;
|
||||
@@ -451,58 +452,43 @@ void Receiver::processBaseband(CVec const &iq, uint32_t len)
|
||||
}
|
||||
#endif
|
||||
|
||||
for (n = 0; n < len; n++)
|
||||
{
|
||||
|
||||
if (RCF_TYPE == RCF_TYPE_POLYPHASE_DISCRETE)
|
||||
{
|
||||
// Matched filtering and interpolation
|
||||
m_polyPhase.feed(iq[n], 1);
|
||||
}
|
||||
// Matched filtering and symbol timing recovery
|
||||
// @2 x symbolrate
|
||||
|
||||
Processor::Buffer<ComplexScalar> *buf_ip = nullptr;
|
||||
if (RCF_TYPE == RCF_TYPE_POLYPHASE_FARROW)
|
||||
{
|
||||
// Matched filtering and interpolation
|
||||
m_farrow.feed(&iq[n], 1);
|
||||
// Farrow interpolation
|
||||
m_farrow.feed(iq, len);
|
||||
m_farrow.process(m_timingGenerator);
|
||||
buf_ip = &m_farrow.getOutputBuffer();
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
// Timing corrector
|
||||
TimingCorrectorProcess(&m_timing_corrector, m_Vc);
|
||||
|
||||
#ifndef _DEBUG
|
||||
// TracePrint(&m_trace, "%d\t%8f\t%.8f\t%.8f\n", TimingCorrectorIsSkip(&m_timing_corrector)-TimingCorrectorIsStuff(&m_timing_corrector), TimingCorrectorGetMu(&m_timing_corrector), TimingCorrectorGetMu(&m_timing_corrector), (powerDB(m_pSymMapper->Eb, 2) - powerDB((SlidingVarGet(&m_statistics.sym_err_mag) + SlidingVarGet(&m_statistics.sym_err_phi)), 1)));
|
||||
#endif
|
||||
|
||||
if (RCF_TYPE == RCF_TYPE_POLYPHASE_DISCRETE)
|
||||
{
|
||||
ComplexScalar __IQ_mf = m_polyPhase.process(TimingCorrectorGetMu(&m_timing_corrector), !TimingCorrectorIsStuff(&m_timing_corrector));
|
||||
IQ_mf = toCpx(__IQ_mf);
|
||||
// Polyphase interpolation
|
||||
// m_polyPhase.feed(iq, len);
|
||||
// m_polyPhase.process(m_timingGenerator);
|
||||
// buf_ip = &m_polyPhase.getOutputBuffer();
|
||||
}
|
||||
|
||||
if (RCF_TYPE == RCF_TYPE_POLYPHASE_FARROW)
|
||||
if (buf_ip == nullptr)
|
||||
{
|
||||
ComplexScalar __IQ_mf = m_farrow.process(TimingCorrectorGetMu(&m_timing_corrector), !TimingCorrectorIsStuff(&m_timing_corrector));
|
||||
IQ_mf = toCpx(__IQ_mf);
|
||||
return;
|
||||
}
|
||||
|
||||
// Further BB processing
|
||||
// @2 x symbolrate
|
||||
while(buf_ip->len())
|
||||
{
|
||||
IQ_mf = toCpx(buf_ip->readAt(0));
|
||||
|
||||
// AGC Blind process samples
|
||||
IQ_agc = CpxScaleRealS(IQ_mf, AGC_GetWeight(&agcBlind));
|
||||
|
||||
// Symbol timing recovery
|
||||
Vd = STRGardnerProcess(&m_SymbolTimingRevovery, IQ_agc);
|
||||
|
||||
// Carrier Derotator
|
||||
IQ_cpr = toCpx(m_nco_cpr.mixComplexS(toComplexScalar(IQ_agc), ComplexScalar(1,1)));
|
||||
m_nco_cpr.process(m_dOmega_vco, m_params.CPR_phase);
|
||||
|
||||
if (TimingCorrectorIsSkip(&m_timing_corrector))
|
||||
{
|
||||
if (!TimingCorrectorIsStuff(&m_timing_corrector))
|
||||
break;
|
||||
}
|
||||
|
||||
IQ_eq_in = IQ_cpr;
|
||||
|
||||
// Operate at symbol clock
|
||||
@@ -556,12 +542,6 @@ void Receiver::processBaseband(CVec const &iq, uint32_t len)
|
||||
sym_err = SymMapGetError(m_pSymMapper, IQ_soft, sym);
|
||||
IQ_hard = sym_err.hard_sym;
|
||||
|
||||
// Timing detector
|
||||
if (m_params.str_mode == str_mode_enabled)
|
||||
{
|
||||
m_Vc = LeadLagProcess(&m_loop_filter_str, &m_params.str_loopfilter_coeff[m_params.str_loopfilter_coeff_index], Vd);
|
||||
}
|
||||
|
||||
// Carrier Phase Recovery
|
||||
if (m_params.cpr_mode == cpr_mode_enabled)
|
||||
{
|
||||
@@ -683,8 +663,6 @@ void Receiver::processBaseband(CVec const &iq, uint32_t len)
|
||||
if (m_pDataListener)
|
||||
m_pDataListener->receiverDataChanged(this);
|
||||
}
|
||||
} while (TimingCorrectorIsStuff(&m_timing_corrector));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -706,10 +684,9 @@ void Receiver::initCPR()
|
||||
void Receiver::initSTR()
|
||||
{
|
||||
// Gardner Symbol Timing Recovery
|
||||
STRGardnerInit(&m_SymbolTimingRevovery);
|
||||
LeadLagInit(&m_loop_filter_str, 0.0);
|
||||
TimingCorrectorInit(&m_timing_corrector, (radio_float_t)0.1);
|
||||
m_Vc = 0;
|
||||
m_timingGenerator.setOmega(1.0);
|
||||
|
||||
}
|
||||
|
||||
void Receiver::initSymbolMapper()
|
||||
@@ -886,8 +863,7 @@ void Receiver::statisticsReset()
|
||||
|
||||
void Receiver::strReset()
|
||||
{
|
||||
LeadLagSetState(&m_loop_filter_str, 0);
|
||||
STRGardnerInit(&m_SymbolTimingRevovery);
|
||||
m_timingGenerator.reset();
|
||||
m_statusListeners.call(&ReceiverStatusListener::receiverStatusChanged, this);
|
||||
}
|
||||
|
||||
|
||||
+58
-3
@@ -271,6 +271,63 @@ public:
|
||||
virtual void receiverDataChanged(Receiver *pObj) = 0;
|
||||
};
|
||||
|
||||
// Symbol timing recovery
|
||||
class TimingGeneratorGardner : public Interpolation::TimingGenerator
|
||||
{
|
||||
// Loop-Filter
|
||||
lead_lag_filter_t *filter;
|
||||
lead_lag_coeff_t *coeff;
|
||||
|
||||
// Gardner Symbol Timing Recovery
|
||||
str_t m_SymbolTimingRevovery;
|
||||
bool is_time;
|
||||
radio_float_t m_omega;
|
||||
|
||||
public:
|
||||
TimingGeneratorGardner()
|
||||
: Interpolation::TimingGenerator()
|
||||
, filter(nullptr)
|
||||
, coeff(nullptr)
|
||||
{
|
||||
STRGardnerInit(&m_SymbolTimingRevovery);
|
||||
is_time = true;
|
||||
}
|
||||
virtual ~TimingGeneratorGardner() = default;
|
||||
|
||||
void reset()
|
||||
{
|
||||
LeadLagSetState(filter, 0);
|
||||
}
|
||||
|
||||
void loopFilterSetup(lead_lag_filter_t *pFilter, lead_lag_coeff_t *pCoeff)
|
||||
{
|
||||
filter = pFilter;
|
||||
coeff = pCoeff;
|
||||
}
|
||||
|
||||
void setOmega(radio_float_t omega)
|
||||
{
|
||||
LeadLagInit(filter, omega);
|
||||
m_omega = omega;
|
||||
}
|
||||
|
||||
void process(ComplexScalar const &iq)
|
||||
{
|
||||
// @2 x symbolrate
|
||||
// Symbol timing recovery
|
||||
radio_float_t vd = STRGardnerProcess(&m_SymbolTimingRevovery, toCpx(iq));
|
||||
|
||||
if (is_time)
|
||||
{
|
||||
// @1 x symbolrate
|
||||
m_omega = LeadLagProcess(filter, coeff, vd);
|
||||
}
|
||||
is_time = not is_time;
|
||||
|
||||
update(m_omega);
|
||||
}
|
||||
};
|
||||
|
||||
class Receiver : public ReceiverInterface, public IDeFormatter, public Timer
|
||||
{
|
||||
public:
|
||||
@@ -322,9 +379,7 @@ private:
|
||||
lead_lag_filter_t m_loop_filter_cpr;
|
||||
|
||||
// Gardner Symbol Timing Recovery
|
||||
str_t m_SymbolTimingRevovery;
|
||||
timing_corrector_t m_timing_corrector;
|
||||
radio_float_t m_Vc;
|
||||
TimingGeneratorGardner m_timingGenerator;
|
||||
|
||||
// AGC
|
||||
// Blind
|
||||
|
||||
Reference in New Issue
Block a user