P25 - updated automatic and direct frequency control to cleanup the code and allow P25 to better track frequency and PPM changes in the tuner and provide a cleaner implementation of the AFC component in the processing chain of all of the other decoders.

Changed C4FM symbol filter to reset frequency tracking values when the tuner's frequency or PPM values change.

Moved all frequency control pieces into the source.tuner.frequency package.
This commit is contained in:
dennis.sheirer
2015-05-04 00:55:04 +00:00
parent d2020cdba0
commit bc5080aa4a
44 changed files with 533 additions and 337 deletions

View File

@@ -81,6 +81,12 @@ public class ComplexSample implements Serializable
mRight *= scalor;
}
public static ComplexSample multiply( ComplexSample sample, float scalor )
{
return new ComplexSample( sample.left() * scalor,
sample.right() * scalor );
}
/**
* Multiplies this sample by the multiplier sample
*/
@@ -159,9 +165,17 @@ public class ComplexSample implements Serializable
* Magnitude squared of this sample
*/
public float magnitudeSquared()
{
return norm();
}
/**
* Norm of this sample = ( i * i ) + ( q * q )
*/
public float norm()
{
return (float)( ( inphase() * inphase() ) +
( quadrature() * quadrature() ) );
( quadrature() * quadrature() ) );
}
/**
@@ -293,6 +307,32 @@ public class ComplexSample implements Serializable
return (float)Math.atan2( y(), x() );
}
/**
* Constrains the i and q quantities to +/- value.
*
* @param value - maximum absolute value
*/
public void clip( float value )
{
if( mLeft > value )
{
mLeft = value;
}
else if( mLeft < -value )
{
mLeft = -value;
}
if( mRight > value )
{
mRight = value;
}
else if( mRight < -value )
{
mRight = -value;
}
}
/**
* Angle of this sample in degrees
*/
@@ -321,18 +361,17 @@ public class ComplexSample implements Serializable
public static void main( String[] args )
{
double SYMBOL_FREQUENCY = 2.0d * Math.PI * 4800.0d / 48000.0d;
double PHASE_CORRECTION_90_DEGREES = SYMBOL_FREQUENCY / 4.0d;
double PHASE_CORRECTION_180_DEGREES = SYMBOL_FREQUENCY / 2.0d;
double angle = Math.PI / 4;
ComplexSample s1 = new ComplexSample( (float)Math.sin( angle ), (float)Math.cos( angle ) );
ComplexSample s2 = new ComplexSample( (float)Math.sin( -angle ), (float)Math.cos( -angle ) );
double angle = Math.PI; //180 degrees
ComplexSample symbol = ComplexSample.multiply( s1, s2.conjugate() );
ComplexSample s1 = new ComplexSample( (float)Math.sin( angle ), (float)Math.cos( angle ) );
mLog.debug( "S1:" + s1.polarAngle() + " S2:" + s2.polarAngle() + " Symbol:" + symbol.polarAngle() );
ComplexSample tap = new ComplexSample( 1.0f, -0.1f );
ComplexSample convolved = ComplexSample.multiply( s1, tap );
mLog.debug( "s: " + s1.toString() +
" t: " + tap.toString() +
" convolved: " + convolved.toString() );
}
}