P25 work in progress

This commit is contained in:
dennis.sheirer
2014-11-22 16:13:44 +00:00
parent 960de375bc
commit 1660f13633
44 changed files with 788 additions and 656 deletions

View File

@@ -15,7 +15,7 @@ public class C4FMSlicer implements RealSampleListener
{
private static final float THRESHOLD = 2.0f;
private Broadcaster<C4FMSymbol> mBroadcaster = new Broadcaster<C4FMSymbol>();
private Broadcaster<Dibit> mBroadcaster = new Broadcaster<Dibit>();
/**
* Primary method for receiving output from the C4FMSymbolFilter. Slices
@@ -26,26 +26,26 @@ public class C4FMSlicer implements RealSampleListener
{
if( sample > THRESHOLD )
{
dispatch( C4FMSymbol.SYMBOL_PLUS_3 );
dispatch( Dibit.D01_PLUS_3 );
}
else if( sample > 0 )
{
dispatch( C4FMSymbol.SYMBOL_PLUS_1 );
dispatch( Dibit.D00_PLUS_1 );
}
else if( sample > -THRESHOLD )
{
dispatch( C4FMSymbol.SYMBOL_MINUS_1 );
dispatch( Dibit.D10_MINUS_1 );
}
else
{
dispatch( C4FMSymbol.SYMBOL_MINUS_3 );
dispatch( Dibit.D11_MINUS_3 );
}
}
/**
* Dispatches the symbol decision to any registered listeners
*/
private void dispatch( C4FMSymbol symbol )
private void dispatch( Dibit symbol )
{
mBroadcaster.receive( symbol );
}
@@ -54,7 +54,7 @@ public class C4FMSlicer implements RealSampleListener
* Registers the listener to receive the normal (non-inverted) C4FM symbol
* stream.
*/
public void addListener( Listener<C4FMSymbol> listener )
public void addListener( Listener<Dibit> listener )
{
mBroadcaster.addListener( listener );
}
@@ -62,7 +62,7 @@ public class C4FMSlicer implements RealSampleListener
/**
* Removes the listener
*/
public void removeListener( Listener<C4FMSymbol> listener )
public void removeListener( Listener<Dibit> listener )
{
mBroadcaster.removeListener( listener );
}

View File

@@ -1,44 +0,0 @@
package dsp.fsk;
public enum C4FMSymbol
{
SYMBOL_PLUS_3( false, true ),
SYMBOL_PLUS_1( false, false ),
SYMBOL_MINUS_1( true, false ),
SYMBOL_MINUS_3( true, true );
private boolean mBit1;
private boolean mBit2;
private C4FMSymbol( boolean bit1, boolean bit2 )
{
mBit1 = bit1;
mBit2 = bit2;
}
public boolean getBit1()
{
return mBit1;
}
public boolean getBit2()
{
return mBit2;
}
public static C4FMSymbol inverted( C4FMSymbol symbol )
{
switch( symbol )
{
case SYMBOL_MINUS_1:
return SYMBOL_MINUS_3;
case SYMBOL_MINUS_3:
return SYMBOL_PLUS_3;
case SYMBOL_PLUS_1:
return SYMBOL_MINUS_1;
case SYMBOL_PLUS_3:
default:
return SYMBOL_PLUS_1;
}
}
}

58
src/dsp/fsk/Dibit.java Normal file
View File

@@ -0,0 +1,58 @@
package dsp.fsk;
public enum Dibit
{
D01_PLUS_3( false, true, 1, 4 ),
D00_PLUS_1( false, false, 0, 0 ),
D10_MINUS_1( true, false, 2, 8 ),
D11_MINUS_3( true, true, 3, 12 );
private boolean mBit1;
private boolean mBit2;
private int mLowValue;
private int mHighValue;
private Dibit( boolean bit1, boolean bit2, int lowValue, int highValue )
{
mBit1 = bit1;
mBit2 = bit2;
mLowValue = lowValue;
mHighValue = highValue;
}
public boolean getBit1()
{
return mBit1;
}
public boolean getBit2()
{
return mBit2;
}
public int getLowValue()
{
return mLowValue;
}
public int getHighValue()
{
return mHighValue;
}
public static Dibit inverted( Dibit symbol )
{
switch( symbol )
{
case D10_MINUS_1:
return D11_MINUS_3;
case D11_MINUS_3:
return D01_PLUS_3;
case D00_PLUS_1:
return D10_MINUS_1;
case D01_PLUS_3:
default:
return D00_PLUS_1;
}
}
}

View File

@@ -20,20 +20,17 @@ import decode.p25.message.tsbk.TSBKMessage;
import decode.p25.message.tsbk.TSBKMessageFactory;
import decode.p25.reference.DataUnitID;
public class P25MessageFramer implements Listener<C4FMSymbol>
public class P25MessageFramer implements Listener<Dibit>
{
private final static Logger mLog =
LoggerFactory.getLogger( P25MessageFramer.class );
private static final int[] STATUS_BITS =
new int[] { 22,92,162,232,302,372,442,512,582,652,722,792,862,932 };
private ArrayList<P25MessageAssembler> mAssemblers =
new ArrayList<P25MessageAssembler>();
public static final int TSBK_BEGIN = 64;
public static final int TSBK_END = 260;
public static final int TSBK_DECODED_END = 162;
public static final int TSBK_DECODED_END = 160;
private Listener<Message> mListener;
private AliasList mAliasList;
@@ -82,18 +79,16 @@ public class P25MessageFramer implements Listener<C4FMSymbol>
}
@Override
public void receive( C4FMSymbol symbol )
public void receive( Dibit symbol )
{
C4FMSymbol correctedSymbol = symbol;
mMatcher.receive( correctedSymbol.getBit1() );
mMatcher.receive( correctedSymbol.getBit2() );
mMatcher.receive( symbol.getBit1() );
mMatcher.receive( symbol.getBit2() );
for( P25MessageAssembler assembler: mAssemblers )
{
if( assembler.isActive() )
{
assembler.receive( correctedSymbol );
assembler.receive( symbol );
if( assembler.complete() )
{
@@ -120,7 +115,7 @@ public class P25MessageFramer implements Listener<C4FMSymbol>
if( !found )
{
mLog.debug( "no inactive C4FM message assemblers available" );
mLog.debug( "no inactive P25 message assemblers available" );
}
}
}
@@ -137,7 +132,9 @@ public class P25MessageFramer implements Listener<C4FMSymbol>
private class P25MessageAssembler
{
private int mStatusIndicatorPointer = 0;
/* Starting position of the status symbol counter is 24 symbols to
* account for the 48-bit sync pattern */
private int mStatusSymbolPointer = 24;
private BitSetBuffer mMessage;
private int mMessageLength;
private boolean mComplete = false;
@@ -151,21 +148,22 @@ public class P25MessageFramer implements Listener<C4FMSymbol>
reset();
}
public void receive( C4FMSymbol symbol )
public void receive( Dibit dibit )
{
if( mActive )
{
/* Throw away status bits that are injected every 70 bits */
if( mMessage.pointer() == STATUS_BITS[ mStatusIndicatorPointer ] )
if( mStatusSymbolPointer == 35 )
{
mStatusIndicatorPointer++;
mStatusSymbolPointer = 0;
}
else
{
mStatusSymbolPointer++;
try
{
mMessage.add( symbol.getBit1() );
mMessage.add( symbol.getBit2() );
mMessage.add( dibit.getBit1() );
mMessage.add( dibit.getBit2() );
}
catch( BitSetFullException e )
{
@@ -186,7 +184,7 @@ public class P25MessageFramer implements Listener<C4FMSymbol>
mDUID = DataUnitID.NID;
mMessage.setSize( mDUID.getMessageLength() );
mMessage.clear();
mStatusIndicatorPointer = 0;
mStatusSymbolPointer = 24;
mComplete = false;
mActive = false;
}
@@ -268,13 +266,20 @@ public class P25MessageFramer implements Listener<C4FMSymbol>
dispatch( new P25Message( mMessage.copy(), mDUID, mAliasList ) );
break;
case TSBK1:
// mLog.debug( "NEW: " + mMessage.toString() );
/* Remove interleaving */
P25Interleave.deinterleave( mMessage, TSBK_BEGIN, TSBK_END );
// mLog.debug( "DEI: " + mMessage.toString() );
/* Remove trellis encoding */
mHalfRate.decode( mMessage, TSBK_BEGIN, TSBK_END );
// mLog.debug( "DEC: " + mMessage.toString() );
BitSetBuffer tsbkBuffer1 = mMessage.copy();
tsbkBuffer1.setSize( TSBK_DECODED_END );
TSBKMessage tsbkMessage1 = TSBKMessageFactory.getMessage(
tsbkBuffer1, DataUnitID.TSBK1, mAliasList );
@@ -299,6 +304,7 @@ public class P25MessageFramer implements Listener<C4FMSymbol>
mHalfRate.decode( mMessage, TSBK_BEGIN, TSBK_END );
BitSetBuffer tsbkBuffer2 = mMessage.copy();
tsbkBuffer2.setSize( TSBK_DECODED_END );
TSBKMessage tsbkMessage2 = TSBKMessageFactory.getMessage(
tsbkBuffer2, DataUnitID.TSBK2, mAliasList );
@@ -324,6 +330,7 @@ public class P25MessageFramer implements Listener<C4FMSymbol>
mHalfRate.decode( mMessage, TSBK_BEGIN, TSBK_END );
BitSetBuffer tsbkBuffer3 = mMessage.copy();
tsbkBuffer3.setSize( TSBK_DECODED_END );
TSBKMessage tsbkMessage3 = TSBKMessageFactory.getMessage(
tsbkBuffer3, DataUnitID.TSBK3, mAliasList );