2537 Complex Vector Oscillator (256/512) Lanes Can Drift Apart Over Time (#2538)

* #2535 Heterodyne Channelizer enhancements and corrections.

* #2537 Complex vector oscillator SIMD lane drift.

Realigns the SIMD lanes every 262,144 samples. At frequencies where the
rotation for a set of lanes is nearly a whole or half turn, rounding affects
each lane differently and the lanes drift apart until the next frequency
change, producing spurs at multiples of the sample rate divided by the lane
count.  Lane phase error at 3125 Hz with a 50 kHz sample rate was about -38 dBc
after one hour and is now about -83 dBc with 16 lanes and -73 dBc with 8 lanes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* #2537 test updates

* #2537 test updates

---------

Co-authored-by: denny <dennis.sheirer@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Denny Sheirer
2026-10-30 08:42:49 -04:00
committed by GitHub
parent 9ebbf957a2
commit 85bfd21257
60 changed files with 1570 additions and 171 deletions

View File

@@ -29,7 +29,7 @@ public enum CalibrationType
{
//There's an oddity with these two vector implementations where it takes ~30x longer when it runs
//after any other calibrations ... so we always sort to top to run this one first
OSCILLATOR_COMPLEX("Complex Oscillator", 1),
OSCILLATOR_COMPLEX("Complex Oscillator", 2),
GAIN_COMPLEX("Complex Gain", 1),
AM_DEMODULATOR("AM Demodulator", 1),
@@ -48,7 +48,7 @@ public enum CalibrationType
HILBERT_TRANSFORM("Hilbert Transform", 1),
INTERPOLATOR("Interpolator", 1),
MAGNITUDE("Magnitude", 1),
MIXER_COMPLEX("Complex Mixer", 1),
MIXER_COMPLEX("Complex Mixer", 2),
NXDN_SOFT_SYNC_DETECTOR("NXDN Soft Sync Detector", 3),
OSCILLATOR_REAL("Real Oscillator", 1),
P25P1_SOFT_SYNC_DETECTOR("P25 Phase 1 Soft Sync Detector", 2),

View File

@@ -22,6 +22,7 @@ package io.github.dsheirer.vector.calibrate.oscillator;
import io.github.dsheirer.dsp.oscillator.IComplexOscillator;
import io.github.dsheirer.dsp.oscillator.ScalarComplexOscillator;
import io.github.dsheirer.dsp.oscillator.VectorComplexOscillator;
import io.github.dsheirer.sample.complex.ComplexSamples;
import io.github.dsheirer.vector.calibrate.Calibration;
import io.github.dsheirer.vector.calibrate.CalibrationException;
import io.github.dsheirer.vector.calibrate.CalibrationType;
@@ -123,8 +124,8 @@ public class ComplexOscillatorCalibration extends Calibration
while((System.currentTimeMillis() - start) < ITERATION_DURATION_MS)
{
float[] generated = mScalarOscillator.generate(BUFFER_SIZE);
accumulator += generated[0];
ComplexSamples generated = mScalarOscillator.generateComplexSamples(BUFFER_SIZE, 0);
accumulator += generated.i()[0];
count++;
}
@@ -144,8 +145,8 @@ public class ComplexOscillatorCalibration extends Calibration
while((System.currentTimeMillis() - start) < ITERATION_DURATION_MS)
{
float[] generated = mVectorOscillator.generate(BUFFER_SIZE);
accumulator += generated[0];
ComplexSamples generated = mVectorOscillator.generateComplexSamples(BUFFER_SIZE, 0);
accumulator += generated.i()[0];
count++;
}