mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:27:33 +00:00
feat(dmr): decode and route AMBE voice
This commit is contained in:
+77
-3
@@ -3,9 +3,21 @@ unit DMRProtocol;
|
||||
{
|
||||
Small, allocation-free DMR burst protocol layer.
|
||||
|
||||
The CACH interleave and Hamming/Golay generator matrices are derived from
|
||||
dsd-fme (src/dmr_bs.c and src/fec.c). The original code is distributed
|
||||
under the ISC licence; see the dsd-fme source tree for its full notice.
|
||||
The CACH/AMBE interleavers and Hamming/Golay matrices are derived from
|
||||
dsd-fme (src/dmr_bs.c, src/fec.c and include/dmr_const.h).
|
||||
|
||||
Copyright (C) 2010 DSD Author
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
}
|
||||
|
||||
{$IFDEF FPC}
|
||||
@@ -25,6 +37,8 @@ type
|
||||
TDMRBit7 = array[0..6] of Byte;
|
||||
TDMRBit20 = array[0..19] of Byte;
|
||||
TDMRBit96 = array[0..95] of Byte;
|
||||
TDMRAMBEFrame = array[0..95] of Byte;
|
||||
TDMRAMBEFrames = array[0..2] of TDMRAMBEFrame;
|
||||
|
||||
TDMRCACH = record
|
||||
Valid: Boolean;
|
||||
@@ -68,6 +82,10 @@ function DMRGolay208Encode(Value: Byte): TDMRBit20;
|
||||
procedure DMRBPTC19696Encode(const Payload: TDMRBit96;
|
||||
out Burst: TDMRDibitBurst);
|
||||
procedure DMRFullLCSetParity(var Payload: TDMRBit96; DataType: Integer);
|
||||
procedure DMRExtractAMBEFrames(const Burst: TDMRDibitBurst;
|
||||
out Frames: TDMRAMBEFrames);
|
||||
procedure DMRInsertAMBEFrames(const Frames: TDMRAMBEFrames;
|
||||
var Burst: TDMRDibitBurst);
|
||||
function DMRDecodeCACH(const Burst: TDMRDibitBurst; out CACH: TDMRCACH): Boolean;
|
||||
function DMRDecodeSlotType(const Burst: TDMRDibitBurst;
|
||||
out SlotType: TDMRSlotType): Boolean;
|
||||
@@ -110,6 +128,19 @@ const
|
||||
HAMMING_15_11_SYNDROME: array[0..14] of Byte =
|
||||
(9,13,15,14,7,10,5,11,12,6,3, 8,4,2,1);
|
||||
|
||||
AMBE_W: array[0..35] of Byte = (
|
||||
0,1,0,1,0,1, 0,1,0,1,0,1, 0,1,0,1,0,1,
|
||||
0,1,0,1,0,2, 0,2,0,2,0,2, 0,2,0,2,0,2);
|
||||
AMBE_X: array[0..35] of Byte = (
|
||||
23,10,22,9,21,8, 20,7,19,6,18,5, 17,4,16,3,15,2,
|
||||
14,1,13,0,12,10, 11,9,10,8,9,7, 8,6,7,5,6,4);
|
||||
AMBE_Y: array[0..35] of Byte = (
|
||||
0,2,0,2,0,2, 0,2,0,3,0,3, 1,3,1,3,1,3,
|
||||
1,3,1,3,1,3, 1,3,1,3,1,3, 1,3,1,3,1,3);
|
||||
AMBE_Z: array[0..35] of Byte = (
|
||||
5,3,4,2,3,1, 2,0,1,13,0,12, 22,11,21,10,20,9,
|
||||
19,8,18,7,17,6, 16,5,15,4,14,3, 13,2,12,1,11,0);
|
||||
|
||||
function DMRHamming74Encode(Value: Byte): TDMRBit7;
|
||||
var
|
||||
i, j: Integer;
|
||||
@@ -203,6 +234,49 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function AMBEDibitIndex(FrameIndex, DibitIndex: Integer): Integer;
|
||||
begin
|
||||
case FrameIndex of
|
||||
0: Result := 12 + DibitIndex;
|
||||
1: if DibitIndex < 18 then Result := 48 + DibitIndex
|
||||
else Result := 90 + DibitIndex - 18;
|
||||
else
|
||||
Result := 108 + DibitIndex;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure DMRExtractAMBEFrames(const Burst: TDMRDibitBurst;
|
||||
out Frames: TDMRAMBEFrames);
|
||||
var
|
||||
FrameIndex, i, DibitIndex: Integer;
|
||||
Dibit: Byte;
|
||||
begin
|
||||
FillChar(Frames, SizeOf(Frames), 0);
|
||||
for FrameIndex := 0 to 2 do
|
||||
for i := 0 to 35 do
|
||||
begin
|
||||
DibitIndex := AMBEDibitIndex(FrameIndex, i);
|
||||
Dibit := Burst[DibitIndex];
|
||||
Frames[FrameIndex][AMBE_W[i] * 24 + AMBE_X[i]] := (Dibit shr 1) and 1;
|
||||
Frames[FrameIndex][AMBE_Y[i] * 24 + AMBE_Z[i]] := Dibit and 1;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure DMRInsertAMBEFrames(const Frames: TDMRAMBEFrames;
|
||||
var Burst: TDMRDibitBurst);
|
||||
var
|
||||
FrameIndex, i, DibitIndex: Integer;
|
||||
begin
|
||||
for FrameIndex := 0 to 2 do
|
||||
for i := 0 to 35 do
|
||||
begin
|
||||
DibitIndex := AMBEDibitIndex(FrameIndex, i);
|
||||
Burst[DibitIndex] :=
|
||||
((Frames[FrameIndex][AMBE_W[i] * 24 + AMBE_X[i]] and 1) shl 1) or
|
||||
(Frames[FrameIndex][AMBE_Y[i] * 24 + AMBE_Z[i]] and 1);
|
||||
end;
|
||||
end;
|
||||
|
||||
function DecodeHamming74(const Received: TDMRBit7; out Value: Byte;
|
||||
out Corrected: Integer): Boolean;
|
||||
var
|
||||
|
||||
Reference in New Issue
Block a user