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