Transceiver: Compansate for frequency error.
This commit is contained in:
parent
8f01fd659e
commit
7a82180778
|
@ -1041,11 +1041,41 @@ inline float vectorRMS(const Vector<float> &vec)
|
||||||
return sqrt(rms/vec.size());
|
return sqrt(rms/vec.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool vectorLinearFit(const Vector<float> &y, float &slope, float &interceptor)
|
||||||
|
{
|
||||||
|
int len_y = y.size();
|
||||||
|
float numerator = 0.0;
|
||||||
|
float denominator = 0.0;
|
||||||
|
float avg_x = len_y/2.0;
|
||||||
|
float avg_y = 0.0;
|
||||||
|
|
||||||
|
if (len_y==0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (int i=0; i<len_y; i++)
|
||||||
|
avg_y += y[i];
|
||||||
|
avg_y /= len_y;
|
||||||
|
|
||||||
|
for (int i=0; i<len_y; i++) {
|
||||||
|
numerator += (i - avg_x) * (y[i] - avg_y);
|
||||||
|
denominator += (i - avg_x) * (i - avg_x);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (denominator == 0.0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
slope = numerator/denominator;
|
||||||
|
interceptor = avg_y - avg_x*slope;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void Transceiver::estimateBurstQuality(const BitVector &wBits, signalVector *received,
|
void Transceiver::estimateBurstQuality(const BitVector &wBits, signalVector *received,
|
||||||
const GSM::Time &wTime, size_t chan,
|
const GSM::Time &wTime, size_t chan,
|
||||||
Transceiver::BurstQuality &qual)
|
Transceiver::BurstQuality &qual)
|
||||||
{
|
{
|
||||||
signalVector *burst;
|
signalVector *burst;
|
||||||
|
float slope, interceptor;
|
||||||
|
|
||||||
// this code supports only 4 SPS modulation
|
// this code supports only 4 SPS modulation
|
||||||
// we also assume that received vector is 1 SPS
|
// we also assume that received vector is 1 SPS
|
||||||
|
@ -1065,11 +1095,24 @@ void Transceiver::estimateBurstQuality(const BitVector &wBits, signalVector *rec
|
||||||
// calculate phase error for each bit
|
// calculate phase error for each bit
|
||||||
for (size_t i=0; i<qual.phase_err.size(); i++) {
|
for (size_t i=0; i<qual.phase_err.size(); i++) {
|
||||||
float rx_phase = (*received)[i].arg();
|
float rx_phase = (*received)[i].arg();
|
||||||
|
// modulated data is 4SPS and is 1/4 bit shifted
|
||||||
float mod_phase = (*burst)[1+(2+i)*4].arg();
|
float mod_phase = (*burst)[1+(2+i)*4].arg();
|
||||||
qual.phase_err[i] = wrapAnglePi(rx_phase - mod_phase);
|
qual.phase_err[i] = wrapAnglePi(rx_phase - mod_phase);
|
||||||
qual.phase_err_deg[i] = rad2deg(qual.phase_err[i]);
|
qual.phase_err_deg[i] = rad2deg(qual.phase_err[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// compensate for frequency error
|
||||||
|
if (vectorLinearFit(qual.phase_err, slope, interceptor)) {
|
||||||
|
for (size_t i=0; i<qual.phase_err.size(); i++) {
|
||||||
|
qual.phase_err[i] -= i*slope + interceptor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert to degrees
|
||||||
|
for (size_t i=0; i<qual.phase_err.size(); i++) {
|
||||||
|
qual.phase_err_deg[i] = rad2deg(qual.phase_err[i]);
|
||||||
|
}
|
||||||
|
|
||||||
// calculate Peak and RMS values
|
// calculate Peak and RMS values
|
||||||
qual.phase_err_max_idx = vectorMaxAbs(qual.phase_err);
|
qual.phase_err_max_idx = vectorMaxAbs(qual.phase_err);
|
||||||
qual.phase_err_max = qual.phase_err[qual.phase_err_max_idx];
|
qual.phase_err_max = qual.phase_err[qual.phase_err_max_idx];
|
||||||
|
|
Loading…
Reference in New Issue