Interim checkin for call recording.

This commit is contained in:
denny
2015-09-11 14:01:47 -04:00
parent 0f85b7260a
commit 575197bd98
93 changed files with 2349 additions and 2637 deletions

View File

@@ -11,14 +11,17 @@ import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sample.Listener;
import sample.real.RealBuffer;
import sample.real.RealSampleListener;
import sample.real.RealSampleProvider;
import source.tuner.frequency.FrequencyCorrectionControl;
import source.tuner.frequency.FrequencyCorrectionControl.FrequencyCorrectionResetListener;
import dsp.gain.DirectGainControl;
import dsp.gain.GainController;
public class C4FMSymbolFilter implements FrequencyCorrectionResetListener,
RealSampleListener,
Listener<RealBuffer>,
RealSampleProvider,
Instrumentable
{
@@ -202,8 +205,11 @@ public class C4FMSymbolFilter implements FrequencyCorrectionResetListener,
private RealSampleListener mListener;
private GainController mGainController;
private DirectGainControl mGainController =
new DirectGainControl( 15.0f, 0.1f, 35.0f, 0.3f );
private FrequencyCorrectionControl mFrequencyCorrectionControl;
private int mFrequencyAdjustmentRequested = 0;
/**
* C4FM Symbol Filter
@@ -218,11 +224,8 @@ public class C4FMSymbolFilter implements FrequencyCorrectionResetListener,
* setting for this filter is 15.4 and that yields a symbol spread that
* is centered on 2.0, ranging 1.92 to 2.08.
*/
public C4FMSymbolFilter( GainController gainController,
FrequencyCorrectionControl frequencyControl )
public C4FMSymbolFilter( FrequencyCorrectionControl frequencyControl )
{
mGainController = gainController;
mFrequencyCorrectionControl = frequencyControl;
/* Register for reset events, so we can reset internal frequency tracking */
@@ -237,9 +240,36 @@ public class C4FMSymbolFilter implements FrequencyCorrectionResetListener,
}
@Override
public void receive( RealBuffer buffer )
{
for( float sample: buffer.getSamples() )
{
receive( sample );
}
/* If a frequency correction was requested during the processing of this
* buffer, we'll apply the change and it will be reflected in the next
* arriving buffer. Reset the lock on frequency correction and reset
* the internal frequency correction tracker */
if( mFrequencyAdjustmentRequested != 0 )
{
mFrequencyCorrectionControl.adjust( mFrequencyAdjustmentRequested );
mLog.debug( "Adjusting frequency [" + mFrequencyAdjustmentRequested +
"] correction is now: " + mFrequencyCorrectionControl
.getErrorCorrection() );
mFrequencyAdjustmentRequested = 0;
/* reset internal frequency error tracker */
mCoarseFrequencyCorrection = 0;
}
}
public void receive( float sample )
{
//TODO: limit frequency corrections to once per buffer !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!11
sample = mGainController.correct( sample );
if( mReset )
{
mGainController.reset();
@@ -353,15 +383,11 @@ public class C4FMSymbolFilter implements FrequencyCorrectionResetListener,
mFineFrequencyCorrection += ( symbolError * K_FINE_FREQUENCY );
/* send frequency correction */
/* Queue a frequency adjustment (once per buffer) as needed */
if( Math.abs( mCoarseFrequencyCorrection ) > COARSE_FREQUENCY_DEADBAND )
{
int adjustment = 500 * ( mCoarseFrequencyCorrection > 0 ? 1 : -1 );
mFrequencyCorrectionControl.adjust( adjustment );
/* reset internal frequency error tracker */
mCoarseFrequencyCorrection = 0;
mFrequencyAdjustmentRequested =
500 * ( mCoarseFrequencyCorrection > 0 ? 1 : -1 );
}
if( mSymbolSpreadTap != null )

View File

@@ -1501,6 +1501,7 @@ public class P25DecoderState extends DecoderState
}
else
{
/* These are alternate trunking control blocks in PDU format */
switch( pdu.getOpcode() )
{
case ADJACENT_STATUS_BROADCAST:
@@ -1583,7 +1584,7 @@ public class P25DecoderState extends DecoderState
GroupDataChannelGrantExtended gdcge =
(GroupDataChannelGrantExtended)pdu;
broadcast( new P25CallEvent.Builder( CallEventType.DATA_CALL )
CallEvent callEvent = new P25CallEvent.Builder( CallEventType.DATA_CALL )
.aliasList( getAliasList() )
.channel( gdcge.getTransmitChannel() )
.details( ( gdcge.isEncrypted() ? "ENCRYPTED" : "" ) +
@@ -1591,7 +1592,9 @@ public class P25DecoderState extends DecoderState
.frequency( gdcge.getDownlinkFrequency() )
.from( gdcge.getSourceAddress() )
.to( gdcge.getGroupAddress() )
.build() );
.build();
broadcast( new TrafficChannelAllocationEvent( this, callEvent ) );
}
else
{
@@ -1604,16 +1607,17 @@ public class P25DecoderState extends DecoderState
GroupVoiceChannelGrantExplicit gvcge =
(GroupVoiceChannelGrantExplicit)pdu;
broadcast( new P25CallEvent.Builder( CallEventType.CALL )
CallEvent callEvent = new P25CallEvent.Builder( CallEventType.CALL )
.aliasList( getAliasList() )
.channel( gvcge.getTransmitChannel() )
.details( "Trigger: PDU-GRP_V_CHAN_USER" +
( gvcge.isEncrypted() ? "ENCRYPTED" : "" ) +
.details( ( gvcge.isEncrypted() ? "ENCRYPTED" : "" ) +
( gvcge.isEmergency() ? " EMERGENCY" : "") )
.frequency( gvcge.getDownlinkFrequency() )
.from( gvcge.getSourceAddress() )
.to( gvcge.getGroupAddress() )
.build() );
.build();
broadcast( new TrafficChannelAllocationEvent( this, callEvent ) );
}
else
{
@@ -1626,18 +1630,19 @@ public class P25DecoderState extends DecoderState
IndividualDataChannelGrantExtended idcge =
(IndividualDataChannelGrantExtended)pdu;
broadcast( new P25CallEvent.Builder( CallEventType.DATA_CALL )
CallEvent callEvent = new P25CallEvent.Builder( CallEventType.DATA_CALL )
.aliasList( getAliasList() )
.channel( idcge.getTransmitChannel() )
.details( "Trigger:PDU-IND_DATA_CHAN_GRNT " +
( idcge.isEncrypted() ? "ENCRYPTED" : "" ) +
.details( ( idcge.isEncrypted() ? "ENCRYPTED" : "" ) +
( idcge.isEmergency() ? " EMERGENCY" : "") )
.frequency( idcge.getDownlinkFrequency() )
.from( idcge.getSourceWACN() + "-" +
idcge.getSourceSystemID() + "-" +
idcge.getSourceAddress() )
.to( idcge.getTargetAddress() )
.build() );
.build();
broadcast( new TrafficChannelAllocationEvent( this, callEvent ) );
}
else
{
@@ -1773,7 +1778,7 @@ public class P25DecoderState extends DecoderState
TelephoneInterconnectChannelGrantExplicit ticge =
(TelephoneInterconnectChannelGrantExplicit)pdu;
broadcast( new P25CallEvent.Builder( CallEventType.CALL )
CallEvent callEvent = new P25CallEvent.Builder( CallEventType.CALL )
.aliasList( getAliasList() )
.channel( ticge.getTransmitChannel() )
.details( "Trigger: PDU-TEL_INT_V_CH_GRNT " +
@@ -1783,7 +1788,9 @@ public class P25DecoderState extends DecoderState
" CALL TIMER:" + ticge.getCallTimer() )
.frequency( ticge.getDownlinkFrequency() )
.from( ticge.getAddress() )
.build() );
.build();
broadcast( new TrafficChannelAllocationEvent( this, callEvent ) );
break;
case UNIT_REGISTRATION_RESPONSE:
if( pdu instanceof UnitRegistrationResponseExtended )
@@ -1851,7 +1858,7 @@ public class P25DecoderState extends DecoderState
UnitToUnitVoiceChannelGrantExtended uuvcge =
(UnitToUnitVoiceChannelGrantExtended)pdu;
broadcast( new P25CallEvent.Builder( CallEventType.CALL )
CallEvent uuCallEvent = new P25CallEvent.Builder( CallEventType.CALL )
.aliasList( getAliasList() )
.channel( uuvcge.getTransmitChannel() )
.details( "Trigger:PDU-U2U_V-CH_GRNT " +
@@ -1862,7 +1869,9 @@ public class P25DecoderState extends DecoderState
uuvcge.getSourceSystemID() + "-" +
uuvcge.getSourceID() )
.to( uuvcge.getTargetAddress() )
.build() );
.build();
broadcast( new TrafficChannelAllocationEvent( this, uuCallEvent ) );
}
else
{

View File

@@ -19,6 +19,7 @@ package module.decode.p25;
import instrument.tap.Tap;
import instrument.tap.stream.DibitTap;
import instrument.tap.stream.FloatBufferTap;
import instrument.tap.stream.FloatTap;
import java.util.ArrayList;
@@ -30,14 +31,12 @@ import org.slf4j.LoggerFactory;
import sample.Listener;
import sample.real.IRealBufferListener;
import sample.real.RealBuffer;
import sample.real.RealBufferToStreamConverter;
import source.tuner.frequency.FrequencyCorrectionControl;
import alias.AliasList;
import controller.channel.Channel.ChannelType;
import dsp.filter.FilterFactory;
import dsp.filter.Window.WindowType;
import dsp.filter.fir.real.RealFIRFilter_RB_RB;
import dsp.gain.DirectGainControl;
public class P25_C4FMDecoder extends P25Decoder implements IRealBufferListener
{
@@ -45,7 +44,6 @@ public class P25_C4FMDecoder extends P25Decoder implements IRealBufferListener
/* Instrumentation Taps */
private static final String INSTRUMENT_FILTER_OUTPUT = "Tap Point: Pre-Filter Output";
private static final String INSTRUMENT_DGC_OUTPUT = "Tap Point: DGC Output";
private static final String INSTRUMENT_C4FM_SYMBOL_FILTER_OUTPUT = "Tap Point: Symbol Filter Output";
private static final String INSTRUMENT_C4FM_SLICER_OUTPUT = "Tap Point: C4FM Slicer Output";
@@ -53,9 +51,6 @@ public class P25_C4FMDecoder extends P25Decoder implements IRealBufferListener
private List<Tap> mAvailableTaps;
private RealFIRFilter_RB_RB mC4FMPreFilter;
private DirectGainControl mDGC;
private RealBufferToStreamConverter mStreamConverter =
new RealBufferToStreamConverter();
private FrequencyCorrectionControl mFrequencyCorrectionControl;
private C4FMSymbolFilter mSymbolFilter;
private C4FMSlicer mC4FMSlicer;
@@ -82,22 +77,14 @@ public class P25_C4FMDecoder extends P25Decoder implements IRealBufferListener
mC4FMPreFilter = new RealFIRFilter_RB_RB( FilterFactory.getLowPass(
48000, 6750, 7500, 60, WindowType.HANNING, true ), 1.0f );
/* Convert buffers to a sample stream so that the symbol filter can
* provide fine-grained gain control over individual samples */
mC4FMPreFilter.setListener( mStreamConverter );
/* Apply gain remotely controlled by the downstream symbol filter */
mDGC = new DirectGainControl( 15.0f, 0.1f, 35.0f, 0.3f );
mStreamConverter.setListener( mDGC );
/* Issue tuned frequency correction commands, remotely controlled by the
* downstream symbol filter */
mFrequencyCorrectionControl = new FrequencyCorrectionControl(
MAXIMUM_FREQUENCY_CORRECTION );
/* Shape gain and frequency offsets to optimize sample stream */
mSymbolFilter = new C4FMSymbolFilter( mDGC, mFrequencyCorrectionControl );
mDGC.setListener( mSymbolFilter );
mSymbolFilter = new C4FMSymbolFilter( mFrequencyCorrectionControl );
mC4FMPreFilter.setListener( mSymbolFilter );
/* Convert samples to symbols */
mC4FMSlicer = new C4FMSlicer();
@@ -119,12 +106,6 @@ public class P25_C4FMDecoder extends P25Decoder implements IRealBufferListener
mC4FMPreFilter.dispose();
mC4FMPreFilter = null;
mDGC.dispose();
mDGC = null;
mStreamConverter.dispose();
mStreamConverter = null;
mFrequencyCorrectionControl.dispose();
mFrequencyCorrectionControl = null;
@@ -172,7 +153,6 @@ public class P25_C4FMDecoder extends P25Decoder implements IRealBufferListener
mAvailableTaps = new ArrayList<Tap>();
mAvailableTaps.add( new FloatTap( INSTRUMENT_FILTER_OUTPUT, 0, 1.0f ) );
mAvailableTaps.add( new FloatTap( INSTRUMENT_DGC_OUTPUT, 0, 1.0f ) );
if( mSymbolFilter != null )
{
@@ -200,14 +180,9 @@ public class P25_C4FMDecoder extends P25Decoder implements IRealBufferListener
switch( tap.getName() )
{
case INSTRUMENT_FILTER_OUTPUT:
FloatTap filterOutput = (FloatTap)tap;
mStreamConverter.setListener( filterOutput );
filterOutput.setListener( mDGC );
break;
case INSTRUMENT_DGC_OUTPUT:
FloatTap dgcTap = (FloatTap)tap;
mDGC.setListener( dgcTap );
dgcTap.setListener( mSymbolFilter );
FloatBufferTap filterOutput = (FloatBufferTap)tap;
mC4FMPreFilter.setListener( filterOutput );
filterOutput.setListener( mSymbolFilter );
break;
case INSTRUMENT_C4FM_SYMBOL_FILTER_OUTPUT:
FloatTap symbolTap = (FloatTap)tap;
@@ -242,10 +217,7 @@ public class P25_C4FMDecoder extends P25Decoder implements IRealBufferListener
switch( tap.getName() )
{
case INSTRUMENT_FILTER_OUTPUT:
mStreamConverter.setListener( mDGC );
break;
case INSTRUMENT_DGC_OUTPUT:
mDGC.setListener( mSymbolFilter );
mC4FMPreFilter.setListener( mSymbolFilter );
break;
case INSTRUMENT_C4FM_SYMBOL_FILTER_OUTPUT:
mSymbolFilter.setListener( mC4FMSlicer );

View File

@@ -15,12 +15,12 @@ import org.slf4j.LoggerFactory;
import controller.channel.ChannelEvent;
import controller.channel.IChannelEventListener;
import sample.Listener;
import alias.Metadata;
import audio.AudioFormats;
import audio.AudioPacket;
import audio.IAudioPacketProvider;
import audio.metadata.AudioMetadata;
import audio.metadata.IMetadataListener;
import audio.metadata.Metadata;
public class P25AudioModule extends Module implements Listener<Message>,
IAudioPacketProvider, IMessageListener, IChannelEventListener, IMetadataListener
@@ -41,10 +41,12 @@ public class P25AudioModule extends Module implements Listener<Message>,
private AudioMetadata mAudioMetadata;
private ChannelEventListener mChannelEventListener = new ChannelEventListener();
public P25AudioModule()
public P25AudioModule( boolean record )
{
mSourceID = ++UNIQUE_ID;
mAudioMetadata = new AudioMetadata( mSourceID );
mAudioMetadata = new AudioMetadata( mSourceID, record );
loadConverter();
}
@Override
@@ -60,9 +62,21 @@ public class P25AudioModule extends Module implements Listener<Message>,
}
@Override
public void init()
public void reset()
{
loadConverter();
mAudioMetadata.reset();
}
@Override
public void start()
{
}
@Override
public void stop()
{
}
/**