mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 16:47:31 -05:00
Interim checkin for call recording.
This commit is contained in:
@@ -26,9 +26,12 @@ public abstract class Module
|
||||
*
|
||||
* Modules can optionally implement any of the following interfaces:
|
||||
*
|
||||
* IAudioPacketListener consumes audio packets
|
||||
* IAudioPacketProvider produces audio packets
|
||||
* ICallEventProvider call events
|
||||
* IChannelEventProvider channel events (reset, selection, start, etc)
|
||||
* ICallEventListener consumes call events
|
||||
* ICallEventProvider provides call events
|
||||
* IChannelEventListener consumes channel events
|
||||
* IChannelEventProvider provides channel events (reset, selection, start, etc)
|
||||
* IComplexBufferListener consumes complex samples and normally
|
||||
* produces demodulated real sample buffers
|
||||
* IFrequencyCorrectionController provides tuned frequency error corrections
|
||||
@@ -42,16 +45,30 @@ public abstract class Module
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize or reset all internal states to default - prepare to start
|
||||
* processing or resume processing, potentially with a different source.
|
||||
*
|
||||
* This method is invoked after constructing a module, and following any stop()
|
||||
* calls and before any start() calls. This allows the module to prior to
|
||||
* starting a module and starting it again processing a newly tuned channel,
|
||||
* like a traffic channel.
|
||||
*/
|
||||
public abstract void reset();
|
||||
|
||||
/**
|
||||
* Start processing.
|
||||
*/
|
||||
public abstract void start();
|
||||
|
||||
/**
|
||||
* Stop processing
|
||||
*/
|
||||
public abstract void stop();
|
||||
|
||||
/**
|
||||
* Dispose of all resources and listeners and prepare for garbage collection
|
||||
*/
|
||||
public abstract void dispose();
|
||||
|
||||
/**
|
||||
* Initializes or reset all internal states to default - prepare to process
|
||||
* again. This method is usually invoked between stopping a module and
|
||||
* starting it again processing a newly tuned channel, like a traffic
|
||||
* channel.
|
||||
*/
|
||||
public abstract void init();
|
||||
|
||||
}
|
||||
|
||||
@@ -54,11 +54,12 @@ import source.SourceException;
|
||||
import source.tuner.TunerChannelSource;
|
||||
import source.tuner.frequency.FrequencyCorrectionControl;
|
||||
import source.tuner.frequency.IFrequencyCorrectionController;
|
||||
import alias.Metadata;
|
||||
import audio.AudioPacket;
|
||||
import audio.IAudioPacketListener;
|
||||
import audio.IAudioPacketProvider;
|
||||
import audio.metadata.IMetadataListener;
|
||||
import audio.metadata.IMetadataProvider;
|
||||
import audio.metadata.Metadata;
|
||||
import audio.squelch.ISquelchStateListener;
|
||||
import audio.squelch.ISquelchStateProvider;
|
||||
import audio.squelch.SquelchState;
|
||||
@@ -151,6 +152,17 @@ public class ProcessingChain implements IChannelEventListener
|
||||
mRealBufferBroadcaster.dispose();
|
||||
mSquelchStateBroadcaster.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcasts the metadata to any registered listeners
|
||||
*/
|
||||
public void broadcast( Metadata metadata )
|
||||
{
|
||||
if( mMetadataBroadcaster != null )
|
||||
{
|
||||
mMetadataBroadcaster.broadcast( metadata );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this processing chain is currently receiving samples from
|
||||
@@ -274,6 +286,12 @@ public class ProcessingChain implements IChannelEventListener
|
||||
mModules.add( module );
|
||||
|
||||
/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Listeners <<<<<<<<<<<<<<<<<<<<<<<<<<< */
|
||||
if( module instanceof IAudioPacketListener )
|
||||
{
|
||||
mAudioPacketBroadcaster.addListener(
|
||||
((IAudioPacketListener)module).getAudioPacketListener() );
|
||||
}
|
||||
|
||||
if( module instanceof ICallEventListener )
|
||||
{
|
||||
mCallEventBroadcaster.addListener(
|
||||
@@ -396,10 +414,16 @@ public class ProcessingChain implements IChannelEventListener
|
||||
{
|
||||
if( mSource != null )
|
||||
{
|
||||
/* Initialize each of the modules */
|
||||
/* Reset each of the modules */
|
||||
for( Module module: mModules )
|
||||
{
|
||||
module.init();
|
||||
module.reset();
|
||||
}
|
||||
|
||||
/* Start each of the modules */
|
||||
for( Module module: mModules )
|
||||
{
|
||||
module.start();
|
||||
}
|
||||
|
||||
/* Register with the source to receive sample data. Setup a
|
||||
@@ -475,6 +499,12 @@ public class ProcessingChain implements IChannelEventListener
|
||||
mThreadPoolManager.cancel( mBufferProcessingTask );
|
||||
mBufferProcessingTask = null;
|
||||
}
|
||||
|
||||
/* Stop each of the modules */
|
||||
for( Module module: mModules )
|
||||
{
|
||||
module.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -73,11 +73,27 @@ public abstract class Decoder extends Module
|
||||
* external modules can be correctly configured. This method is invoked
|
||||
* prior to processing start.
|
||||
*/
|
||||
public void init()
|
||||
public void reset()
|
||||
{
|
||||
mDecoderState.init();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Start the decoder
|
||||
*/
|
||||
@Override
|
||||
public void start()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the decoder
|
||||
*/
|
||||
@Override
|
||||
public void stop()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Identifies the decoder type (ie protocol)
|
||||
*/
|
||||
|
||||
@@ -71,6 +71,8 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import properties.SystemProperties;
|
||||
import record.RecorderType;
|
||||
import record.config.RecordConfiguration;
|
||||
import settings.SettingsManager;
|
||||
import util.TimeStamp;
|
||||
import alias.AliasList;
|
||||
@@ -79,6 +81,8 @@ import controller.ResourceManager;
|
||||
import controller.channel.Channel.ChannelType;
|
||||
import controller.channel.ChannelNode;
|
||||
import controller.channel.map.ChannelMap;
|
||||
import controller.site.Site;
|
||||
import controller.system.System;
|
||||
import filter.AllPassFilter;
|
||||
import filter.FilterSet;
|
||||
import filter.IFilter;
|
||||
@@ -87,7 +91,7 @@ public class DecoderFactory
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger( DecoderFactory.class );
|
||||
|
||||
public static final boolean NO_DC_REMOVAL = false;
|
||||
public static final boolean NO_REMOVE_DC = false;
|
||||
public static final boolean REMOVE_DC = true;
|
||||
|
||||
public static final int NO_FREQUENCY_CORRECTION = 0;
|
||||
@@ -96,80 +100,98 @@ public class DecoderFactory
|
||||
* Returns a list of one primary decoder and any auxiliary decoders, as
|
||||
* specified in the configurations.
|
||||
*
|
||||
* @param config - primary decoder configuration
|
||||
* @param channelType - standard or traffic channel type
|
||||
* @param resourceManager
|
||||
* @param decodeConfig - primary decoder configuration
|
||||
* @param recordConfig - recording configuration used by traffic channel manager
|
||||
* @param auxConfig - auxiliary decoder(s) configuration
|
||||
* @param optional alias list - (null is ok)
|
||||
*
|
||||
* @return list of configured decoders
|
||||
*/
|
||||
public static List<Module> getModules( ChannelType channelType,
|
||||
ResourceManager resourceManager,
|
||||
DecodeConfiguration config,
|
||||
DecodeConfiguration decodeConfig,
|
||||
RecordConfiguration recordConfig,
|
||||
AuxDecodeConfiguration auxConfig,
|
||||
AliasList aliasList )
|
||||
{
|
||||
List<Module> modules = getPrimaryModules( channelType, config,
|
||||
aliasList, resourceManager );
|
||||
AliasList aliasList,
|
||||
System system,
|
||||
Site site )
|
||||
{
|
||||
List<Module> modules = getPrimaryModules( channelType, decodeConfig,
|
||||
recordConfig, aliasList, system, site, resourceManager );
|
||||
|
||||
modules.addAll( getAuxiliaryDecoders( auxConfig, aliasList ) );
|
||||
|
||||
return modules;
|
||||
}
|
||||
|
||||
public static FMDemodulatorModule getFMDemodulator( DecodeConfiguration config, int pass, int stop, boolean removeDC )
|
||||
public static FMDemodulatorModule getFMDemodulator(
|
||||
DecodeConfiguration config, int pass, int stop, boolean removeDC )
|
||||
{
|
||||
if( config.isAFCEnabled() )
|
||||
{
|
||||
return new FMDemodulatorModule( pass, stop, config.getAFCMaximumCorrection(), removeDC );
|
||||
return new FMDemodulatorModule( pass, stop,
|
||||
config.getAFCMaximumCorrection(), removeDC );
|
||||
}
|
||||
else
|
||||
{
|
||||
return new FMDemodulatorModule( pass, stop, NO_FREQUENCY_CORRECTION, removeDC );
|
||||
return new FMDemodulatorModule( pass, stop,
|
||||
NO_FREQUENCY_CORRECTION, removeDC );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a primary decoder as specified in the decode configuration
|
||||
* @param config - primary decoder configuration
|
||||
*
|
||||
* @param channelType - traffic or standard decode channel
|
||||
* @param decodeConfig - primary decoder configuration
|
||||
* @param recordConfig - recording options
|
||||
* @param aliasList - optional alias list
|
||||
* @param resourceManager - shared resource manager
|
||||
* @return configured decoder or null
|
||||
*/
|
||||
public static List<Module> getPrimaryModules( ChannelType channelType,
|
||||
DecodeConfiguration config,
|
||||
AliasList aliasList,
|
||||
DecodeConfiguration decodeConfig,
|
||||
RecordConfiguration recordConfig,
|
||||
AliasList aliasList,
|
||||
System system,
|
||||
Site site,
|
||||
ResourceManager resourceManager )
|
||||
{
|
||||
List<Module> modules = new ArrayList<Module>();
|
||||
|
||||
/* Baseband low-pass filter pass and stop frequencies */
|
||||
int pass = config.getDecoderType().getChannelBandwidth() / 2;
|
||||
int pass = decodeConfig.getDecoderType().getChannelBandwidth() / 2;
|
||||
int stop = pass + 1250;
|
||||
|
||||
switch( config.getDecoderType() )
|
||||
boolean recordAudio = recordConfig.getRecorders().contains( RecorderType.AUDIO );
|
||||
|
||||
switch( decodeConfig.getDecoderType() )
|
||||
{
|
||||
case AM:
|
||||
// decoder = new AMDecoder();
|
||||
break;
|
||||
case NBFM:
|
||||
modules.add( new AudioModule() );
|
||||
modules.add( new NBFMDecoder( config ) );
|
||||
modules.add( getFMDemodulator( config, pass, stop, REMOVE_DC ) );
|
||||
modules.add( new AudioModule( recordAudio, NO_REMOVE_DC ) );
|
||||
modules.add( new NBFMDecoder( decodeConfig ) );
|
||||
modules.add( getFMDemodulator( decodeConfig, pass, stop, REMOVE_DC ) );
|
||||
break;
|
||||
case LTR_STANDARD:
|
||||
modules.add( new AudioModule( REMOVE_DC ) );
|
||||
MessageDirection direction = ((DecodeConfigLTRStandard)config).getMessageDirection();
|
||||
modules.add( new AudioModule( recordAudio, REMOVE_DC ) );
|
||||
MessageDirection direction = ((DecodeConfigLTRStandard)decodeConfig).getMessageDirection();
|
||||
modules.add( new LTRStandardDecoder( aliasList, direction ) );
|
||||
modules.add( getFMDemodulator( config, pass, stop, NO_DC_REMOVAL ) );
|
||||
modules.add( getFMDemodulator( decodeConfig, pass, stop, NO_REMOVE_DC ) );
|
||||
break;
|
||||
case LTR_NET:
|
||||
modules.add( new AudioModule( REMOVE_DC ) );
|
||||
modules.add( new LTRNetDecoder( (DecodeConfigLTRNet)config, aliasList ) );
|
||||
// modules.add( new ComplexBufferRecorderModule( getRecordingFilename( "decimated_baseband" ) ) );
|
||||
modules.add( getFMDemodulator( config, pass, stop, NO_DC_REMOVAL ) );
|
||||
modules.add( new AudioModule( recordAudio, REMOVE_DC ) );
|
||||
modules.add( new LTRNetDecoder( (DecodeConfigLTRNet)decodeConfig, aliasList ) );
|
||||
modules.add( getFMDemodulator( decodeConfig, pass, stop, NO_REMOVE_DC ) );
|
||||
break;
|
||||
case MPT1327:
|
||||
DecodeConfigMPT1327 mptConfig = (DecodeConfigMPT1327)config;
|
||||
DecodeConfigMPT1327 mptConfig = (DecodeConfigMPT1327)decodeConfig;
|
||||
|
||||
modules.add( new AudioModule() );
|
||||
modules.add( new AudioModule( recordAudio, NO_REMOVE_DC ) );
|
||||
|
||||
ChannelMap channelMap = resourceManager.getPlaylistManager().getPlayist()
|
||||
.getChannelMapList().getChannelMap( mptConfig.getChannelMapName() );
|
||||
@@ -181,25 +203,25 @@ public class DecoderFactory
|
||||
long timeout = mptConfig.getCallTimeout() * 1000; //convert to milliseconds
|
||||
|
||||
modules.add( new TrafficChannelManager( resourceManager,
|
||||
config, timeout,
|
||||
decodeConfig, recordConfig, system, site,
|
||||
aliasList.getName(), timeout,
|
||||
mptConfig.getTrafficChannelPoolSize() ) );
|
||||
}
|
||||
|
||||
// modules.add( new RealBufferRecorderModule( getRecordingFilename( "demodulated_mpt1327" ) ) );
|
||||
modules.add( getFMDemodulator( config, pass, stop, REMOVE_DC ) );
|
||||
modules.add( getFMDemodulator( decodeConfig, pass, stop, REMOVE_DC ) );
|
||||
break;
|
||||
case PASSPORT:
|
||||
// decoder = new PassportDecoder( config, aliasList );
|
||||
break;
|
||||
case P25_PHASE1:
|
||||
DecodeConfigP25Phase1 p25Config = (DecodeConfigP25Phase1)config;
|
||||
DecodeConfigP25Phase1 p25Config = (DecodeConfigP25Phase1)decodeConfig;
|
||||
|
||||
Modulation modulation = p25Config.getModulation();
|
||||
|
||||
switch( modulation )
|
||||
{
|
||||
case C4FM:
|
||||
modules.add( getFMDemodulator( config, 6750, 7500, REMOVE_DC ) );
|
||||
modules.add( getFMDemodulator( decodeConfig, 6750, 7500, REMOVE_DC ) );
|
||||
modules.add( new P25_C4FMDecoder( aliasList, channelType ) );
|
||||
break;
|
||||
case CQPSK:
|
||||
@@ -215,16 +237,17 @@ public class DecoderFactory
|
||||
long timeout = p25Config.getCallTimeout() * 1000; //convert to milliseconds
|
||||
|
||||
modules.add( new TrafficChannelManager( resourceManager,
|
||||
config, timeout,
|
||||
decodeConfig, recordConfig, system, site,
|
||||
aliasList.getName(), timeout,
|
||||
p25Config.getTrafficChannelPoolSize() ) );
|
||||
}
|
||||
|
||||
modules.add( new P25AudioModule() );
|
||||
modules.add( new P25AudioModule( recordAudio ) );
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
"Unknown decoder type [" +
|
||||
config.getDecoderType().toString() + "]" );
|
||||
decodeConfig.getDecoderType().toString() + "]" );
|
||||
}
|
||||
|
||||
return modules;
|
||||
|
||||
@@ -23,7 +23,7 @@ import java.util.Date;
|
||||
import module.decode.DecoderType;
|
||||
import alias.Alias;
|
||||
import alias.AliasList;
|
||||
import alias.MetadataType;
|
||||
import audio.metadata.MetadataType;
|
||||
|
||||
public abstract class CallEvent implements Comparable<CallEvent>
|
||||
{
|
||||
@@ -133,7 +133,7 @@ public abstract class CallEvent implements Comparable<CallEvent>
|
||||
|
||||
public MetadataType getFromIDType()
|
||||
{
|
||||
return MetadataType.FROM_TALKGROUP;
|
||||
return MetadataType.FROM;
|
||||
}
|
||||
|
||||
public void setFromID( String id )
|
||||
|
||||
@@ -26,6 +26,9 @@ import instrument.tap.stream.FloatTap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import module.decode.Decoder;
|
||||
import module.decode.DecoderType;
|
||||
import sample.Broadcaster;
|
||||
@@ -35,6 +38,7 @@ import sample.real.RealBuffer;
|
||||
import alias.AliasList;
|
||||
import bits.MessageFramer;
|
||||
import bits.SyncPattern;
|
||||
import controller.channel.Channel;
|
||||
import controller.channel.Channel.ChannelType;
|
||||
import controller.channel.map.ChannelMap;
|
||||
import dsp.filter.FilterFactory;
|
||||
@@ -54,6 +58,8 @@ import dsp.fsk.FSK2Decoder.Output;
|
||||
public class MPT1327Decoder extends Decoder
|
||||
implements IRealBufferListener, Instrumentable
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger( MPT1327Decoder.class );
|
||||
|
||||
/* Decimated sample rate ( 48,000 / 2 = 24,000 ) feeding the decoder */
|
||||
private static final int sDECIMATED_SAMPLE_RATE = 24000;
|
||||
|
||||
|
||||
@@ -35,12 +35,12 @@ public class MPT1327DecoderPanel extends DecoderPanel
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private JLabel mProtocol = new JLabel( "" );
|
||||
private JLabel mSiteOrFromTalkgroup = new JLabel( "" );
|
||||
private JLabel mSiteOrFromTalkgroupAlias = new JLabel( "" );
|
||||
private JLabel mSiteOrToTalkgroup = new JLabel( "" );
|
||||
private JLabel mSiteOrToTalkgroupAlias = new JLabel( "" );
|
||||
|
||||
private JLabel mToTalkgroupLabel = new JLabel( "" );
|
||||
private JLabel mToTalkgroup = new JLabel( "" );
|
||||
private JLabel mToTalkgroupAliasLabel = new JLabel( "" );
|
||||
private JLabel mFromTalkgroupLabel = new JLabel( "" );
|
||||
private JLabel mFromTalkgroup = new JLabel( "" );
|
||||
private JLabel mFromTalkgroupAliasLabel = new JLabel( "" );
|
||||
|
||||
public MPT1327DecoderPanel( SettingsManager settingsManager, MPT1327Decoder decoder )
|
||||
{
|
||||
@@ -71,35 +71,35 @@ public class MPT1327DecoderPanel extends DecoderPanel
|
||||
|
||||
MPT1327DecoderState mptState = getDecoderState();
|
||||
|
||||
mSiteOrFromTalkgroup.setFont( mFontDecoder );
|
||||
mSiteOrFromTalkgroup.setForeground( mColorLabelDecoder );
|
||||
mSiteOrToTalkgroup.setFont( mFontDecoder );
|
||||
mSiteOrToTalkgroup.setForeground( mColorLabelDecoder );
|
||||
|
||||
mSiteOrFromTalkgroupAlias.setFont( mFontDecoder );
|
||||
mSiteOrFromTalkgroupAlias.setForeground( mColorLabelDecoder );
|
||||
mSiteOrToTalkgroupAlias.setFont( mFontDecoder );
|
||||
mSiteOrToTalkgroupAlias.setForeground( mColorLabelDecoder );
|
||||
|
||||
mToTalkgroupLabel.setFont( mFontDetails );
|
||||
mToTalkgroupLabel.setForeground( mColorLabelDetails );
|
||||
mFromTalkgroupLabel.setFont( mFontDetails );
|
||||
mFromTalkgroupLabel.setForeground( mColorLabelDetails );
|
||||
|
||||
mToTalkgroup.setFont( mFontDecoder );
|
||||
mToTalkgroup.setForeground( mColorLabelDecoder );
|
||||
mFromTalkgroup.setFont( mFontDecoder );
|
||||
mFromTalkgroup.setForeground( mColorLabelDecoder );
|
||||
|
||||
mToTalkgroupAliasLabel.setFont( mFontDecoder );
|
||||
mToTalkgroupAliasLabel.setForeground( mColorLabelDecoder );
|
||||
mFromTalkgroupAliasLabel.setFont( mFontDecoder );
|
||||
mFromTalkgroupAliasLabel.setForeground( mColorLabelDecoder );
|
||||
|
||||
|
||||
switch( mptState.getChannelType() )
|
||||
{
|
||||
case STANDARD:
|
||||
mSiteOrFromTalkgroup.setText( mptState.getSite() );
|
||||
setAliasLabel( mSiteOrFromTalkgroupAlias, mptState.getSiteAlias() );
|
||||
mSiteOrToTalkgroup.setText( mptState.getSite() );
|
||||
setAliasLabel( mSiteOrToTalkgroupAlias, mptState.getSiteAlias() );
|
||||
break;
|
||||
case TRAFFIC:
|
||||
mSiteOrFromTalkgroup.setText( mptState.getFromTalkgroup() );
|
||||
setAliasLabel( mSiteOrFromTalkgroupAlias, mptState.getFromTalkgroupAlias() );
|
||||
mSiteOrToTalkgroup.setText( mptState.getToTalkgroup() );
|
||||
setAliasLabel( mSiteOrToTalkgroupAlias, mptState.getToTalkgroupAlias() );
|
||||
|
||||
mToTalkgroupLabel.setText( "To:" );
|
||||
mToTalkgroup.setText( getDecoderState().getToTalkgroup() );
|
||||
setAliasLabel( mToTalkgroupAliasLabel, mptState.getToTalkgroupAlias() );
|
||||
mFromTalkgroupLabel.setText( "From:" );
|
||||
mFromTalkgroup.setText( getDecoderState().getFromTalkgroup() );
|
||||
setAliasLabel( mFromTalkgroupAliasLabel, mptState.getFromTalkgroupAlias() );
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException( "Unrecognized channel "
|
||||
@@ -108,14 +108,14 @@ public class MPT1327DecoderPanel extends DecoderPanel
|
||||
}
|
||||
|
||||
add( mProtocol );
|
||||
add( mSiteOrFromTalkgroup );
|
||||
add( mSiteOrFromTalkgroupAlias, "wrap" );
|
||||
add( mSiteOrToTalkgroup );
|
||||
add( mSiteOrToTalkgroupAlias, "wrap" );
|
||||
|
||||
if( mptState.getChannelType() == ChannelType.TRAFFIC )
|
||||
{
|
||||
add( mToTalkgroupLabel );
|
||||
add( mToTalkgroup );
|
||||
add( mToTalkgroupAliasLabel, "wrap" );
|
||||
add( mFromTalkgroupLabel );
|
||||
add( mFromTalkgroup );
|
||||
add( mFromTalkgroupAliasLabel, "wrap" );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,18 +156,18 @@ public class MPT1327DecoderPanel extends DecoderPanel
|
||||
switch( changedAttribute )
|
||||
{
|
||||
case CHANNEL_SITE_NUMBER:
|
||||
mSiteOrFromTalkgroup.setText( String.valueOf( state.getSite() ) );
|
||||
setAliasLabel( mSiteOrFromTalkgroupAlias, state.getSiteAlias() );
|
||||
repaint();
|
||||
break;
|
||||
case FROM_TALKGROUP:
|
||||
mSiteOrFromTalkgroup.setText( state.getFromTalkgroup() );
|
||||
setAliasLabel( mSiteOrFromTalkgroupAlias, state.getFromTalkgroupAlias() );
|
||||
mSiteOrToTalkgroup.setText( String.valueOf( state.getSite() ) );
|
||||
setAliasLabel( mSiteOrToTalkgroupAlias, state.getSiteAlias() );
|
||||
repaint();
|
||||
break;
|
||||
case TO_TALKGROUP:
|
||||
mToTalkgroup.setText( state.getToTalkgroup() );
|
||||
setAliasLabel( mToTalkgroupAliasLabel, state.getToTalkgroupAlias() );
|
||||
mSiteOrToTalkgroup.setText( state.getToTalkgroup() );
|
||||
setAliasLabel( mSiteOrToTalkgroupAlias, state.getToTalkgroupAlias() );
|
||||
repaint();
|
||||
break;
|
||||
case FROM_TALKGROUP:
|
||||
mFromTalkgroup.setText( state.getFromTalkgroup() );
|
||||
setAliasLabel( mFromTalkgroupAliasLabel, state.getFromTalkgroupAlias() );
|
||||
repaint();
|
||||
break;
|
||||
default:
|
||||
@@ -193,27 +193,27 @@ public class MPT1327DecoderPanel extends DecoderPanel
|
||||
{
|
||||
mProtocol.setForeground( mColorLabelDecoder );
|
||||
}
|
||||
if( mSiteOrFromTalkgroup != null )
|
||||
if( mSiteOrToTalkgroup != null )
|
||||
{
|
||||
mSiteOrFromTalkgroup.setForeground( mColorLabelDecoder );
|
||||
mSiteOrToTalkgroup.setForeground( mColorLabelDecoder );
|
||||
}
|
||||
if( mSiteOrFromTalkgroupAlias != null )
|
||||
if( mSiteOrToTalkgroupAlias != null )
|
||||
{
|
||||
mSiteOrFromTalkgroupAlias.setForeground( mColorLabelDecoder );
|
||||
mSiteOrToTalkgroupAlias.setForeground( mColorLabelDecoder );
|
||||
}
|
||||
if( mToTalkgroup != null )
|
||||
if( mFromTalkgroup != null )
|
||||
{
|
||||
mToTalkgroup.setForeground( mColorLabelDecoder );
|
||||
mFromTalkgroup.setForeground( mColorLabelDecoder );
|
||||
}
|
||||
if( mToTalkgroupAliasLabel != null )
|
||||
if( mFromTalkgroupAliasLabel != null )
|
||||
{
|
||||
mToTalkgroupAliasLabel.setForeground( mColorLabelDecoder );
|
||||
mFromTalkgroupAliasLabel.setForeground( mColorLabelDecoder );
|
||||
}
|
||||
break;
|
||||
case CHANNEL_STATE_LABEL_DETAILS:
|
||||
if( mToTalkgroupLabel != null )
|
||||
if( mFromTalkgroupLabel != null )
|
||||
{
|
||||
mToTalkgroupLabel.setForeground( mColorLabelDetails );
|
||||
mFromTalkgroupLabel.setForeground( mColorLabelDetails );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -245,42 +245,6 @@ public class MPT1327DecoderState extends DecoderState
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Intercept the fade event so that we can generate a call end event
|
||||
// */
|
||||
// @Override
|
||||
// public void fade( final CallEventType type )
|
||||
// {
|
||||
// /*
|
||||
// * We can receive multiple call tear-down messages -- only post a call
|
||||
// * end event for the one that can change the state to fade
|
||||
// */
|
||||
// if( getState().canChangeTo( State.FADE ) )
|
||||
// {
|
||||
// CallEvent current = getCurrentCallEvent();
|
||||
//
|
||||
// if( current != null )
|
||||
// {
|
||||
// mCallEventModel.setEnd( current );
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// mCallEventModel.add(
|
||||
// new MPT1327CallEvent.Builder( type )
|
||||
// .aliasList( getAliasList() )
|
||||
// .channel( String.valueOf( mChannelNumber ) )
|
||||
// .frequency( mChannelMap.getFrequency( mChannelNumber ) )
|
||||
// .from( mFromTalkgroup )
|
||||
// .to( mToTalkgroup )
|
||||
// .build() );
|
||||
// }
|
||||
//
|
||||
// setCurrentCall( null );
|
||||
// }
|
||||
//
|
||||
// super.fade( type );
|
||||
// }
|
||||
|
||||
public void reset()
|
||||
{
|
||||
mIdents.clear();
|
||||
@@ -343,7 +307,7 @@ public class MPT1327DecoderState extends DecoderState
|
||||
{
|
||||
if( hasAliasList() )
|
||||
{
|
||||
return getAliasList().getTalkgroupAlias( mFromTalkgroup );
|
||||
return getAliasList().getMPT1327Alias( mFromTalkgroup );
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -370,7 +334,7 @@ public class MPT1327DecoderState extends DecoderState
|
||||
{
|
||||
if( hasAliasList() )
|
||||
{
|
||||
return getAliasList().getTalkgroupAlias( mToTalkgroup );
|
||||
return getAliasList().getMPT1327Alias( mToTalkgroup );
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,10 +31,10 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sample.Listener;
|
||||
import alias.Metadata;
|
||||
import alias.MetadataReset;
|
||||
import alias.MetadataType;
|
||||
import audio.metadata.IMetadataProvider;
|
||||
import audio.metadata.Metadata;
|
||||
import audio.metadata.MetadataReset;
|
||||
import audio.metadata.MetadataType;
|
||||
import audio.squelch.ISquelchStateProvider;
|
||||
import audio.squelch.SquelchState;
|
||||
import controller.ThreadPoolManager;
|
||||
@@ -117,9 +117,18 @@ public class ChannelState extends Module implements ICallEventProvider,
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
public void reset()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void dispose()
|
||||
@@ -500,7 +509,7 @@ public class ChannelState extends Module implements ICallEventProvider,
|
||||
|
||||
if( channel != null )
|
||||
{
|
||||
broadcast( new Metadata( MetadataType.CHANNEL, channel, true ) );
|
||||
broadcast( new Metadata( MetadataType.CHANNEL_NUMBER, channel, true ) );
|
||||
}
|
||||
|
||||
broadcast( new Metadata( MetadataType.PROTOCOL,
|
||||
|
||||
@@ -225,7 +225,7 @@ public class ChannelStatePanel extends JPanel
|
||||
g2.drawLine( 0, getHeight() - 1, getWidth(), getHeight() - 1 );
|
||||
|
||||
/* Draw channel selected box */
|
||||
if( getChannel().isSelected() )
|
||||
if( getChannel() != null && getChannel().isSelected() )
|
||||
{
|
||||
g2.setColor( mColorChannelSelected );
|
||||
g2.drawRect( 1, 1, getWidth() - 2, getHeight() - 2 );
|
||||
|
||||
@@ -14,10 +14,12 @@ import module.decode.event.ICallEventProvider;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import record.config.RecordConfiguration;
|
||||
import sample.Listener;
|
||||
import source.config.SourceConfigTuner;
|
||||
import source.tuner.TunerChannel;
|
||||
import source.tuner.TunerChannel.Type;
|
||||
import alias.AliasList;
|
||||
import controller.ResourceManager;
|
||||
import controller.channel.Channel;
|
||||
import controller.channel.Channel.ChannelType;
|
||||
@@ -38,7 +40,11 @@ public class TrafficChannelManager extends Module
|
||||
private Listener<CallEvent> mCallEventListener;
|
||||
|
||||
private DecodeConfiguration mDecodeConfiguration;
|
||||
private RecordConfiguration mRecordConfiguration;
|
||||
private ResourceManager mResourceManager;
|
||||
private System mSystem;
|
||||
private Site mSite;
|
||||
private String mAliasListName;
|
||||
private long mTrafficChannelTimeout;
|
||||
|
||||
/**
|
||||
@@ -51,6 +57,8 @@ public class TrafficChannelManager extends Module
|
||||
* @param decodeConfiguration - decoder configuration to use for each
|
||||
* traffic channel allocation.
|
||||
*
|
||||
* @param recordConfiguration - recording options for each traffic channel
|
||||
*
|
||||
* @param trafficChannelTimeout - millisecond call timer limit used when an
|
||||
* end of call signalling event is not decoded.
|
||||
*
|
||||
@@ -59,11 +67,19 @@ public class TrafficChannelManager extends Module
|
||||
*/
|
||||
public TrafficChannelManager( ResourceManager resourceManager,
|
||||
DecodeConfiguration decodeConfiguration,
|
||||
RecordConfiguration recordConfiguration,
|
||||
System system,
|
||||
Site site,
|
||||
String aliasListName,
|
||||
long trafficChannelTimeout,
|
||||
int trafficChannelPoolSize )
|
||||
{
|
||||
mResourceManager = resourceManager;
|
||||
mDecodeConfiguration = decodeConfiguration;
|
||||
mRecordConfiguration = recordConfiguration;
|
||||
mSystem = system;
|
||||
mSite = site;
|
||||
mAliasListName = aliasListName;
|
||||
mTrafficChannelTimeout = trafficChannelTimeout;
|
||||
mTrafficChannelPoolMaximumSize = trafficChannelPoolSize;
|
||||
}
|
||||
@@ -97,10 +113,14 @@ public class TrafficChannelManager extends Module
|
||||
|
||||
channel.setDecodeConfiguration( mDecodeConfiguration );
|
||||
|
||||
channel.setRecordConfiguration( mRecordConfiguration );
|
||||
|
||||
channel.setResourceManager( mResourceManager );
|
||||
|
||||
channel.setTrafficChannelTimeout( mTrafficChannelTimeout );
|
||||
|
||||
channel.setAliasListName( mAliasListName );
|
||||
|
||||
mTrafficChannelPool.add( channel );
|
||||
}
|
||||
|
||||
@@ -109,8 +129,8 @@ public class TrafficChannelManager extends Module
|
||||
{
|
||||
channel.setSourceConfiguration( new SourceConfigTuner( tunerChannel ) );
|
||||
|
||||
channel.setSystem( new System( "Traffic" ), false );
|
||||
channel.setSite( new Site( "Channel" ), false );
|
||||
channel.setSystem( mSystem, false );
|
||||
channel.setSite( mSite, false );
|
||||
channel.setName( channelNumber );
|
||||
|
||||
channel.setEnabled( true );
|
||||
@@ -124,8 +144,8 @@ public class TrafficChannelManager extends Module
|
||||
{
|
||||
channel.setEnabled( false );
|
||||
|
||||
channel.setSystem( null, false );
|
||||
channel.setSite( null, false );
|
||||
channel.setSystem( mSystem, false );
|
||||
channel.setSite( mSite, false );
|
||||
channel.setName( "Traffic" );
|
||||
}
|
||||
}
|
||||
@@ -208,9 +228,30 @@ public class TrafficChannelManager extends Module
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
public void reset()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop()
|
||||
{
|
||||
if( !mTrafficChannelsInUse.isEmpty() )
|
||||
{
|
||||
List<String> channels = new ArrayList<>();
|
||||
|
||||
/* Copy the keyset so we don't get concurrent modification of the map */
|
||||
channels.addAll( mTrafficChannelsInUse.keySet() );
|
||||
|
||||
for( String channel: channels )
|
||||
{
|
||||
callEnd( channel );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -94,7 +94,7 @@ public class AMDemodulatorModule extends Module
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
public void reset()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -109,4 +109,14 @@ public class AMDemodulatorModule extends Module
|
||||
{
|
||||
mAGC.removeListener();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ public class FMDemodulatorModule extends Module implements IComplexBufferListene
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
public void reset()
|
||||
{
|
||||
mDemodulator.reset();
|
||||
|
||||
@@ -193,4 +193,14 @@ public class FMDemodulatorModule extends Module implements IComplexBufferListene
|
||||
mUnfilteredBufferBroadcaster.removeListener( mListener );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public class CallEventLogger extends EventLogger implements ICallEventListener,
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
public void reset()
|
||||
{
|
||||
super.start();
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public class MessageEventLogger extends EventLogger implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
public void reset()
|
||||
{
|
||||
super.start();
|
||||
}
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
package module.record;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import module.Module;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import record.wave.ComplexWaveRecorder;
|
||||
import sample.Listener;
|
||||
import sample.complex.ComplexBuffer;
|
||||
import sample.complex.IComplexBufferListener;
|
||||
|
||||
public class ComplexBufferRecorderModule extends Module
|
||||
implements IComplexBufferListener
|
||||
{
|
||||
private final static Logger mLog =
|
||||
LoggerFactory.getLogger( ComplexBufferRecorderModule.class );
|
||||
|
||||
private ComplexWaveRecorder mRecorder;
|
||||
private String mFilename;
|
||||
|
||||
public ComplexBufferRecorderModule( String filename )
|
||||
{
|
||||
mFilename = filename;
|
||||
mRecorder = new ComplexWaveRecorder( 48000, mFilename );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Listener<ComplexBuffer> getComplexBufferListener()
|
||||
{
|
||||
return mRecorder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
mRecorder.stop();
|
||||
}
|
||||
catch ( IOException e )
|
||||
{
|
||||
mLog.error( "Error stopping the recorder", e );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
mLog.debug( "Starting the recorder [" + mFilename + "]" );
|
||||
|
||||
try
|
||||
{
|
||||
mRecorder.start();
|
||||
}
|
||||
catch ( IOException e )
|
||||
{
|
||||
mLog.error( "Error starting the recorder", e );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package module.record;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import module.Module;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import record.wave.FloatWaveRecorder;
|
||||
import sample.Listener;
|
||||
import sample.real.IRealBufferListener;
|
||||
import sample.real.RealBuffer;
|
||||
|
||||
public class RealBufferRecorderModule extends Module
|
||||
implements IRealBufferListener
|
||||
{
|
||||
private final static Logger mLog =
|
||||
LoggerFactory.getLogger( RealBufferRecorderModule.class );
|
||||
|
||||
private FloatWaveRecorder mRecorder;
|
||||
private String mFilename;
|
||||
|
||||
public RealBufferRecorderModule( String filename )
|
||||
{
|
||||
mFilename = filename;
|
||||
mRecorder = new FloatWaveRecorder( 48000, mFilename );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Listener<RealBuffer> getRealBufferListener()
|
||||
{
|
||||
return mRecorder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
mRecorder.stop();
|
||||
}
|
||||
catch ( IOException e )
|
||||
{
|
||||
mLog.error( "Error stopping the recorder", e );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
mLog.debug( "Starting the recorder [" + mFilename + "]" );
|
||||
|
||||
try
|
||||
{
|
||||
mRecorder.start();
|
||||
}
|
||||
catch ( IOException e )
|
||||
{
|
||||
mLog.error( "Error starting the recorder", e );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user