mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +00:00
fix(dmr): choose timing phase by sync variance
This commit is contained in:
+46
-10
@@ -158,7 +158,7 @@ type
|
||||
procedure LoseSync;
|
||||
function Digitize(Phase: Integer; Symbol: Double): Byte;
|
||||
function SliceSymbol(Symbol, OuterLevel: Double): Byte;
|
||||
function SyncEyeOpening(Phase: Integer): Double;
|
||||
function SyncPhaseQuality(Phase: Integer): Double;
|
||||
procedure CalibrateSyncLevels(Phase: Integer);
|
||||
procedure StartBurstTracking(Phase: Integer);
|
||||
procedure CompleteBurst;
|
||||
@@ -627,13 +627,49 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TDMRDecoder.SyncEyeOpening(Phase: Integer): Double;
|
||||
function TDMRDecoder.SyncPhaseQuality(Phase: Integer): Double;
|
||||
var
|
||||
i: Integer;
|
||||
i, P, PositiveCount, NegativeCount: Integer;
|
||||
V, PositiveMean, NegativeMean, ErrorSum, Scale: Double;
|
||||
begin
|
||||
Result := 1.0e300;
|
||||
PositiveMean := 0;
|
||||
NegativeMean := 0;
|
||||
PositiveCount := 0;
|
||||
NegativeCount := 0;
|
||||
P := (FHistoryPos[Phase] + DMR_SYNC_END_DIBIT + 1 - 24) mod
|
||||
(DMR_SYNC_END_DIBIT + 1);
|
||||
for i := 0 to 23 do
|
||||
Result := Min(Result, FMagHistory[Phase, i]);
|
||||
begin
|
||||
V := FSymbolHistory[Phase, P];
|
||||
if V >= 0 then
|
||||
begin
|
||||
PositiveMean := PositiveMean + V;
|
||||
Inc(PositiveCount);
|
||||
end
|
||||
else
|
||||
begin
|
||||
NegativeMean := NegativeMean - V;
|
||||
Inc(NegativeCount);
|
||||
end;
|
||||
P := (P + 1) mod (DMR_SYNC_END_DIBIT + 1);
|
||||
end;
|
||||
if (PositiveCount = 0) or (NegativeCount = 0) then Exit(-1.0e300);
|
||||
PositiveMean := PositiveMean / PositiveCount;
|
||||
NegativeMean := NegativeMean / NegativeCount;
|
||||
ErrorSum := 0;
|
||||
P := (FHistoryPos[Phase] + DMR_SYNC_END_DIBIT + 1 - 24) mod
|
||||
(DMR_SYNC_END_DIBIT + 1);
|
||||
for i := 0 to 23 do
|
||||
begin
|
||||
V := FSymbolHistory[Phase, P];
|
||||
if V >= 0 then ErrorSum := ErrorSum + Sqr(V - PositiveMean)
|
||||
else ErrorSum := ErrorSum + Sqr((-V) - NegativeMean);
|
||||
P := (P + 1) mod (DMR_SYNC_END_DIBIT + 1);
|
||||
end;
|
||||
Scale := Sqr(0.5 * (PositiveMean + NegativeMean));
|
||||
if Scale <= 1.0e-18 then Exit(-1.0e300);
|
||||
// Higher is better: zero denotes perfectly compact outer-level clusters.
|
||||
Result := -ErrorSum / (24.0 * Scale);
|
||||
end;
|
||||
|
||||
procedure TDMRDecoder.CalibrateSyncLevels(Phase: Integer);
|
||||
@@ -789,14 +825,14 @@ begin
|
||||
FStatusLock.Enter;
|
||||
try
|
||||
// Adjacent timing hypotheses recognize the same physical burst within one
|
||||
// sample period. Keep the phase with the largest 24-symbol eye opening,
|
||||
// not merely the first phase that happened to match the sign pattern.
|
||||
// sample period. Keep the phase whose known positive/negative sync levels
|
||||
// form the tightest clusters, not merely the first sign-pattern match.
|
||||
if (FLastSyncSample <> 0) and
|
||||
(FSampleNo - FLastSyncSample <= DMR_SAMPLES_PER_SYM * 2) then
|
||||
begin
|
||||
if SyncEyeOpening(Phase) > FBestSyncQuality then
|
||||
if SyncPhaseQuality(Phase) > FBestSyncQuality then
|
||||
begin
|
||||
FBestSyncQuality := SyncEyeOpening(Phase);
|
||||
FBestSyncQuality := SyncPhaseQuality(Phase);
|
||||
FSyncKind := Kind;
|
||||
FInverted := Inverted;
|
||||
CalibrateSyncLevels(Phase);
|
||||
@@ -809,7 +845,7 @@ begin
|
||||
Inc(FSyncCount);
|
||||
FLastSyncTick := NowTick;
|
||||
FLastSyncSample := FSampleNo;
|
||||
FBestSyncQuality := SyncEyeOpening(Phase);
|
||||
FBestSyncQuality := SyncPhaseQuality(Phase);
|
||||
CalibrateSyncLevels(Phase);
|
||||
if Kind in [dskMSData, dskMSVoice] then FMobileActiveBurst := True;
|
||||
StartBurstTracking(Phase);
|
||||
|
||||
Reference in New Issue
Block a user