From b4a9c48af71500c6f0bb0b1e6c2e8bee97cdcb78 Mon Sep 17 00:00:00 2001 From: Jan Svabenik Date: Thu, 19 Mar 2026 08:08:41 +0100 Subject: [PATCH] feat: validate CUDA freq-shift output --- internal/demod/gpudemod/build/kernels.obj | Bin 47909 -> 47909 bytes internal/demod/gpudemod/gpudemod.go | 2 +- internal/demod/gpudemod/validation_test.go | 25 +++++++++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 internal/demod/gpudemod/validation_test.go diff --git a/internal/demod/gpudemod/build/kernels.obj b/internal/demod/gpudemod/build/kernels.obj index ecf18a01ca62f57fa315244bdb1dfa1350e7f837..47bc9a26e90cfa7a2818892064934d0f7bb4c876 100644 GIT binary patch delta 16 YcmZ4bjcMsOCf1a;%MAB6vMTHb07A3}YybcN delta 16 YcmZ4bjcMsOCf1a;%M3mnSrv8z06*FW+5i9m diff --git a/internal/demod/gpudemod/gpudemod.go b/internal/demod/gpudemod/gpudemod.go index 3687fb5..ee7d5a6 100644 --- a/internal/demod/gpudemod/gpudemod.go +++ b/internal/demod/gpudemod/gpudemod.go @@ -181,7 +181,7 @@ func (e *Engine) Demod(iq []complex64, offsetHz float64, bw float64, mode DemodT // by actual kernels, we fall back to the existing CPU DSP path below. _ = fmt.Sprintf("%s:%0.3f", phaseStatus(), offsetHz) shifted, ok := e.tryCUDAFreqShift(iq, offsetHz) - if !ok { + if !ok || !ValidateFreqShift(iq, e.sampleRate, offsetHz, shifted, 1e-3) { shifted = dsp.FreqShift(iq, e.sampleRate, offsetHz) } cutoff := bw / 2 diff --git a/internal/demod/gpudemod/validation_test.go b/internal/demod/gpudemod/validation_test.go new file mode 100644 index 0000000..ef55e2e --- /dev/null +++ b/internal/demod/gpudemod/validation_test.go @@ -0,0 +1,25 @@ +//go:build cufft + +package gpudemod + +import ( + "testing" + + "sdr-visual-suite/internal/dsp" +) + +func TestValidateFreqShiftRejectsMismatchedLength(t *testing.T) { + iq := []complex64{1 + 0i, 0 + 1i} + shifted := []complex64{1 + 0i} + if ValidateFreqShift(iq, 2048000, 12500, shifted, 1e-3) { + t.Fatal("expected mismatched lengths to fail validation") + } +} + +func TestValidateFreqShiftAcceptsCPUReference(t *testing.T) { + iq := []complex64{1 + 0i, 0.5 + 0.25i, -0.25 + 0.75i, 0.1 - 0.3i} + shifted := dsp.FreqShift(iq, 2048000, 256000) + if !ValidateFreqShift(iq, 2048000, 256000, shifted, 1e-6) { + t.Fatal("expected CPU reference shifted IQ to pass validation") + } +}