feat(dmr): add receive frontend and AMBE adapter

This commit is contained in:
2026-07-14 18:38:39 +03:00
parent f33a1fbd0a
commit 53a3681618
20 changed files with 998 additions and 30 deletions
+31
View File
@@ -0,0 +1,31 @@
program dmr_bindings_test;
{$MODE Delphi}
uses
SysUtils, DMRBindings;
var
Decoder: Pointer;
Bits: array[0..DMR_AMBE_BITS - 1] of Byte;
PCM: array[0..DMR_PCM_SAMPLES - 1] of Single;
Info: TDMRMbeResult;
begin
if not DMRLoad then
begin
WriteLn(DMRLastError);
Halt(1);
end;
Decoder := DMRMbeCreate(3);
if Decoder = nil then Halt(2);
try
FillChar(Bits, SizeOf(Bits), 0);
Bits[0] := 2; // ABI must reject values other than 0/1 before mbelib.
if DMRMbeDecode(Decoder, @Bits[0], @PCM[0], @Info) <> -2 then Halt(3);
DMRMbeReset(Decoder);
finally
DMRMbeDestroy(Decoder);
DMRUnload;
end;
WriteLn('DMR native bindings tests passed');
end.
+68
View File
@@ -0,0 +1,68 @@
program dmr_frontend_test;
{$MODE Delphi}
uses
{$IFDEF UNIX}cthreads,{$ENDIF}
Classes, SysUtils, DMRDecoder;
const
BS_VOICE_SYNC = '131111333113313313113313';
procedure FeedSync(D: TDMRDecoder; const Pattern: string; Invert: Boolean);
var
L, R: array of Single;
i, j, p: Integer;
V: Single;
begin
// Three leading samples ensure the detector really searches all ten timing
// hypotheses instead of relying on an aligned first sample.
SetLength(L, 3 + Length(Pattern) * DMR_SAMPLES_PER_SYM + 20);
SetLength(R, Length(L));
p := 3;
for i := 1 to Length(Pattern) do
begin
if Pattern[i] = '1' then V := 0.7 else V := -0.7;
if Invert then V := -V;
for j := 0 to DMR_SAMPLES_PER_SYM - 1 do
begin
L[p] := V;
R[p] := V;
Inc(p);
end;
end;
D.FeedAudio(L, R, Length(L));
end;
var
D: TDMRDecoder;
S: TDMRStatus;
begin
D := TDMRDecoder.Create;
try
D.SetEnabled(True);
FeedSync(D, BS_VOICE_SYNC, False);
Sleep(50);
D.GetStatus(S);
if (not S.Synced) or (S.SyncKind <> dskBSVoice) or S.Inverted then
begin
WriteLn('normal sync failed');
Halt(1);
end;
D.SetEnabled(False);
D.SetInverted(True);
D.SetEnabled(True);
FeedSync(D, BS_VOICE_SYNC, True);
Sleep(50);
D.GetStatus(S);
if (not S.Synced) or (S.SyncKind <> dskBSVoice) or (not S.Inverted) then
begin
WriteLn('inverted sync failed');
Halt(2);
end;
WriteLn('DMR front-end sync tests passed');
finally
D.Free;
end;
end.