#2524 P25P2 Decoder enhancements (#2525)

* 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:
Denny Sheirer
2026-10-29 07:32:17 -04:00
committed by GitHub
parent 6b9cd2d317
commit 9a6dc2b0a0
52 changed files with 4026 additions and 1314 deletions

View File

@@ -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());

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -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);
}
}
}