mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 16:47:31 -05:00
* Adopts same architecture and symbol processor as P1 C4FM/LSM, DMR and NXDN. * Soft symbol sync detection, processing and erro correction. * Scalar and vector soft sync detection and calibration * Improved time slot detection/prediction and ISCH processing. * Fixes bug in parsing sequential mac structures in SACCH * Vector calibration(s) cleanup across multiple calibrations * Error correction bug in ISCH * Renames differential demod shared with P1 LSM decoder. Co-authored-by: denny <dennis.sheirer@gmail.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2025 Dennis Sheirer
|
||||
* Copyright (C) 2014-2026 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -44,6 +44,7 @@ import io.github.dsheirer.vector.calibrate.sample.UnpackedSampleConverterCalibra
|
||||
import io.github.dsheirer.vector.calibrate.sync.DMRSoftSyncCalibration;
|
||||
import io.github.dsheirer.vector.calibrate.sync.NXDNSoftSyncCalibration;
|
||||
import io.github.dsheirer.vector.calibrate.sync.P25P1SoftSyncCalibration;
|
||||
import io.github.dsheirer.vector.calibrate.sync.P25P2SoftSyncCalibration;
|
||||
import io.github.dsheirer.vector.calibrate.window.WindowCalibration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -117,6 +118,7 @@ public class CalibrationManager
|
||||
sInstance.add(new MagnitudeCalibration());
|
||||
sInstance.add(new NXDNSoftSyncCalibration());
|
||||
sInstance.add(new P25P1SoftSyncCalibration());
|
||||
sInstance.add(new P25P2SoftSyncCalibration());
|
||||
sInstance.add(new RealDcRemovalCalibration());
|
||||
sInstance.add(new RealHalfBand11TapFilterCalibration());
|
||||
sInstance.add(new RealHalfBand15TapFilterCalibration());
|
||||
|
||||
@@ -34,7 +34,7 @@ public enum CalibrationType
|
||||
|
||||
AM_DEMODULATOR("AM Demodulator", 1),
|
||||
DC_REMOVAL_REAL("Real DC Removal Filter", 1),
|
||||
DMR_SOFT_SYNC_DETECTOR("DMR Soft Sync Detector", 1),
|
||||
DMR_SOFT_SYNC_DETECTOR("DMR Soft Sync Detector", 2),
|
||||
DIFFERENTIAL_DEMODULATOR("DQPSK Demodulator", 1),
|
||||
FILTER_FIR("FIR Filter", 1),
|
||||
FILTER_HALF_BAND_REAL_11_TAP("Real Half-Band Decimation Filter - 11 Tap", 1),
|
||||
@@ -48,12 +48,13 @@ public enum CalibrationType
|
||||
INTERPOLATOR("Interpolator", 1),
|
||||
MAGNITUDE("Magnitude", 1),
|
||||
MIXER_COMPLEX("Complex Mixer", 1),
|
||||
NXDN_SOFT_SYNC_DETECTOR("NXDN Soft Sync Detector", 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", 1),
|
||||
SAMPLE_PACKED_CONVERTER("Packed Sample Converter", 1),
|
||||
SAMPLE_UNPACKED_INTERLEAVED_ITERATOR("Unpacked Interleaved Sample Iterator", 1),
|
||||
SAMPLE_UNPACKED_ITERATOR("Unpacked Sample Iterator", 1),
|
||||
P25P1_SOFT_SYNC_DETECTOR("P25 Phase 1 Soft Sync Detector", 2),
|
||||
P25P2_SOFT_SYNC_DETECTOR("P25 Phase 2 Soft Sync Detector", 1),
|
||||
SAMPLE_PACKED_CONVERTER("Packed Sample Converter", 2),
|
||||
SAMPLE_UNPACKED_INTERLEAVED_ITERATOR("Unpacked Interleaved Sample Iterator", 2),
|
||||
SAMPLE_UNPACKED_ITERATOR("Unpacked Sample Iterator", 2),
|
||||
SQUELCHING_FM_DEMODULATOR("Squelching FM Demodulator", 1),
|
||||
WINDOW("Window", 1);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2025 Dennis Sheirer
|
||||
* Copyright (C) 2014-2026 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -106,7 +106,7 @@ public class PackedSampleConverterCalibration extends Calibration
|
||||
ScalarUnpackedSampleConverter scalor = new ScalarUnpackedSampleConverter();
|
||||
|
||||
long count = 0;
|
||||
long accumulator = 0;
|
||||
double accumulator = 0.0;
|
||||
|
||||
while((System.currentTimeMillis() - start) < ITERATION_DURATION_MS)
|
||||
{
|
||||
@@ -115,14 +115,14 @@ public class PackedSampleConverterCalibration extends Calibration
|
||||
count++;
|
||||
}
|
||||
|
||||
return count + (accumulator * 0);
|
||||
return count + (long)(accumulator * 0);
|
||||
}
|
||||
|
||||
private long testVector(ByteBuffer buffer)
|
||||
{
|
||||
VectorUnpackedSampleConverter vector = new VectorUnpackedSampleConverter();
|
||||
long start = System.currentTimeMillis();
|
||||
long accumulator = 0;
|
||||
double accumulator = 0.0;
|
||||
long count = 0;
|
||||
|
||||
while((System.currentTimeMillis() - start) < ITERATION_DURATION_MS)
|
||||
@@ -132,6 +132,6 @@ public class PackedSampleConverterCalibration extends Calibration
|
||||
count++;
|
||||
}
|
||||
|
||||
return count + (accumulator * 0);
|
||||
return count + (long)(accumulator * 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2025 Dennis Sheirer
|
||||
* Copyright (C) 2014-2026 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -220,7 +220,7 @@ public class UnpackedInterleavedSampleConverterCalibration extends Calibration
|
||||
private long calibrateScalar(short[] samples, short[] residualI, short[] residualQ)
|
||||
{
|
||||
long start = System.currentTimeMillis();
|
||||
long accumulator = 0;
|
||||
double accumulator = 0.0;
|
||||
long count = 0;
|
||||
while((System.currentTimeMillis() - start) < ITERATION_DURATION_MS)
|
||||
{
|
||||
@@ -234,13 +234,13 @@ public class UnpackedInterleavedSampleConverterCalibration extends Calibration
|
||||
}
|
||||
}
|
||||
|
||||
return count + (accumulator * 0);
|
||||
return count + (long)(accumulator * 0);
|
||||
}
|
||||
|
||||
private long calibrateVector64(short[] samples, short[] residualI, short[] residualQ)
|
||||
{
|
||||
long start = System.currentTimeMillis();
|
||||
long accumulator = 0;
|
||||
double accumulator = 0.0;
|
||||
long count = 0;
|
||||
|
||||
while((System.currentTimeMillis() - start) < ITERATION_DURATION_MS)
|
||||
@@ -255,13 +255,13 @@ public class UnpackedInterleavedSampleConverterCalibration extends Calibration
|
||||
}
|
||||
}
|
||||
|
||||
return count + (accumulator * 0);
|
||||
return count + (long)(accumulator * 0);
|
||||
}
|
||||
|
||||
private long calibrateVector128(short[] samples, short[] residualI, short[] residualQ)
|
||||
{
|
||||
long start = System.currentTimeMillis();
|
||||
long accumulator = 0;
|
||||
double accumulator = 0.0;
|
||||
long count = 0;
|
||||
|
||||
for(int x = 0; x < ITERATION_DURATION_MS; x++)
|
||||
@@ -276,13 +276,13 @@ public class UnpackedInterleavedSampleConverterCalibration extends Calibration
|
||||
}
|
||||
}
|
||||
|
||||
return count + (accumulator * 0);
|
||||
return count + (long)(accumulator * 0);
|
||||
}
|
||||
|
||||
private long calibrateVector256(short[] samples, short[] residualI, short[] residualQ)
|
||||
{
|
||||
long start = System.currentTimeMillis();
|
||||
long accumulator = 0;
|
||||
double accumulator = 0.0;
|
||||
long count = 0;
|
||||
|
||||
while((System.currentTimeMillis() - start) < ITERATION_DURATION_MS)
|
||||
@@ -297,13 +297,13 @@ public class UnpackedInterleavedSampleConverterCalibration extends Calibration
|
||||
}
|
||||
}
|
||||
|
||||
return count + (accumulator * 0);
|
||||
return count + (long)(accumulator * 0);
|
||||
}
|
||||
|
||||
private long calibrateVector512(short[] samples, short[] residualI, short[] residualQ)
|
||||
{
|
||||
long start = System.currentTimeMillis();
|
||||
long accumulator = 0;
|
||||
double accumulator = 0.0;
|
||||
long count = 0;
|
||||
|
||||
while((System.currentTimeMillis() - start) < ITERATION_DURATION_MS)
|
||||
@@ -319,6 +319,6 @@ public class UnpackedInterleavedSampleConverterCalibration extends Calibration
|
||||
}
|
||||
}
|
||||
|
||||
return count + (accumulator * 0);
|
||||
return count + (long)(accumulator * 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2025 Dennis Sheirer
|
||||
* Copyright (C) 2014-2026 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -208,7 +208,7 @@ public class UnpackedSampleConverterCalibration extends Calibration
|
||||
private long testScalar(short[] samples, short[] residualI, short[] residualQ)
|
||||
{
|
||||
long start = System.currentTimeMillis();
|
||||
long accumulator = 0;
|
||||
double accumulator = 0.0;
|
||||
long count = 0;
|
||||
|
||||
while((System.currentTimeMillis() - start) < ITERATION_DURATION_MS)
|
||||
@@ -223,13 +223,13 @@ public class UnpackedSampleConverterCalibration extends Calibration
|
||||
}
|
||||
}
|
||||
|
||||
return count + (accumulator * 0);
|
||||
return count + (long)(accumulator * 0);
|
||||
}
|
||||
|
||||
private long testVector64(short[] samples, short[] residualI, short[] residualQ)
|
||||
{
|
||||
long start = System.currentTimeMillis();
|
||||
long accumulator = 0;
|
||||
double accumulator = 0.0;
|
||||
long count = 0;
|
||||
|
||||
while((System.currentTimeMillis() - start) < ITERATION_DURATION_MS)
|
||||
@@ -244,13 +244,13 @@ public class UnpackedSampleConverterCalibration extends Calibration
|
||||
}
|
||||
}
|
||||
|
||||
return count + (accumulator * 0);
|
||||
return count + (long)(accumulator * 0);
|
||||
}
|
||||
|
||||
private long testVector128(short[] samples, short[] residualI, short[] residualQ)
|
||||
{
|
||||
long start = System.currentTimeMillis();
|
||||
long accumulator = 0;
|
||||
double accumulator = 0.0;
|
||||
long count = 0;
|
||||
while((System.currentTimeMillis() - start) < ITERATION_DURATION_MS)
|
||||
{
|
||||
@@ -264,13 +264,13 @@ public class UnpackedSampleConverterCalibration extends Calibration
|
||||
}
|
||||
}
|
||||
|
||||
return count + (accumulator * 0);
|
||||
return count + (long)(accumulator * 0);
|
||||
}
|
||||
|
||||
private long testVector256(short[] samples, short[] residualI, short[] residualQ)
|
||||
{
|
||||
long start = System.currentTimeMillis();
|
||||
long accumulator = 0;
|
||||
double accumulator = 0.0;
|
||||
long count = 0;
|
||||
|
||||
while((System.currentTimeMillis() - start) < ITERATION_DURATION_MS)
|
||||
@@ -286,13 +286,13 @@ public class UnpackedSampleConverterCalibration extends Calibration
|
||||
}
|
||||
}
|
||||
|
||||
return count + (accumulator * 0);
|
||||
return count + (long)(accumulator * 0);
|
||||
}
|
||||
|
||||
private long testVector512(short[] samples, short[] residualI, short[] residualQ)
|
||||
{
|
||||
long start = System.currentTimeMillis();
|
||||
long accumulator = 0;
|
||||
double accumulator = 0.0;
|
||||
long count = 0;
|
||||
|
||||
while((System.currentTimeMillis() - start) < ITERATION_DURATION_MS)
|
||||
@@ -308,6 +308,6 @@ public class UnpackedSampleConverterCalibration extends Calibration
|
||||
}
|
||||
}
|
||||
|
||||
return count + (accumulator * 0);
|
||||
return count + (long)(accumulator * 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2024 Dennis Sheirer
|
||||
* Copyright (C) 2014-2026 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -45,6 +45,9 @@ public class DMRSoftSyncCalibration extends Calibration
|
||||
private final DMRSoftSyncDetector mVectorDetector128 = new DMRSoftSyncDetectorVector128();
|
||||
private final DMRSoftSyncDetector mVectorDetector256 = new DMRSoftSyncDetectorVector256();
|
||||
private final DMRSoftSyncDetector mVectorDetector512 = new DMRSoftSyncDetectorVector512();
|
||||
//Accumulates the sync detection scores so that the JIT compiler can't eliminate the unused sync detector
|
||||
//calculations, which otherwise measures the loop overhead instead of the implementation.
|
||||
private float mScoreAccumulator;
|
||||
|
||||
/**
|
||||
* Constructs an instance
|
||||
@@ -193,6 +196,7 @@ public class DMRSoftSyncCalibration extends Calibration
|
||||
private long testScalar(float[] samples)
|
||||
{
|
||||
long count = 0;
|
||||
float accumulator = 0.0f;
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
@@ -200,79 +204,88 @@ public class DMRSoftSyncCalibration extends Calibration
|
||||
{
|
||||
for(float sample : samples)
|
||||
{
|
||||
mScalarDetector.process(sample);
|
||||
accumulator += mScalarDetector.process(sample);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
mScoreAccumulator += accumulator;
|
||||
return count;
|
||||
}
|
||||
|
||||
private long testVector64(float[] samples)
|
||||
{
|
||||
long count = 0;
|
||||
float accumulator = 0.0f;
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
while((System.currentTimeMillis() - start) < ITERATION_DURATION_MS)
|
||||
{
|
||||
for(float sample : samples)
|
||||
{
|
||||
mVectorDetector64.process(sample);
|
||||
accumulator += mVectorDetector64.process(sample);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
mScoreAccumulator += accumulator;
|
||||
return count;
|
||||
}
|
||||
|
||||
private long testVector128(float[] samples)
|
||||
{
|
||||
long count = 0;
|
||||
float accumulator = 0.0f;
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
while((System.currentTimeMillis() - start) < ITERATION_DURATION_MS)
|
||||
{
|
||||
for(float sample : samples)
|
||||
{
|
||||
mVectorDetector128.process(sample);
|
||||
accumulator += mVectorDetector128.process(sample);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
mScoreAccumulator += accumulator;
|
||||
return count;
|
||||
}
|
||||
|
||||
private long testVector256(float[] samples)
|
||||
{
|
||||
long count = 0;
|
||||
float accumulator = 0.0f;
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
while((System.currentTimeMillis() - start) < ITERATION_DURATION_MS)
|
||||
{
|
||||
for(float sample : samples)
|
||||
{
|
||||
mVectorDetector256.process(sample);
|
||||
accumulator += mVectorDetector256.process(sample);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
mScoreAccumulator += accumulator;
|
||||
return count;
|
||||
}
|
||||
|
||||
private long testVector512(float[] samples)
|
||||
{
|
||||
long count = 0;
|
||||
float accumulator = 0.0f;
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
while((System.currentTimeMillis() - start) < ITERATION_DURATION_MS)
|
||||
{
|
||||
for(float sample : samples)
|
||||
{
|
||||
mVectorDetector512.process(sample);
|
||||
accumulator += mVectorDetector512.process(sample);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
mScoreAccumulator += accumulator;
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,9 @@ public class NXDNSoftSyncCalibration extends Calibration
|
||||
private final NXDNSoftSyncDetector mVectorDetector128 = new NXDNSoftSyncDetectorVector128();
|
||||
private final NXDNSoftSyncDetector mVectorDetector256 = new NXDNSoftSyncDetectorVector256();
|
||||
private final NXDNSoftSyncDetector mVectorDetector512 = new NXDNSoftSyncDetectorVector512();
|
||||
//Accumulates the sync detection scores so that the JIT compiler can't eliminate the unused sync detector
|
||||
//calculations, which otherwise measures the loop overhead instead of the implementation.
|
||||
private float mScoreAccumulator;
|
||||
|
||||
/**
|
||||
* Constructs an instance
|
||||
@@ -193,6 +196,7 @@ public class NXDNSoftSyncCalibration extends Calibration
|
||||
private long testScalar(float[] samples)
|
||||
{
|
||||
long count = 0;
|
||||
float accumulator = 0.0f;
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
@@ -200,79 +204,88 @@ public class NXDNSoftSyncCalibration extends Calibration
|
||||
{
|
||||
for(float sample : samples)
|
||||
{
|
||||
mScalarDetector.process(sample);
|
||||
accumulator += mScalarDetector.process(sample);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
mScoreAccumulator += accumulator;
|
||||
return count;
|
||||
}
|
||||
|
||||
private long testVector64(float[] samples)
|
||||
{
|
||||
long count = 0;
|
||||
float accumulator = 0.0f;
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
while((System.currentTimeMillis() - start) < ITERATION_DURATION_MS)
|
||||
{
|
||||
for(float sample : samples)
|
||||
{
|
||||
mVectorDetector64.process(sample);
|
||||
accumulator += mVectorDetector64.process(sample);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
mScoreAccumulator += accumulator;
|
||||
return count;
|
||||
}
|
||||
|
||||
private long testVector128(float[] samples)
|
||||
{
|
||||
long count = 0;
|
||||
float accumulator = 0.0f;
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
while((System.currentTimeMillis() - start) < ITERATION_DURATION_MS)
|
||||
{
|
||||
for(float sample : samples)
|
||||
{
|
||||
mVectorDetector128.process(sample);
|
||||
accumulator += mVectorDetector128.process(sample);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
mScoreAccumulator += accumulator;
|
||||
return count;
|
||||
}
|
||||
|
||||
private long testVector256(float[] samples)
|
||||
{
|
||||
long count = 0;
|
||||
float accumulator = 0.0f;
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
while((System.currentTimeMillis() - start) < ITERATION_DURATION_MS)
|
||||
{
|
||||
for(float sample : samples)
|
||||
{
|
||||
mVectorDetector256.process(sample);
|
||||
accumulator += mVectorDetector256.process(sample);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
mScoreAccumulator += accumulator;
|
||||
return count;
|
||||
}
|
||||
|
||||
private long testVector512(float[] samples)
|
||||
{
|
||||
long count = 0;
|
||||
float accumulator = 0.0f;
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
while((System.currentTimeMillis() - start) < ITERATION_DURATION_MS)
|
||||
{
|
||||
for(float sample : samples)
|
||||
{
|
||||
mVectorDetector512.process(sample);
|
||||
accumulator += mVectorDetector512.process(sample);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
mScoreAccumulator += accumulator;
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2024 Dennis Sheirer
|
||||
* Copyright (C) 2014-2026 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -45,6 +45,9 @@ public class P25P1SoftSyncCalibration extends Calibration
|
||||
private final P25P1SoftSyncDetector mVectorDetector128 = new P25P1SoftSyncDetectorVector128();
|
||||
private final P25P1SoftSyncDetector mVectorDetector256 = new P25P1SoftSyncDetectorVector256();
|
||||
private final P25P1SoftSyncDetector mVectorDetector512 = new P25P1SoftSyncDetectorVector512();
|
||||
//Accumulates the sync detection scores so that the JIT compiler can't eliminate the unused sync detector
|
||||
//calculations, which otherwise measures the loop overhead instead of the implementation.
|
||||
private float mScoreAccumulator;
|
||||
|
||||
/**
|
||||
* Constructs an instance
|
||||
@@ -193,6 +196,7 @@ public class P25P1SoftSyncCalibration extends Calibration
|
||||
private long testScalar(float[] samples)
|
||||
{
|
||||
long count = 0;
|
||||
float accumulator = 0.0f;
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
@@ -200,79 +204,88 @@ public class P25P1SoftSyncCalibration extends Calibration
|
||||
{
|
||||
for(float sample : samples)
|
||||
{
|
||||
mScalarDetector.process(sample);
|
||||
accumulator += mScalarDetector.process(sample);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
mScoreAccumulator += accumulator;
|
||||
return count;
|
||||
}
|
||||
|
||||
private long testVector64(float[] samples)
|
||||
{
|
||||
long count = 0;
|
||||
float accumulator = 0.0f;
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
while((System.currentTimeMillis() - start) < ITERATION_DURATION_MS)
|
||||
{
|
||||
for(float sample : samples)
|
||||
{
|
||||
mVectorDetector64.process(sample);
|
||||
accumulator += mVectorDetector64.process(sample);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
mScoreAccumulator += accumulator;
|
||||
return count;
|
||||
}
|
||||
|
||||
private long testVector128(float[] samples)
|
||||
{
|
||||
long count = 0;
|
||||
float accumulator = 0.0f;
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
while((System.currentTimeMillis() - start) < ITERATION_DURATION_MS)
|
||||
{
|
||||
for(float sample : samples)
|
||||
{
|
||||
mVectorDetector128.process(sample);
|
||||
accumulator += mVectorDetector128.process(sample);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
mScoreAccumulator += accumulator;
|
||||
return count;
|
||||
}
|
||||
|
||||
private long testVector256(float[] samples)
|
||||
{
|
||||
long count = 0;
|
||||
float accumulator = 0.0f;
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
while((System.currentTimeMillis() - start) < ITERATION_DURATION_MS)
|
||||
{
|
||||
for(float sample : samples)
|
||||
{
|
||||
mVectorDetector256.process(sample);
|
||||
accumulator += mVectorDetector256.process(sample);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
mScoreAccumulator += accumulator;
|
||||
return count;
|
||||
}
|
||||
|
||||
private long testVector512(float[] samples)
|
||||
{
|
||||
long count = 0;
|
||||
float accumulator = 0.0f;
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
while((System.currentTimeMillis() - start) < ITERATION_DURATION_MS)
|
||||
{
|
||||
for(float sample : samples)
|
||||
{
|
||||
mVectorDetector512.process(sample);
|
||||
accumulator += mVectorDetector512.process(sample);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
mScoreAccumulator += accumulator;
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,305 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2026 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.vector.calibrate.sync;
|
||||
|
||||
import io.github.dsheirer.module.decode.p25.phase2.sync.P25P2SoftSyncDetector;
|
||||
import io.github.dsheirer.module.decode.p25.phase2.sync.P25P2SoftSyncDetectorScalar;
|
||||
import io.github.dsheirer.module.decode.p25.phase2.sync.P25P2SoftSyncDetectorVector128;
|
||||
import io.github.dsheirer.module.decode.p25.phase2.sync.P25P2SoftSyncDetectorVector256;
|
||||
import io.github.dsheirer.module.decode.p25.phase2.sync.P25P2SoftSyncDetectorVector512;
|
||||
import io.github.dsheirer.module.decode.p25.phase2.sync.P25P2SoftSyncDetectorVector64;
|
||||
import io.github.dsheirer.vector.calibrate.Calibration;
|
||||
import io.github.dsheirer.vector.calibrate.CalibrationException;
|
||||
import io.github.dsheirer.vector.calibrate.CalibrationType;
|
||||
import io.github.dsheirer.vector.calibrate.Implementation;
|
||||
import org.apache.commons.math3.stat.descriptive.moment.Mean;
|
||||
|
||||
/**
|
||||
* P25 Phase 2 Soft Sync Detector calibration
|
||||
*/
|
||||
public class P25P2SoftSyncCalibration extends Calibration
|
||||
{
|
||||
private static final int BUFFER_SIZE = 2048;
|
||||
private static final int ITERATION_DURATION_MS = 1000;
|
||||
private static final int WARMUP_ITERATIONS = 5;
|
||||
private static final int TEST_ITERATIONS = 5;
|
||||
private final P25P2SoftSyncDetector mScalarDetector = new P25P2SoftSyncDetectorScalar();
|
||||
private final P25P2SoftSyncDetector mVectorDetector64 = new P25P2SoftSyncDetectorVector64();
|
||||
private final P25P2SoftSyncDetector mVectorDetector128 = new P25P2SoftSyncDetectorVector128();
|
||||
private final P25P2SoftSyncDetector mVectorDetector256 = new P25P2SoftSyncDetectorVector256();
|
||||
private final P25P2SoftSyncDetector mVectorDetector512 = new P25P2SoftSyncDetectorVector512();
|
||||
//Accumulates the sync detection scores so that the JIT compiler can't eliminate the unused sync detector
|
||||
//calculations, which otherwise measures the loop overhead instead of the implementation.
|
||||
private float mScoreAccumulator;
|
||||
|
||||
/**
|
||||
* Constructs an instance
|
||||
*/
|
||||
public P25P2SoftSyncCalibration()
|
||||
{
|
||||
super(CalibrationType.P25P2_SOFT_SYNC_DETECTOR);
|
||||
}
|
||||
|
||||
@Override public void calibrate() throws CalibrationException
|
||||
{
|
||||
float[] samples = getFloatSamples(BUFFER_SIZE);
|
||||
|
||||
Mean scalarMean = new Mean();
|
||||
|
||||
for(int x = 0; x < WARMUP_ITERATIONS; x++)
|
||||
{
|
||||
long score = testScalar(samples);
|
||||
scalarMean.increment(score);
|
||||
}
|
||||
|
||||
mLog.info("P25P2 SOFT SYNC DETECTOR WARMUP - SCALAR: " + DECIMAL_FORMAT.format(scalarMean.getResult()));
|
||||
|
||||
Mean vectorMean64 = new Mean();
|
||||
|
||||
for(int x = 0; x < WARMUP_ITERATIONS; x++)
|
||||
{
|
||||
long score = testVector64(samples);
|
||||
vectorMean64.increment(score);
|
||||
}
|
||||
|
||||
mLog.info("P25P2 SOFT SYNC DETECTOR WARMUP - VECTOR 64: " + DECIMAL_FORMAT.format(vectorMean64.getResult()));
|
||||
|
||||
Mean vectorMean128 = new Mean();
|
||||
|
||||
for(int x = 0; x < WARMUP_ITERATIONS; x++)
|
||||
{
|
||||
long score = testVector128(samples);
|
||||
vectorMean128.increment(score);
|
||||
}
|
||||
|
||||
mLog.info("P25P2 SOFT SYNC DETECTOR WARMUP - VECTOR 128: " + DECIMAL_FORMAT.format(vectorMean128.getResult()));
|
||||
|
||||
Mean vectorMean256 = new Mean();
|
||||
|
||||
for(int x = 0; x < WARMUP_ITERATIONS; x++)
|
||||
{
|
||||
long score = testVector256(samples);
|
||||
vectorMean256.increment(score);
|
||||
}
|
||||
|
||||
mLog.info("P25P2 SOFT SYNC DETECTOR WARMUP - VECTOR 256: " + DECIMAL_FORMAT.format(vectorMean256.getResult()));
|
||||
|
||||
Mean vectorMean512 = new Mean();
|
||||
|
||||
for(int x = 0; x < WARMUP_ITERATIONS; x++)
|
||||
{
|
||||
long score = testVector512(samples);
|
||||
vectorMean512.increment(score);
|
||||
}
|
||||
|
||||
mLog.info("P25P2 SOFT SYNC DETECTOR WARMUP - VECTOR 512: " + DECIMAL_FORMAT.format(vectorMean512.getResult()));
|
||||
|
||||
//Start tests
|
||||
scalarMean.clear();
|
||||
|
||||
for(int x = 0; x < TEST_ITERATIONS; x++)
|
||||
{
|
||||
long score = testScalar(samples);
|
||||
scalarMean.increment(score);
|
||||
}
|
||||
|
||||
mLog.info("P25P2 SOFT SYNC DETECTOR - SCALAR: " + DECIMAL_FORMAT.format(scalarMean.getResult()));
|
||||
|
||||
vectorMean64.clear();
|
||||
|
||||
for(int x = 0; x < TEST_ITERATIONS; x++)
|
||||
{
|
||||
long score = testVector64(samples);
|
||||
vectorMean64.increment(score);
|
||||
}
|
||||
|
||||
mLog.info("P25P2 SOFT SYNC DETECTOR - VECTOR 64: " + DECIMAL_FORMAT.format(vectorMean64.getResult()));
|
||||
|
||||
vectorMean128.clear();
|
||||
|
||||
for(int x = 0; x < TEST_ITERATIONS; x++)
|
||||
{
|
||||
long score = testVector128(samples);
|
||||
vectorMean128.increment(score);
|
||||
}
|
||||
|
||||
mLog.info("P25P2 SOFT SYNC DETECTOR - VECTOR 128: " + DECIMAL_FORMAT.format(vectorMean128.getResult()));
|
||||
|
||||
vectorMean256.clear();
|
||||
|
||||
for(int x = 0; x < TEST_ITERATIONS; x++)
|
||||
{
|
||||
long score = testVector256(samples);
|
||||
vectorMean256.increment(score);
|
||||
}
|
||||
|
||||
mLog.info("P25P2 SOFT SYNC DETECTOR - VECTOR 256: " + DECIMAL_FORMAT.format(vectorMean256.getResult()));
|
||||
|
||||
vectorMean512.clear();
|
||||
|
||||
for(int x = 0; x < TEST_ITERATIONS; x++)
|
||||
{
|
||||
long score = testVector512(samples);
|
||||
vectorMean512.increment(score);
|
||||
}
|
||||
|
||||
mLog.info("P25P2 SOFT SYNC DETECTOR - VECTOR 512: " + DECIMAL_FORMAT.format(vectorMean512.getResult()));
|
||||
|
||||
Implementation best = Implementation.SCALAR;
|
||||
double bestScore = scalarMean.getResult();
|
||||
|
||||
if(vectorMean64.getResult() > bestScore)
|
||||
{
|
||||
bestScore = vectorMean64.getResult();
|
||||
best = Implementation.VECTOR_SIMD_64;
|
||||
}
|
||||
|
||||
if(vectorMean128.getResult() > bestScore)
|
||||
{
|
||||
bestScore = vectorMean128.getResult();
|
||||
best = Implementation.VECTOR_SIMD_128;
|
||||
}
|
||||
|
||||
if(vectorMean256.getResult() > bestScore)
|
||||
{
|
||||
bestScore = vectorMean256.getResult();
|
||||
best = Implementation.VECTOR_SIMD_256;
|
||||
}
|
||||
|
||||
if(vectorMean512.getResult() > bestScore)
|
||||
{
|
||||
best = Implementation.VECTOR_SIMD_512;
|
||||
}
|
||||
|
||||
setImplementation(best);
|
||||
|
||||
mLog.info("P25P2 SOFT SYNC DETECTOR - SET OPTIMAL IMPLEMENTATION TO:" + getImplementation());
|
||||
}
|
||||
|
||||
private long testScalar(float[] samples)
|
||||
{
|
||||
long count = 0;
|
||||
float accumulator = 0.0f;
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
while((System.currentTimeMillis() - start) < ITERATION_DURATION_MS)
|
||||
{
|
||||
for(float sample : samples)
|
||||
{
|
||||
accumulator += mScalarDetector.process(sample);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
mScoreAccumulator += accumulator;
|
||||
return count;
|
||||
}
|
||||
|
||||
private long testVector64(float[] samples)
|
||||
{
|
||||
long count = 0;
|
||||
float accumulator = 0.0f;
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
while((System.currentTimeMillis() - start) < ITERATION_DURATION_MS)
|
||||
{
|
||||
for(float sample : samples)
|
||||
{
|
||||
accumulator += mVectorDetector64.process(sample);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
mScoreAccumulator += accumulator;
|
||||
return count;
|
||||
}
|
||||
|
||||
private long testVector128(float[] samples)
|
||||
{
|
||||
long count = 0;
|
||||
float accumulator = 0.0f;
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
while((System.currentTimeMillis() - start) < ITERATION_DURATION_MS)
|
||||
{
|
||||
for(float sample : samples)
|
||||
{
|
||||
accumulator += mVectorDetector128.process(sample);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
mScoreAccumulator += accumulator;
|
||||
return count;
|
||||
}
|
||||
|
||||
private long testVector256(float[] samples)
|
||||
{
|
||||
long count = 0;
|
||||
float accumulator = 0.0f;
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
while((System.currentTimeMillis() - start) < ITERATION_DURATION_MS)
|
||||
{
|
||||
for(float sample : samples)
|
||||
{
|
||||
accumulator += mVectorDetector256.process(sample);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
mScoreAccumulator += accumulator;
|
||||
return count;
|
||||
}
|
||||
|
||||
private long testVector512(float[] samples)
|
||||
{
|
||||
long count = 0;
|
||||
float accumulator = 0.0f;
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
while((System.currentTimeMillis() - start) < ITERATION_DURATION_MS)
|
||||
{
|
||||
for(float sample : samples)
|
||||
{
|
||||
accumulator += mVectorDetector512.process(sample);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
mScoreAccumulator += accumulator;
|
||||
return count;
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
P25P2SoftSyncCalibration calibration = new P25P2SoftSyncCalibration();
|
||||
|
||||
try
|
||||
{
|
||||
calibration.calibrate();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
mLog.error("Error during calibration", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user