program fectest2; {$MODE Delphi} { Валидация TBeaconFEC против эталонных тест-векторов gr-satellites (python/components/deframers/qa_ao40_fec_deframer_*). Гоним поток мягких символов через PushSoftSymbol и сверяем выданный 256-байтовый кадр с эталоном. Решает вопрос конвенции Viterbi (libfec [0x6D,0x4F] vs AO-40 [0x4F,-0x6D]). } uses SysUtils, Classes, BeaconFEC; const GR = '/home/vladimir/Документы/source/gr-satellites/python/components/deframers/'; SymPath = GR + 'qa_ao40_fec_deframer_symbols.f32'; // qa_ao40_fec_deframer.py: финальный кадр (256 байт) FrameRef: array[0..255] of Byte = ( 137, 0, 0, 0, 0, 0, 0, 0, 0, 31, 204, 0, 206, 2, 209, 0, 0, 7, 8, 9, 9, 0, 0, 5, 1, 1, 0, 64, 19, 47, 200, 242, 92, 143, 52, 35, 243, 186, 11, 93, 98, 116, 81, 199, 234, 250, 105, 74, 154, 159, 0, 9, 239, 160, 31, 244, 167, 234, 74, 198, 143, 17, 64, 17, 30, 16, 247, 1, 62, 32, 100, 0, 215, 139, 248, 215, 148, 200, 147, 168, 42, 218, 82, 166, 14, 88, 14, 200, 15, 78, 1, 29, 32, 90, 0, 219, 148, 168, 170, 138, 152, 19, 172, 105, 10, 166, 168, 16, 230, 16, 146, 15, 184, 1, 80, 32, 100, 0, 215, 150, 168, 193, 139, 72, 37, 171, 169, 202, 206, 157, 16, 118, 15, 201, 16, 85, 1, 58, 32, 90, 0, 215, 151, 41, 8, 140, 72, 79, 169, 106, 90, 242, 164, 16, 57, 15, 123, 15, 134, 1, 73, 32, 100, 0, 215, 148, 8, 208, 138, 216, 42, 173, 106, 90, 126, 180, 14, 83, 14, 155, 14, 183, 1, 9, 32, 90, 0, 219, 153, 168, 242, 143, 232, 56, 175, 170, 138, 194, 158, 14, 222, 15, 72, 14, 49, 1, 49, 32, 90, 0, 206, 155, 200, 255, 136, 104, 27, 178, 106, 90, 202, 167, 15, 195, 14, 116, 14, 88, 1, 52, 32, 90, 0, 215, 155, 57, 27, 151, 184, 197, 176, 43, 58, 214, 181, 1, 107, 0, 106, 2, 158, 0, 3, 32, 19, 0); type TFrameChecker = class Got: Boolean; Match: Boolean; NErr: Integer; RSErr: Integer; procedure OnFrame(const Frame: TBeaconFrame; RSErrors: Integer); end; procedure TFrameChecker.OnFrame(const Frame: TBeaconFrame; RSErrors: Integer); var i, e: Integer; begin if Got then Exit; // берём первый кадр Got := True; RSErr := RSErrors; e := 0; for i := 0 to 255 do if Frame[i] <> FrameRef[i] then Inc(e); NErr := e; Match := (e = 0); end; var fec: TBeaconFEC; chk: TFrameChecker; fs: TFileStream; n, i: Integer; buf: array of Single; begin if not FileExists(SymPath) then begin WriteLn('symbols file not found: ', SymPath); Halt(2); end; fs := TFileStream.Create(SymPath, fmOpenRead); try n := fs.Size div 4; SetLength(buf, n); fs.ReadBuffer(buf[0], n * 4); finally fs.Free; end; WriteLn('loaded ', n, ' soft symbols'); chk := TFrameChecker.Create; fec := TBeaconFEC.Create; try fec.OnFrame := chk.OnFrame; for i := 0 to n - 1 do fec.PushSoftSymbol(buf[i]); WriteLn('frames decoded: ', fec.Frames); if not chk.Got then begin WriteLn('==> FAIL: no frame decoded (sync not found / RS uncorrectable)'); Halt(1); end; WriteLn(Format('frame: %d/256 byte mismatches, RS errors=%d', [chk.NErr, chk.RSErr])); if chk.Match then WriteLn('==> PASS: frame matches gr-satellites reference') else begin WriteLn('==> FAIL: frame does not match reference'); Halt(1); end; finally fec.Free; chk.Free; end; end.