mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 08:37:25 -05:00
* Uses same shared architecture and symbol processor pattern as other C4FM decoders. * Adds soft symbol processing and sync detection. * Removes RRC filter and replaces with improved channel filter. * Viterbi soft symbol decoding with demodulator reliability weighting * Improved sync reacquisition in low SNR * Improved handling for phase wrapping and interpolation * NAC Tracker updated to track by NAC count * Native buffers returning partial buffers * Message processor uses only valid LDU1 words * Reduced phantom TDU messages * Tuner/Channe frequency error corrections don't reset the symbol trackers and fix possible divide by zero error * LSM timing error detector now updates per symbol block size instead of sample buffer size - faster convergence * New unit tests * Resolves several issues, including a lagging sync detect offset issue in the recently updated P25P1 C4FM decoder. * Consolidate filter designers for each protocol back into the FilterFactory class. * DMR, P25 Phase 1 C4FM and LSM, and P25 Phase 2 decoders design the baseband filter once and share the taps across the I and Q filters. Co-authored-by: denny <dennis.sheirer@gmail.com>
69 lines
2.7 KiB
Java
69 lines
2.7 KiB
Java
package io.github.dsheirer.dsp.c4fm;
|
|
|
|
import io.github.dsheirer.dsp.symbol.Dibit;
|
|
|
|
/**
|
|
* C4FM message framer base class.
|
|
*/
|
|
public abstract class C4FMMessageFramer
|
|
{
|
|
private static final float SOFT_SYMBOL_SCALE = (float)(4.0 / Math.PI); //Radians to symbol units (+/-1, +/-3)
|
|
|
|
/**
|
|
* Converts the soft symbol into a pair of soft bit values using max-log likelihood ratios for the Gray mapped
|
|
* 4-level symbol (D01=+3, D00=+1, D10=-1, D11=-3), where a positive soft bit value favors a 1 bit.
|
|
* @param softSymbol in radians
|
|
* @param softBits array to receive the two soft bit values
|
|
* @param index for the first bit (sign bit), followed by the second (magnitude) bit
|
|
*/
|
|
protected static void setSoftBits(float softSymbol, float[] softBits, int index)
|
|
{
|
|
float u = softSymbol * SOFT_SYMBOL_SCALE;
|
|
float magnitude = Math.abs(u);
|
|
//First bit is 1 for negative symbols
|
|
float favorZero = magnitude <= 2.0f ? 4.0f * u : 8.0f * u - 8.0f * Math.signum(u);
|
|
softBits[index] = -favorZero;
|
|
//Second bit is 1 for the outer (+/-3) symbols
|
|
softBits[index + 1] = 4.0f * (magnitude - 2.0f);
|
|
}
|
|
|
|
/**
|
|
* Process the symbol
|
|
* @param symbol in radians
|
|
* @return true if the framer emits a valid message that includes this symbol, so that corrective measurement
|
|
* can be sent to a feedback decoder.
|
|
*/
|
|
public abstract boolean process(Dibit symbol);
|
|
|
|
/**
|
|
* Process the symbol decision along with the soft symbol it was decided from. Framers that can use soft symbols
|
|
* (ie soft decision decoding) override this method. Default implementation discards the soft symbol.
|
|
* @param symbol decision
|
|
* @param softSymbol equalized soft symbol in radians
|
|
* @return true if the framer emits a valid message that includes this symbol.
|
|
*/
|
|
public boolean process(Dibit symbol, float softSymbol)
|
|
{
|
|
return process(symbol);
|
|
}
|
|
|
|
/**
|
|
* Process the symbol decision along with the soft symbol it was decided from and the soft symbol reliability (ie
|
|
* inverse of the soft symbol noise variance). Framers that can weight soft decision decoding override this method.
|
|
* Default implementation discards the reliability.
|
|
* @param symbol decision
|
|
* @param softSymbol equalized soft symbol in radians
|
|
* @param reliability of the soft symbol
|
|
* @return true if the framer emits a valid message that includes this symbol.
|
|
*/
|
|
public boolean process(Dibit symbol, float softSymbol, float reliability)
|
|
{
|
|
return process(symbol, softSymbol);
|
|
}
|
|
|
|
/**
|
|
* A sync pattern is detected
|
|
*/
|
|
public abstract void syncDetected();
|
|
}
|