sigProcLib: fix C/I computation for 8-PSK modulated bursts

Change-Id: I860af60bc0fbd36dfb38316fad65ddd3a5827a8f
Related: Ib4ceec553f2e5f77bf3f6777724968456a180f5e
Related: OS#4006, OS#4373
This commit is contained in:
Sylvain Munaut 2021-02-04 20:37:01 +01:00 committed by Vadim Yanitskiy
parent 0f4d5791df
commit ad202d72e1
3 changed files with 38 additions and 17 deletions

View File

@ -734,11 +734,10 @@ int Transceiver::pullRadioVector(size_t chan, struct trx_ul_burst_ind *bi)
goto ret_idle; goto ret_idle;
} }
type = (CorrType) rc; rxBurst = demodAnyBurst(*burst, (CorrType) rc, cfg->rx_sps, &ebp);
bi->toa = ebp.toa; bi->toa = ebp.toa;
bi->tsc = ebp.tsc; bi->tsc = ebp.tsc;
bi->ci = ebp.ci; bi->ci = ebp.ci;
rxBurst = demodAnyBurst(*burst, cfg->rx_sps, ebp.amp, ebp.toa, type);
/* EDGE demodulator returns 444 (gSlotLen * 3) bits */ /* EDGE demodulator returns 444 (gSlotLen * 3) bits */
if (rxBurst->size() == EDGE_BURST_NBITS) { if (rxBurst->size() == EDGE_BURST_NBITS) {

View File

@ -1792,15 +1792,15 @@ static SoftVector *signalToSoftVector(signalVector *dec)
* stages. * stages.
*/ */
static signalVector *demodCommon(const signalVector &burst, int sps, static signalVector *demodCommon(const signalVector &burst, int sps,
complex chan, float toa) const struct estim_burst_params *ebp)
{ {
signalVector *delay, *dec; signalVector *delay, *dec;
if ((sps != 1) && (sps != 4)) if ((sps != 1) && (sps != 4))
return NULL; return NULL;
delay = delayVector(&burst, NULL, -toa * (float) sps); delay = delayVector(&burst, NULL, -ebp->toa * (float) sps);
scaleVector(*delay, (complex) 1.0 / chan); scaleVector(*delay, (complex) 1.0 / ebp->amp);
if (sps == 1) if (sps == 1)
return delay; return delay;
@ -1816,13 +1816,13 @@ static signalVector *demodCommon(const signalVector &burst, int sps,
* 4 SPS (if activated) to minimize distortion through the fractional * 4 SPS (if activated) to minimize distortion through the fractional
* delay filters. Symbol rotation and after always operates at 1 SPS. * delay filters. Symbol rotation and after always operates at 1 SPS.
*/ */
static SoftVector *demodGmskBurst(const signalVector &rxBurst, static SoftVector *demodGmskBurst(const signalVector &rxBurst, int sps,
int sps, complex channel, float TOA) const struct estim_burst_params *ebp)
{ {
SoftVector *bits; SoftVector *bits;
signalVector *dec; signalVector *dec;
dec = demodCommon(rxBurst, sps, channel, TOA); dec = demodCommon(rxBurst, sps, ebp);
if (!dec) if (!dec)
return NULL; return NULL;
@ -1835,6 +1835,27 @@ static SoftVector *demodGmskBurst(const signalVector &rxBurst,
return bits; return bits;
} }
static float computeEdgeCI(const signalVector *rot)
{
float err_pwr = 0.0f;
float step = 2.0f * M_PI_F / 8.0f;
for (size_t i = 8; i < rot->size() - 8; i++) {
/* Compute the ideal symbol */
complex sym = (*rot)[i];
float phase = step * roundf(sym.arg() / step);
complex ideal = complex(cos(phase), sin(phase));
/* Compute the error vector */
complex err = ideal - sym;
/* Accumulate power */
err_pwr += err.norm2();
}
return 3.0103f * log2f(1.0f * (rot->size() - 16) / err_pwr);
}
/* /*
* Demodulate an 8-PSK burst. Prior to symbol rotation, operate at * Demodulate an 8-PSK burst. Prior to symbol rotation, operate at
* 4 SPS (if activated) to minimize distortion through the fractional * 4 SPS (if activated) to minimize distortion through the fractional
@ -1845,19 +1866,20 @@ static SoftVector *demodGmskBurst(const signalVector &rxBurst,
* through the fractional delay filters at 1 SPS renders signal * through the fractional delay filters at 1 SPS renders signal
* nearly unrecoverable. * nearly unrecoverable.
*/ */
static SoftVector *demodEdgeBurst(const signalVector &burst, static SoftVector *demodEdgeBurst(const signalVector &burst, int sps,
int sps, complex chan, float toa) struct estim_burst_params *ebp)
{ {
SoftVector *bits; SoftVector *bits;
signalVector *dec, *rot, *eq; signalVector *dec, *rot, *eq;
dec = demodCommon(burst, sps, chan, toa); dec = demodCommon(burst, sps, ebp);
if (!dec) if (!dec)
return NULL; return NULL;
/* Equalize and derotate */ /* Equalize and derotate */
eq = convolve(dec, GSMPulse4->c0_inv, NULL, NO_DELAY); eq = convolve(dec, GSMPulse4->c0_inv, NULL, NO_DELAY);
rot = derotateEdgeBurst(*eq, 1); rot = derotateEdgeBurst(*eq, 1);
ebp->ci = computeEdgeCI(rot);
/* Soft slice and normalize */ /* Soft slice and normalize */
bits = softSliceEdgeBurst(*rot); bits = softSliceEdgeBurst(*rot);
@ -1869,13 +1891,13 @@ static SoftVector *demodEdgeBurst(const signalVector &burst,
return bits; return bits;
} }
SoftVector *demodAnyBurst(const signalVector &burst, int sps, complex amp, SoftVector *demodAnyBurst(const signalVector &burst, CorrType type,
float toa, CorrType type) int sps, struct estim_burst_params *ebp)
{ {
if (type == EDGE) if (type == EDGE)
return demodEdgeBurst(burst, sps, amp, toa); return demodEdgeBurst(burst, sps, ebp);
else else
return demodGmskBurst(burst, sps, amp, toa); return demodGmskBurst(burst, sps, ebp);
} }
bool sigProcLibSetup() bool sigProcLibSetup()

View File

@ -134,7 +134,7 @@ int detectAnyBurst(const signalVector &burst,
struct estim_burst_params *ebp); struct estim_burst_params *ebp);
/** Demodulate burst basde on type and output soft bits */ /** Demodulate burst basde on type and output soft bits */
SoftVector *demodAnyBurst(const signalVector &burst, int sps, SoftVector *demodAnyBurst(const signalVector &burst, CorrType type,
complex amp, float toa, CorrType type); int sps, struct estim_burst_params *ebp);
#endif /* SIGPROCLIB_H */ #endif /* SIGPROCLIB_H */