mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 19:45:09 +00:00
fix(dmr): track voice state per timeslot
This commit is contained in:
+38
-11
@@ -113,11 +113,12 @@ type
|
||||
FCurrentBurstPos: Integer;
|
||||
FLastBurst: TDMRDibitBurst;
|
||||
FLastBurstInfo: TDMRBurstInfo;
|
||||
FLastLinkControl: TDMRLinkControl;
|
||||
FLinkControl: array[0..1] of TDMRLinkControl;
|
||||
FLastLCSlot: Integer;
|
||||
FColorCodeValid: Boolean;
|
||||
FColorCode, FLastDataType, FSlotTypeCorrectedBits: Integer;
|
||||
FSelectedSlot: Integer;
|
||||
FLastSelectedVoiceTick: QWord;
|
||||
FVoiceFrameCount, FVoiceErrorCount: QWord;
|
||||
FOnAudio: TDMRAudioEvent;
|
||||
FBurstCount: QWord;
|
||||
@@ -280,13 +281,14 @@ begin
|
||||
FillChar(FCurrentBurst, SizeOf(FCurrentBurst), 0);
|
||||
FillChar(FLastBurst, SizeOf(FLastBurst), 0);
|
||||
FillChar(FLastBurstInfo, SizeOf(FLastBurstInfo), 0);
|
||||
FillChar(FLastLinkControl, SizeOf(FLastLinkControl), 0);
|
||||
FillChar(FLinkControl, SizeOf(FLinkControl), 0);
|
||||
FLastLCSlot := -1;
|
||||
FColorCodeValid := False;
|
||||
FColorCode := 0;
|
||||
FLastDataType := 0;
|
||||
FSlotTypeCorrectedBits := 0;
|
||||
FSelectedSlot := -1;
|
||||
FLastSelectedVoiceTick := 0;
|
||||
FVoiceFrameCount := 0;
|
||||
FVoiceErrorCount := 0;
|
||||
DMRMbeReset(FMbe);
|
||||
@@ -487,7 +489,6 @@ begin
|
||||
end;
|
||||
if FLastBurstInfo.LinkControl.Decoded then
|
||||
begin
|
||||
FLastLinkControl := FLastBurstInfo.LinkControl;
|
||||
if (FSyncKind in [dskBSData, dskBSVoice]) and
|
||||
FLastBurstInfo.CACH.Valid then
|
||||
FLastLCSlot := FLastBurstInfo.CACH.Slot
|
||||
@@ -495,7 +496,12 @@ begin
|
||||
FLastLCSlot := 1
|
||||
else
|
||||
FLastLCSlot := 0;
|
||||
if FSelectedSlot < 0 then FSelectedSlot := FLastLCSlot;
|
||||
FLinkControl[FLastLCSlot] := FLastBurstInfo.LinkControl;
|
||||
if FSelectedSlot < 0 then
|
||||
begin
|
||||
FSelectedSlot := FLastLCSlot;
|
||||
FLastSelectedVoiceTick := GetTickCount64;
|
||||
end;
|
||||
end;
|
||||
DecodeVoiceBurst;
|
||||
Inc(FBurstCount);
|
||||
@@ -508,6 +514,7 @@ var
|
||||
PCM: array[0..DMR_PCM_SAMPLES - 1] of Single;
|
||||
MbeResult: TDMRMbeResult;
|
||||
Slot, FrameIndex, RC: Integer;
|
||||
NowTick: QWord;
|
||||
begin
|
||||
if (FMbe = nil) or (FLastSyncTick = 0) or
|
||||
(GetTickCount64 - FLastSyncTick > DMR_SYNC_HOLD_MS) then Exit;
|
||||
@@ -521,8 +528,20 @@ begin
|
||||
end
|
||||
else if FSyncKind = dskDirectTS2Voice then Slot := 1
|
||||
else Slot := 0;
|
||||
if FSelectedSlot < 0 then FSelectedSlot := Slot;
|
||||
NowTick := GetTickCount64;
|
||||
if (FSelectedSlot < 0) or
|
||||
((Slot <> FSelectedSlot) and (FLastSelectedVoiceTick <> 0) and
|
||||
(NowTick - FLastSelectedVoiceTick > 1000)) then
|
||||
begin
|
||||
FSelectedSlot := Slot;
|
||||
DMRMbeReset(FMbe);
|
||||
end;
|
||||
if Slot <> FSelectedSlot then Exit;
|
||||
FLastSelectedVoiceTick := NowTick;
|
||||
// Service Options bit 6 denotes privacy/encryption. mbelib cannot decrypt
|
||||
// it, so suppress the characteristic digital noise while retaining IDs.
|
||||
if FLinkControl[Slot].Decoded and
|
||||
((FLinkControl[Slot].ServiceOptions and $40) <> 0) then Exit;
|
||||
|
||||
DMRExtractAMBEFrames(FLastBurst, Frames);
|
||||
for FrameIndex := 0 to 2 do
|
||||
@@ -576,6 +595,7 @@ end;
|
||||
procedure TDMRDecoder.GetStatus(out S: TDMRStatus);
|
||||
var
|
||||
NowTick: QWord;
|
||||
LCStatusSlot: Integer;
|
||||
begin
|
||||
FillChar(S, SizeOf(S), 0);
|
||||
NowTick := GetTickCount64;
|
||||
@@ -608,12 +628,19 @@ begin
|
||||
S.ColorCode := FColorCode;
|
||||
S.DataType := FLastDataType;
|
||||
S.SlotTypeCorrectedBits := FSlotTypeCorrectedBits;
|
||||
S.LinkControlValid := FLastLinkControl.Decoded;
|
||||
S.LCSlot := FLastLCSlot;
|
||||
S.LCOpcode := FLastLinkControl.Opcode;
|
||||
S.ServiceOptions := FLastLinkControl.ServiceOptions;
|
||||
S.TargetID := FLastLinkControl.TargetID;
|
||||
S.SourceID := FLastLinkControl.SourceID;
|
||||
LCStatusSlot := FSelectedSlot;
|
||||
if (LCStatusSlot < 0) or not FLinkControl[LCStatusSlot].Decoded then
|
||||
LCStatusSlot := FLastLCSlot;
|
||||
S.LinkControlValid := (LCStatusSlot >= 0) and
|
||||
FLinkControl[LCStatusSlot].Decoded;
|
||||
S.LCSlot := LCStatusSlot;
|
||||
if S.LinkControlValid then
|
||||
begin
|
||||
S.LCOpcode := FLinkControl[LCStatusSlot].Opcode;
|
||||
S.ServiceOptions := FLinkControl[LCStatusSlot].ServiceOptions;
|
||||
S.TargetID := FLinkControl[LCStatusSlot].TargetID;
|
||||
S.SourceID := FLinkControl[LCStatusSlot].SourceID;
|
||||
end;
|
||||
S.SelectedSlot := FSelectedSlot;
|
||||
S.VoiceFrameCount := FVoiceFrameCount;
|
||||
S.VoiceErrorCount := FVoiceErrorCount;
|
||||
|
||||
+2
-1
@@ -3594,7 +3594,8 @@ begin
|
||||
if not S.Synced then Exit(Format('DMR sync... %.3f', [S.SignalRMS]));
|
||||
if S.Inverted then Inv := ' INV' else Inv := '';
|
||||
Details := '';
|
||||
if S.CACHValid then Details := Format(' TS%d', [S.Slot + 1]);
|
||||
if S.LinkControlValid then Details := Format(' TS%d', [S.LCSlot + 1])
|
||||
else if S.CACHValid then Details := Format(' TS%d', [S.Slot + 1]);
|
||||
if S.SlotTypeValid then
|
||||
Details := Details + Format(' CC%d/DT%d', [S.ColorCode, S.DataType]);
|
||||
if S.LinkControlValid then Details := Details + Format(' TG%d', [S.TargetID]);
|
||||
|
||||
Reference in New Issue
Block a user