mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-15 01:57:39 -05:00
Compare commits
25 Commits
v0.3.0-bet
...
v0.3.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fbc92cfe31 | ||
|
|
1a432197ac | ||
|
|
fbc6e508bd | ||
|
|
f9b6e67b00 | ||
|
|
a628800a71 | ||
|
|
25f71a76c4 | ||
|
|
5fe8ccd478 | ||
|
|
069f951a86 | ||
|
|
dab6df7836 | ||
|
|
89da46b63c | ||
|
|
5f2ce2a9f2 | ||
|
|
7a0b377971 | ||
|
|
5dbe0ecce3 | ||
|
|
6647c581a6 | ||
|
|
a2ab5bfa95 | ||
|
|
ed486440b8 | ||
|
|
13464e01fc | ||
|
|
ea46a8b0e8 | ||
|
|
d510c34356 | ||
|
|
ae8a44caed | ||
|
|
1aa85a86ca | ||
|
|
17539d4d55 | ||
|
|
1db1d28390 | ||
|
|
37a941e904 | ||
|
|
57f6655824 |
@@ -7,7 +7,7 @@
|
|||||||
<property name="major" value="0"/>
|
<property name="major" value="0"/>
|
||||||
<property name="minor" value="3"/>
|
<property name="minor" value="3"/>
|
||||||
<property name="patch" value="0"/>
|
<property name="patch" value="0"/>
|
||||||
<property name="release" value="-beta8"/>
|
<property name="release" value="-beta10"/>
|
||||||
<property name="filename" value="sdrtrunk_${major}.${minor}.${patch}${release}"/>
|
<property name="filename" value="sdrtrunk_${major}.${minor}.${patch}${release}"/>
|
||||||
|
|
||||||
<!-- Build properties -->
|
<!-- Build properties -->
|
||||||
|
|||||||
@@ -90,7 +90,8 @@ public class AudioChannelPanel extends JPanel
|
|||||||
|
|
||||||
private void init()
|
private void init()
|
||||||
{
|
{
|
||||||
setLayout(new MigLayout("align center center, insets 0 0 0 0", "[][][align right]0[grow,fill]", ""));
|
setLayout(new MigLayout("align center center, insets 0 0 0 0",
|
||||||
|
"[][][align right]0[grow,fill]", ""));
|
||||||
setBackground(mBackgroundColor);
|
setBackground(mBackgroundColor);
|
||||||
|
|
||||||
mMutedLabel.setFont(mFont);
|
mMutedLabel.setFont(mFont);
|
||||||
@@ -109,7 +110,7 @@ public class AudioChannelPanel extends JPanel
|
|||||||
|
|
||||||
mTo.setFont(mFont);
|
mTo.setFont(mFont);
|
||||||
mTo.setForeground(mValueColor);
|
mTo.setForeground(mValueColor);
|
||||||
add(mTo);
|
add(mTo,"wmin 10lp");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -159,29 +160,39 @@ public class AudioChannelPanel extends JPanel
|
|||||||
* does not occur on the Swing event thread -- wrap any calls to this
|
* does not occur on the Swing event thread -- wrap any calls to this
|
||||||
* method with an event thread call.
|
* method with an event thread call.
|
||||||
*/
|
*/
|
||||||
private void updateLabel(JLabel valueLabel, String value, JLabel aliasLabel, Alias alias)
|
private void updateLabel(JLabel textLabel, String value, JLabel iconLabel, Alias alias)
|
||||||
{
|
{
|
||||||
if(value != null)
|
if(value != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(alias != null)
|
if(alias != null)
|
||||||
{
|
{
|
||||||
valueLabel.setText(alias.getName());
|
iconLabel.setIcon(mIconManager.getIcon(alias.getIconName(), 18));
|
||||||
aliasLabel.setIcon(mIconManager.getIcon(alias.getIconName(), 18));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
valueLabel.setText(value);
|
|
||||||
aliasLabel.setIcon(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
valueLabel.setText("-----");
|
|
||||||
aliasLabel.setIcon(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
String aliasName = alias.getName();
|
||||||
|
|
||||||
|
//Truncate label if length exceeds 33 characters - hack!
|
||||||
|
if(aliasName.length() > 33)
|
||||||
|
{
|
||||||
|
textLabel.setText(aliasName.substring(0,30) + "...");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
textLabel.setText(aliasName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iconLabel.setIcon(null);
|
||||||
|
textLabel.setText(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iconLabel.setIcon(null);
|
||||||
|
textLabel.setText("-----");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Processes audio metadata to update this panel's display values
|
* Processes audio metadata to update this panel's display values
|
||||||
|
|||||||
@@ -33,8 +33,7 @@ public class AudioChannelsPanel extends JPanel
|
|||||||
|
|
||||||
public AudioChannelsPanel(IconManager iconManager, SettingsManager settingsManager, IAudioController controller)
|
public AudioChannelsPanel(IconManager iconManager, SettingsManager settingsManager, IAudioController controller)
|
||||||
{
|
{
|
||||||
// setLayout(new MigLayout("insets 0 0 0 0", "[][grow,fill][][grow,fill]", "[grow,fill]"));
|
setLayout(new MigLayout("insets 0 0 0 0", "[][sg abc,grow,fill][][sg abc,grow,fill]", "[grow,fill]"));
|
||||||
setLayout(new MigLayout("insets 0 0 0 0", "[][sg,grow,fill][][sg,grow,fill]", "[grow,fill]"));
|
|
||||||
|
|
||||||
setBackground(Color.BLACK);
|
setBackground(Color.BLACK);
|
||||||
|
|
||||||
@@ -44,7 +43,7 @@ public class AudioChannelsPanel extends JPanel
|
|||||||
|
|
||||||
for(int x = 0; x < outputs.size(); x++)
|
for(int x = 0; x < outputs.size(); x++)
|
||||||
{
|
{
|
||||||
add(new AudioChannelPanel(iconManager, settingsManager, outputs.get(x)), "growx");
|
add(new AudioChannelPanel(iconManager, settingsManager, outputs.get(x)));
|
||||||
|
|
||||||
if(x < outputs.size() - 1)
|
if(x < outputs.size() - 1)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -86,6 +86,9 @@ public class AudioManager implements Listener<AudioPacket>, IAudioController
|
|||||||
loadSettings();
|
loadSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the saved mixer configuration or a default configuration for audio playback.
|
||||||
|
*/
|
||||||
private void loadSettings()
|
private void loadSettings()
|
||||||
{
|
{
|
||||||
MixerChannelConfiguration configuration = null;
|
MixerChannelConfiguration configuration = null;
|
||||||
@@ -132,6 +135,9 @@ public class AudioManager implements Listener<AudioPacket>, IAudioController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a default audio playback configuration with a mono audio playback channel.
|
||||||
|
*/
|
||||||
private MixerChannelConfiguration getDefaultConfiguration()
|
private MixerChannelConfiguration getDefaultConfiguration()
|
||||||
{
|
{
|
||||||
/* Use the system default mixer and mono channel as default startup */
|
/* Use the system default mixer and mono channel as default startup */
|
||||||
@@ -161,6 +167,9 @@ public class AudioManager implements Listener<AudioPacket>, IAudioController
|
|||||||
mAudioOutputConnections.clear();
|
mAudioOutputConnections.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Primary ingest point for audio produced by all decoding channels, for distribution to audio playback devices.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public synchronized void receive(AudioPacket packet)
|
public synchronized void receive(AudioPacket packet)
|
||||||
{
|
{
|
||||||
@@ -176,11 +185,11 @@ public class AudioManager implements Listener<AudioPacket>, IAudioController
|
|||||||
|
|
||||||
for(AudioOutputConnection connection : mAudioOutputConnections)
|
for(AudioOutputConnection connection : mAudioOutputConnections)
|
||||||
{
|
{
|
||||||
if(connection.isInactive() &&
|
if(connection.isInactive() && mChannelConnectionMap.containsKey(connection.getChannelMetadataID()))
|
||||||
mChannelConnectionMap.containsKey(connection.getChannelMetadataID()))
|
|
||||||
{
|
{
|
||||||
mChannelConnectionMap.remove(connection.getChannelMetadataID());
|
mChannelConnectionMap.remove(connection.getChannelMetadataID());
|
||||||
connection.disconnect();
|
connection.disconnect();
|
||||||
|
mAvailableConnectionCount++;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -192,7 +201,7 @@ public class AudioManager implements Listener<AudioPacket>, IAudioController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identifies the lowest priority channel connection
|
* Identifies the lowest priority channel connection where the a higher value indicates a lower priority.
|
||||||
*/
|
*/
|
||||||
private void updateLowestPriorityAssignment()
|
private void updateLowestPriorityAssignment()
|
||||||
{
|
{
|
||||||
@@ -201,19 +210,32 @@ public class AudioManager implements Listener<AudioPacket>, IAudioController
|
|||||||
for(AudioOutputConnection connection : mAudioOutputConnections)
|
for(AudioOutputConnection connection : mAudioOutputConnections)
|
||||||
{
|
{
|
||||||
if(connection.isConnected() &&
|
if(connection.isConnected() &&
|
||||||
(mLowestPriorityConnection == null || mLowestPriorityConnection.getPriority() > connection.getPriority()))
|
(mLowestPriorityConnection == null || mLowestPriorityConnection.getPriority() < connection.getPriority()))
|
||||||
{
|
{
|
||||||
mLowestPriorityConnection = connection;
|
mLowestPriorityConnection = connection;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures audio playback to use the configuration specified in the entry argument.
|
||||||
|
*
|
||||||
|
* @param entry to use in configuring the audio playback setup.
|
||||||
|
* @throws AudioException if there is an error
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setMixerChannelConfiguration(MixerChannelConfiguration entry) throws AudioException
|
public void setMixerChannelConfiguration(MixerChannelConfiguration entry) throws AudioException
|
||||||
{
|
{
|
||||||
setMixerChannelConfiguration(entry, true);
|
setMixerChannelConfiguration(entry, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures audio playback to use the configuration specified in the entry argument.
|
||||||
|
*
|
||||||
|
* @param entry to use in configuring the audio playback setup.
|
||||||
|
* @param saveSettings to save the audio playback configuration settings in the properties file.
|
||||||
|
* @throws AudioException if there is an error
|
||||||
|
*/
|
||||||
public void setMixerChannelConfiguration(MixerChannelConfiguration entry, boolean saveSettings) throws AudioException
|
public void setMixerChannelConfiguration(MixerChannelConfiguration entry, boolean saveSettings) throws AudioException
|
||||||
{
|
{
|
||||||
if(entry != null && (entry.getMixerChannel() == MixerChannel.MONO || entry.getMixerChannel() == MixerChannel.STEREO))
|
if(entry != null && (entry.getMixerChannel() == MixerChannel.MONO || entry.getMixerChannel() == MixerChannel.STEREO))
|
||||||
@@ -266,9 +288,8 @@ public class AudioManager implements Listener<AudioPacket>, IAudioController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears all channel assignments and terminates all audio outputs in
|
* Clears all channel assignments and terminates all audio outputs in preparation for complete shutdown or change
|
||||||
* preparation for complete shutdown or change to another mixer/channel
|
* to another mixer/channel configuration
|
||||||
* configuration
|
|
||||||
*/
|
*/
|
||||||
private void disposeCurrentConfiguration()
|
private void disposeCurrentConfiguration()
|
||||||
{
|
{
|
||||||
@@ -288,12 +309,18 @@ public class AudioManager implements Listener<AudioPacket>, IAudioController
|
|||||||
mLowestPriorityConnection = null;
|
mLowestPriorityConnection = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current audio playback mixer channel configuration setting.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public MixerChannelConfiguration getMixerChannelConfiguration() throws AudioException
|
public MixerChannelConfiguration getMixerChannelConfiguration() throws AudioException
|
||||||
{
|
{
|
||||||
return mMixerChannelConfiguration;
|
return mMixerChannelConfiguration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of audio outputs available for the current mixer channel configuration
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<AudioOutput> getAudioOutputs()
|
public List<AudioOutput> getAudioOutputs()
|
||||||
{
|
{
|
||||||
@@ -311,12 +338,18 @@ public class AudioManager implements Listener<AudioPacket>, IAudioController
|
|||||||
return outputs;
|
return outputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an audio event listener to receive audio event notifications.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void addControllerListener(Listener<AudioEvent> listener)
|
public void addControllerListener(Listener<AudioEvent> listener)
|
||||||
{
|
{
|
||||||
mControllerBroadcaster.addListener(listener);
|
mControllerBroadcaster.addListener(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes an audio event listener from receiving audio event notifications.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void removeControllerListener(Listener<AudioEvent> listener)
|
public void removeControllerListener(Listener<AudioEvent> listener)
|
||||||
{
|
{
|
||||||
@@ -324,16 +357,15 @@ public class AudioManager implements Listener<AudioPacket>, IAudioController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an audio output connection for the packet if one is
|
* Returns an audio output connection for the packet if one is available, or overrides an existing lower priority
|
||||||
* available, or overrides an existing lower priority connection.
|
* connection. Returns null if no connection is available for the audio packet.
|
||||||
* Returns null if no connection is available for the audio packet.
|
|
||||||
*
|
*
|
||||||
* @param packet from a source
|
* @param audioPacket from a decoding channel source
|
||||||
* @return an audio output connection or null
|
* @return an audio output connection or null
|
||||||
*/
|
*/
|
||||||
private AudioOutputConnection getConnection(AudioPacket packet)
|
private AudioOutputConnection getConnection(AudioPacket audioPacket)
|
||||||
{
|
{
|
||||||
int channelMetadataID = packet.getMetadata().getMetadataID();
|
int channelMetadataID = audioPacket.getMetadata().getMetadataID();
|
||||||
|
|
||||||
//Use an existing connection
|
//Use an existing connection
|
||||||
if(mChannelConnectionMap.containsKey(channelMetadataID))
|
if(mChannelConnectionMap.containsKey(channelMetadataID))
|
||||||
@@ -341,37 +373,35 @@ public class AudioManager implements Listener<AudioPacket>, IAudioController
|
|||||||
return mChannelConnectionMap.get(channelMetadataID);
|
return mChannelConnectionMap.get(channelMetadataID);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Connect to and use an available connection
|
//Connect to an unused, available connection
|
||||||
if(mAvailableConnectionCount > 0)
|
if(mAvailableConnectionCount > 0)
|
||||||
{
|
{
|
||||||
for(AudioOutputConnection connection : mAudioOutputConnections)
|
for(AudioOutputConnection connection : mAudioOutputConnections)
|
||||||
{
|
{
|
||||||
if(connection.isDisconnected())
|
if(connection.isDisconnected())
|
||||||
{
|
{
|
||||||
connection.connect(channelMetadataID);
|
connection.connect(channelMetadataID, audioPacket.getMetadata().getAudioPriority());
|
||||||
mChannelConnectionMap.put(channelMetadataID, connection);
|
mChannelConnectionMap.put(channelMetadataID, connection);
|
||||||
|
mAvailableConnectionCount--;
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Preempt an existing connection and connect it to this higher priority source
|
//Preempt an existing lower priority connection and connect when this is a higher priority packet
|
||||||
else //Check for a channel priority override
|
else
|
||||||
{
|
{
|
||||||
int priority = packet.getMetadata().getAudioPriority();
|
int priority = audioPacket.getMetadata().getAudioPriority();
|
||||||
|
|
||||||
if(mLowestPriorityConnection != null &&
|
|
||||||
priority < mLowestPriorityConnection.getPriority())
|
|
||||||
{
|
|
||||||
AudioOutputConnection connection = mLowestPriorityConnection;
|
AudioOutputConnection connection = mLowestPriorityConnection;
|
||||||
|
|
||||||
|
if(connection != null && priority < connection.getPriority())
|
||||||
|
{
|
||||||
mChannelConnectionMap.remove(connection.getChannelMetadataID());
|
mChannelConnectionMap.remove(connection.getChannelMetadataID());
|
||||||
|
|
||||||
connection.connect(channelMetadataID);
|
connection.connect(channelMetadataID, priority);
|
||||||
|
|
||||||
mChannelConnectionMap.put(channelMetadataID, connection);
|
mChannelConnectionMap.put(channelMetadataID, connection);
|
||||||
|
|
||||||
updateLowestPriorityAssignment();
|
|
||||||
|
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -494,9 +524,11 @@ public class AudioManager implements Listener<AudioPacket>, IAudioController
|
|||||||
* Connects this assignment to the indicated source so that audio
|
* Connects this assignment to the indicated source so that audio
|
||||||
* packets from this source can be sent to the audio output
|
* packets from this source can be sent to the audio output
|
||||||
*/
|
*/
|
||||||
public void connect(int source)
|
public void connect(int source, int priority)
|
||||||
{
|
{
|
||||||
mChannelMetadataID = source;
|
mChannelMetadataID = source;
|
||||||
|
mPriority = priority;
|
||||||
|
updateLowestPriorityAssignment();
|
||||||
|
|
||||||
mAudioOutput.updateTimestamp();
|
mAudioOutput.updateTimestamp();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
public class ChannelMetadataModel extends AbstractTableModel implements Listener<MutableMetadataChangeEvent>
|
public class ChannelMetadataModel extends AbstractTableModel implements Listener<MutableMetadataChangeEvent>
|
||||||
{
|
{
|
||||||
private final DecimalFormat FREQUENCY_FORMATTER = new DecimalFormat( "#.0000" );
|
private final DecimalFormat FREQUENCY_FORMATTER = new DecimalFormat( "#.00000" );
|
||||||
|
|
||||||
public static final int COLUMN_STATE = 0;
|
public static final int COLUMN_STATE = 0;
|
||||||
public static final int COLUMN_DECODER = 1;
|
public static final int COLUMN_DECODER = 1;
|
||||||
|
|||||||
@@ -36,14 +36,19 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import sample.Listener;
|
import sample.Listener;
|
||||||
import sample.real.IOverflowListener;
|
import sample.real.IOverflowListener;
|
||||||
|
import source.tuner.frequency.FrequencyChangeEvent;
|
||||||
|
import source.tuner.frequency.IFrequencyChangeListener;
|
||||||
|
|
||||||
import java.util.concurrent.RejectedExecutionException;
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static source.tuner.frequency.FrequencyChangeEvent.Event.NOTIFICATION_FREQUENCY_CHANGE;
|
||||||
|
|
||||||
public class ChannelState extends Module implements ICallEventProvider, IDecoderStateEventListener,
|
public class ChannelState extends Module implements ICallEventProvider, IDecoderStateEventListener,
|
||||||
IDecoderStateEventProvider, ISquelchStateProvider, IAttributeChangeRequestListener, IOverflowListener
|
IDecoderStateEventProvider, IFrequencyChangeListener, ISquelchStateProvider, IAttributeChangeRequestListener,
|
||||||
|
IOverflowListener
|
||||||
{
|
{
|
||||||
private final static Logger mLog = LoggerFactory.getLogger(ChannelState.class);
|
private final static Logger mLog = LoggerFactory.getLogger(ChannelState.class);
|
||||||
|
|
||||||
@@ -61,6 +66,7 @@ public class ChannelState extends Module implements ICallEventProvider, IDecoder
|
|||||||
private ChannelType mChannelType;
|
private ChannelType mChannelType;
|
||||||
private TrafficChannelManager mTrafficChannelEndListener;
|
private TrafficChannelManager mTrafficChannelEndListener;
|
||||||
private CallEvent mTrafficChannelCallEvent;
|
private CallEvent mTrafficChannelCallEvent;
|
||||||
|
private FrequencyChangeListener mFrequencyChangeListener;
|
||||||
|
|
||||||
private boolean mSquelchLocked = false;
|
private boolean mSquelchLocked = false;
|
||||||
private boolean mSelected = false;
|
private boolean mSelected = false;
|
||||||
@@ -189,6 +195,17 @@ public class ChannelState extends Module implements ICallEventProvider, IDecoder
|
|||||||
mStateMonitor = null;
|
mStateMonitor = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Listener<FrequencyChangeEvent> getFrequencyChangeListener()
|
||||||
|
{
|
||||||
|
if(mFrequencyChangeListener == null)
|
||||||
|
{
|
||||||
|
mFrequencyChangeListener = new FrequencyChangeListener();
|
||||||
|
}
|
||||||
|
|
||||||
|
return mFrequencyChangeListener;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isStandardChannel()
|
private boolean isStandardChannel()
|
||||||
{
|
{
|
||||||
return mChannelType == ChannelType.STANDARD;
|
return mChannelType == ChannelType.STANDARD;
|
||||||
@@ -532,6 +549,23 @@ public class ChannelState extends Module implements ICallEventProvider, IDecoder
|
|||||||
broadcast(mTrafficChannelCallEvent);
|
broadcast(mTrafficChannelCallEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener to receive frequency change events and rebroadcast them to the decoder states
|
||||||
|
*/
|
||||||
|
public class FrequencyChangeListener implements Listener<FrequencyChangeEvent>
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void receive(FrequencyChangeEvent frequencyChangeEvent)
|
||||||
|
{
|
||||||
|
if(frequencyChangeEvent.getEvent() == NOTIFICATION_FREQUENCY_CHANGE)
|
||||||
|
{
|
||||||
|
long frequency = frequencyChangeEvent.getValue().longValue();
|
||||||
|
|
||||||
|
broadcast(new DecoderStateEvent(this, Event.SOURCE_FREQUENCY, getState(), frequency));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DecoderStateEvent receiver wrapper
|
* DecoderStateEvent receiver wrapper
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -63,13 +63,11 @@ public class TrafficChannelManager extends Module implements ICallEventProvider,
|
|||||||
private Listener<CallEvent> mCallEventListener;
|
private Listener<CallEvent> mCallEventListener;
|
||||||
|
|
||||||
private ChannelModel mChannelModel;
|
private ChannelModel mChannelModel;
|
||||||
private ChannelProcessingManager mChannelProcessingManager;
|
|
||||||
private DecodeConfiguration mDecodeConfiguration;
|
private DecodeConfiguration mDecodeConfiguration;
|
||||||
private RecordConfiguration mRecordConfiguration;
|
private RecordConfiguration mRecordConfiguration;
|
||||||
private String mSystem;
|
private String mSystem;
|
||||||
private String mSite;
|
private String mSite;
|
||||||
private String mAliasListName;
|
private String mAliasListName;
|
||||||
private CallEvent mPreviousDoNotMonitorCallEvent;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Monitors call events and allocates traffic decoder channels in response
|
* Monitors call events and allocates traffic decoder channels in response
|
||||||
@@ -77,7 +75,6 @@ public class TrafficChannelManager extends Module implements ICallEventProvider,
|
|||||||
* traffic channel allocations.
|
* traffic channel allocations.
|
||||||
*
|
*
|
||||||
* @param channelModel containing channels currently in use
|
* @param channelModel containing channels currently in use
|
||||||
* @param channelProcessingManager
|
|
||||||
* @param decodeConfiguration - decoder configuration to use for each
|
* @param decodeConfiguration - decoder configuration to use for each
|
||||||
* traffic channel allocation.
|
* traffic channel allocation.
|
||||||
* @param recordConfiguration - recording options for each traffic channel
|
* @param recordConfiguration - recording options for each traffic channel
|
||||||
@@ -88,7 +85,6 @@ public class TrafficChannelManager extends Module implements ICallEventProvider,
|
|||||||
* in the pool
|
* in the pool
|
||||||
*/
|
*/
|
||||||
public TrafficChannelManager(ChannelModel channelModel,
|
public TrafficChannelManager(ChannelModel channelModel,
|
||||||
ChannelProcessingManager channelProcessingManager,
|
|
||||||
DecodeConfiguration decodeConfiguration,
|
DecodeConfiguration decodeConfiguration,
|
||||||
RecordConfiguration recordConfiguration,
|
RecordConfiguration recordConfiguration,
|
||||||
String system,
|
String system,
|
||||||
@@ -97,7 +93,6 @@ public class TrafficChannelManager extends Module implements ICallEventProvider,
|
|||||||
int trafficChannelPoolSize)
|
int trafficChannelPoolSize)
|
||||||
{
|
{
|
||||||
mChannelModel = channelModel;
|
mChannelModel = channelModel;
|
||||||
mChannelProcessingManager = channelProcessingManager;
|
|
||||||
mDecodeConfiguration = decodeConfiguration;
|
mDecodeConfiguration = decodeConfiguration;
|
||||||
mRecordConfiguration = recordConfiguration;
|
mRecordConfiguration = recordConfiguration;
|
||||||
mSystem = system;
|
mSystem = system;
|
||||||
@@ -120,7 +115,6 @@ public class TrafficChannelManager extends Module implements ICallEventProvider,
|
|||||||
|
|
||||||
mCallEventListener = null;
|
mCallEventListener = null;
|
||||||
mDecodeConfiguration = null;
|
mDecodeConfiguration = null;
|
||||||
mPreviousDoNotMonitorCallEvent = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -197,21 +191,7 @@ public class TrafficChannelManager extends Module implements ICallEventProvider,
|
|||||||
|
|
||||||
long frequency = callEvent.getFrequency();
|
long frequency = callEvent.getFrequency();
|
||||||
|
|
||||||
/* Check the from/to aliases for do not monitor priority */
|
if(frequency > 0)
|
||||||
if(isDoNotMonitor(callEvent))
|
|
||||||
{
|
|
||||||
callEvent.setCallEventType(CallEventType.CALL_DO_NOT_MONITOR);
|
|
||||||
|
|
||||||
if(isSameCallEvent(mPreviousDoNotMonitorCallEvent, callEvent))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mPreviousDoNotMonitorCallEvent = callEvent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(frequency > 0)
|
|
||||||
{
|
{
|
||||||
Channel channel = getChannel(callEvent.getChannel(), new TunerChannel(Type.TRAFFIC,
|
Channel channel = getChannel(callEvent.getChannel(), new TunerChannel(Type.TRAFFIC,
|
||||||
frequency, mDecodeConfiguration.getDecoderType().getChannelBandwidth()));
|
frequency, mDecodeConfiguration.getDecoderType().getChannelBandwidth()));
|
||||||
@@ -330,31 +310,6 @@ public class TrafficChannelManager extends Module implements ICallEventProvider,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks for aliases that contain a do not follow/process priority.
|
|
||||||
*
|
|
||||||
* @param event
|
|
||||||
* @return - true if there is an alias that has a do not process alias id
|
|
||||||
*/
|
|
||||||
private boolean isDoNotMonitor(CallEvent event)
|
|
||||||
{
|
|
||||||
Alias to = event.getToIDAlias();
|
|
||||||
|
|
||||||
if(to != null && to.hasCallPriority() && to.getCallPriority() == Priority.DO_NOT_MONITOR)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Alias from = event.getFromIDAlias();
|
|
||||||
|
|
||||||
if(from != null && from.hasCallPriority() && from.getCallPriority() == Priority.DO_NOT_MONITOR)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Listener<DecoderStateEvent> getDecoderStateListener()
|
public Listener<DecoderStateEvent> getDecoderStateListener()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* SDR Trunk
|
* sdrtrunk
|
||||||
* Copyright (C) 2014-2016 Dennis Sheirer
|
* Copyright (C) 2014-2017 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -14,15 +14,11 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package controller.channel;
|
package controller.channel;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlAttribute;
|
import controller.config.Configuration;
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
|
||||||
import javax.xml.bind.annotation.XmlSeeAlso;
|
|
||||||
import javax.xml.bind.annotation.XmlTransient;
|
|
||||||
|
|
||||||
import module.decode.DecoderFactory;
|
import module.decode.DecoderFactory;
|
||||||
import module.decode.DecoderType;
|
import module.decode.DecoderType;
|
||||||
import module.decode.config.AuxDecodeConfiguration;
|
import module.decode.config.AuxDecodeConfiguration;
|
||||||
@@ -31,6 +27,7 @@ import module.log.EventLogType;
|
|||||||
import module.log.config.EventLogConfiguration;
|
import module.log.config.EventLogConfiguration;
|
||||||
import record.RecorderType;
|
import record.RecorderType;
|
||||||
import record.config.RecordConfiguration;
|
import record.config.RecordConfiguration;
|
||||||
|
import sample.Listener;
|
||||||
import source.SourceType;
|
import source.SourceType;
|
||||||
import source.config.SourceConfigFactory;
|
import source.config.SourceConfigFactory;
|
||||||
import source.config.SourceConfigRecording;
|
import source.config.SourceConfigRecording;
|
||||||
@@ -40,15 +37,24 @@ import source.tuner.TunerChannel;
|
|||||||
import source.tuner.TunerChannel.Type;
|
import source.tuner.TunerChannel.Type;
|
||||||
import source.tuner.frequency.FrequencyChangeEvent;
|
import source.tuner.frequency.FrequencyChangeEvent;
|
||||||
import source.tuner.frequency.FrequencyChangeEvent.Event;
|
import source.tuner.frequency.FrequencyChangeEvent.Event;
|
||||||
import source.tuner.frequency.IFrequencyChangeProcessor;
|
|
||||||
import controller.config.Configuration;
|
import javax.xml.bind.annotation.XmlAttribute;
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
import javax.xml.bind.annotation.XmlSeeAlso;
|
||||||
|
import javax.xml.bind.annotation.XmlTransient;
|
||||||
|
|
||||||
@XmlSeeAlso({Configuration.class})
|
@XmlSeeAlso({Configuration.class})
|
||||||
@XmlRootElement(name = "channel")
|
@XmlRootElement(name = "channel")
|
||||||
public class Channel extends Configuration implements IFrequencyChangeProcessor
|
public class Channel extends Configuration implements Listener<FrequencyChangeEvent>
|
||||||
{
|
{
|
||||||
// Standard channels are persisted and traffic channels are temporary
|
// Standard channels are persisted and traffic channels are temporary
|
||||||
public enum ChannelType { STANDARD, TRAFFIC };
|
public enum ChannelType
|
||||||
|
{
|
||||||
|
STANDARD, TRAFFIC
|
||||||
|
}
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
// Static unique channel identifier tracking
|
// Static unique channel identifier tracking
|
||||||
@@ -278,7 +284,7 @@ public class Channel extends Configuration implements IFrequencyChangeProcessor
|
|||||||
* Note: this method is package private and is intended to be managed
|
* Note: this method is package private and is intended to be managed
|
||||||
* by a co-package central processing manager
|
* by a co-package central processing manager
|
||||||
*
|
*
|
||||||
* @see controller.ChannelProcessingManager
|
* @see controller.channel.ChannelProcessingManager
|
||||||
*/
|
*/
|
||||||
void setEnabled(boolean enabled)
|
void setEnabled(boolean enabled)
|
||||||
{
|
{
|
||||||
@@ -436,8 +442,7 @@ public class Channel extends Configuration implements IFrequencyChangeProcessor
|
|||||||
{
|
{
|
||||||
TunerChannel tunerChannel = getTunerChannel();
|
TunerChannel tunerChannel = getTunerChannel();
|
||||||
|
|
||||||
return tunerChannel != null &&
|
return tunerChannel != null && tunerChannel.overlaps(minimum, maximum);
|
||||||
tunerChannel.overlaps( minimum, maximum );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -447,7 +452,7 @@ public class Channel extends Configuration implements IFrequencyChangeProcessor
|
|||||||
* be used to visually show in the spectral display.
|
* be used to visually show in the spectral display.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void frequencyChanged( FrequencyChangeEvent event )
|
public void receive(FrequencyChangeEvent event)
|
||||||
{
|
{
|
||||||
if(event.getEvent() == Event.NOTIFICATION_CHANNEL_FREQUENCY_CORRECTION_CHANGE)
|
if(event.getEvent() == Event.NOTIFICATION_CHANNEL_FREQUENCY_CORRECTION_CHANGE)
|
||||||
{
|
{
|
||||||
@@ -455,9 +460,21 @@ public class Channel extends Configuration implements IFrequencyChangeProcessor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current channel frequency correction value (when this channel is processing)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
@XmlTransient
|
@XmlTransient
|
||||||
public int getChannelFrequencyCorrection()
|
public int getChannelFrequencyCorrection()
|
||||||
{
|
{
|
||||||
return mChannelFrequencyCorrection;
|
return mChannelFrequencyCorrection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets frequency correction value to 0
|
||||||
|
*/
|
||||||
|
public void resetFrequencyCorrection()
|
||||||
|
{
|
||||||
|
mChannelFrequencyCorrection = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -231,7 +231,7 @@ public class ChannelProcessingManager implements ChannelEventListener
|
|||||||
|
|
||||||
if(processingChain == null)
|
if(processingChain == null)
|
||||||
{
|
{
|
||||||
processingChain = new ProcessingChain(channel.getName(), channel.getChannelType());
|
processingChain = new ProcessingChain(channel.getChannelType());
|
||||||
|
|
||||||
/* Register global listeners */
|
/* Register global listeners */
|
||||||
for(Listener<AudioPacket> listener : mAudioPacketListeners)
|
for(Listener<AudioPacket> listener : mAudioPacketListeners)
|
||||||
@@ -244,6 +244,9 @@ public class ChannelProcessingManager implements ChannelEventListener
|
|||||||
processingChain.addMessageListener(listener);
|
processingChain.addMessageListener(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Register channel to receive frequency correction events to show in the spectral display (hack!)
|
||||||
|
processingChain.addFrequencyChangeListener(channel);
|
||||||
|
|
||||||
/* Processing Modules */
|
/* Processing Modules */
|
||||||
List<Module> modules = DecoderFactory.getModules(mChannelModel, mChannelMapModel, this,
|
List<Module> modules = DecoderFactory.getModules(mChannelModel, mChannelMapModel, this,
|
||||||
mAliasModel, channel, processingChain.getChannelState().getMutableMetadata());
|
mAliasModel, channel, processingChain.getChannelState().getMutableMetadata());
|
||||||
@@ -347,6 +350,9 @@ public class ChannelProcessingManager implements ChannelEventListener
|
|||||||
|
|
||||||
processingChain.removeRecordingModules();
|
processingChain.removeRecordingModules();
|
||||||
|
|
||||||
|
//Deregister channel from receive frequency correction events to show in the spectral display (hack!)
|
||||||
|
processingChain.removeFrequencyChangeListener(channel);
|
||||||
|
channel.resetFrequencyCorrection();
|
||||||
|
|
||||||
mChannelModel.broadcast(new ChannelEvent(channel, Event.NOTIFICATION_PROCESSING_STOP));
|
mChannelModel.broadcast(new ChannelEvent(channel, Event.NOTIFICATION_PROCESSING_STOP));
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* SDR Trunk
|
* sdrtrunk
|
||||||
* Copyright (C) 2015 Dennis Sheirer
|
* Copyright (C) 2014-2017 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -14,23 +14,24 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package dsp.filter.cic;
|
package dsp.filter.cic;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import dsp.filter.FilterFactory;
|
||||||
import java.util.List;
|
import dsp.filter.Filters;
|
||||||
|
import dsp.filter.Window.WindowType;
|
||||||
|
import dsp.filter.fir.complex.ComplexFIRFilter_CB_CB;
|
||||||
|
import dsp.filter.halfband.complex.HalfBandFilter_CB_CB;
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
import sample.Listener;
|
import sample.Listener;
|
||||||
import sample.complex.ComplexBuffer;
|
import sample.complex.ComplexBuffer;
|
||||||
import sample.complex.ComplexSampleListener;
|
import sample.complex.ComplexSampleListener;
|
||||||
import sample.complex.ComplexToComplexBufferAssembler;
|
import sample.complex.ComplexToComplexBufferAssembler;
|
||||||
import sample.decimator.ComplexDecimator;
|
import sample.decimator.ComplexDecimator;
|
||||||
import dsp.filter.FilterFactory;
|
|
||||||
import dsp.filter.Filters;
|
import java.util.ArrayList;
|
||||||
import dsp.filter.Window.WindowType;
|
import java.util.List;
|
||||||
import dsp.filter.fir.complex.ComplexFIRFilter_CB_CB;
|
|
||||||
import dsp.filter.halfband.complex.HalfBandFilter_CB_CB;
|
|
||||||
|
|
||||||
public class ComplexPrimeCICDecimate implements Listener<ComplexBuffer>
|
public class ComplexPrimeCICDecimate implements Listener<ComplexBuffer>
|
||||||
{
|
{
|
||||||
@@ -367,8 +368,11 @@ public class ComplexPrimeCICDecimate implements Listener<ComplexBuffer>
|
|||||||
attenuation,
|
attenuation,
|
||||||
windowType), 0.4f);
|
windowType), 0.4f);
|
||||||
|
|
||||||
mAssembler.setListener( mCleanupFilter );
|
//Bypassing the CIC cleanup filter for now
|
||||||
mCleanupFilter.setListener( mHalfBandFilter );
|
mAssembler.setListener(mHalfBandFilter);
|
||||||
|
|
||||||
|
// mAssembler.setListener( mCleanupFilter );
|
||||||
|
// mCleanupFilter.setListener( mHalfBandFilter );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dispose()
|
public void dispose()
|
||||||
|
|||||||
@@ -1,21 +1,38 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* sdrtrunk
|
||||||
|
* Copyright (C) 2014-2017 Dennis Sheirer
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
package instrument;
|
package instrument;
|
||||||
|
|
||||||
|
import controller.channel.Channel.ChannelType;
|
||||||
import instrument.tap.Tap;
|
import instrument.tap.Tap;
|
||||||
import instrument.tap.TapGroup;
|
import instrument.tap.TapGroup;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import module.Module;
|
import module.Module;
|
||||||
import module.ProcessingChain;
|
import module.ProcessingChain;
|
||||||
import source.Source;
|
import source.Source;
|
||||||
import controller.channel.Channel.ChannelType;
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class InstrumentableProcessingChain extends ProcessingChain implements Instrumentable
|
public class InstrumentableProcessingChain extends ProcessingChain implements Instrumentable
|
||||||
{
|
{
|
||||||
public InstrumentableProcessingChain()
|
public InstrumentableProcessingChain()
|
||||||
{
|
{
|
||||||
super( "instrumented", ChannelType.STANDARD );
|
super(ChannelType.STANDARD);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSource(Source source) throws IllegalStateException
|
public void setSource(Source source) throws IllegalStateException
|
||||||
|
|||||||
@@ -108,7 +108,6 @@ public class ProcessingChain implements IChannelEventListener
|
|||||||
private Broadcaster<RealBuffer> mUnFilteredRealBufferBroadcaster = new Broadcaster<>();
|
private Broadcaster<RealBuffer> mUnFilteredRealBufferBroadcaster = new Broadcaster<>();
|
||||||
private Broadcaster<SquelchState> mSquelchStateBroadcaster = new Broadcaster<>();
|
private Broadcaster<SquelchState> mSquelchStateBroadcaster = new Broadcaster<>();
|
||||||
|
|
||||||
private String mName;
|
|
||||||
private AtomicBoolean mRunning = new AtomicBoolean();
|
private AtomicBoolean mRunning = new AtomicBoolean();
|
||||||
|
|
||||||
protected Source mSource;
|
protected Source mSource;
|
||||||
@@ -120,13 +119,10 @@ public class ProcessingChain implements IChannelEventListener
|
|||||||
/**
|
/**
|
||||||
* Creates a processing chain for managing a set of modules
|
* Creates a processing chain for managing a set of modules
|
||||||
*
|
*
|
||||||
* @param name for thread pool naming each thread
|
|
||||||
* @param channelType
|
* @param channelType
|
||||||
*/
|
*/
|
||||||
public ProcessingChain(String name, ChannelType channelType)
|
public ProcessingChain(ChannelType channelType)
|
||||||
{
|
{
|
||||||
mName = name;
|
|
||||||
|
|
||||||
mChannelState = new ChannelState(channelType);
|
mChannelState = new ChannelState(channelType);
|
||||||
addModule(mChannelState);
|
addModule(mChannelState);
|
||||||
|
|
||||||
@@ -211,6 +207,8 @@ public class ProcessingChain implements IChannelEventListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
mSource = source;
|
mSource = source;
|
||||||
|
|
||||||
|
addModule(mSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -322,7 +320,13 @@ public class ProcessingChain implements IChannelEventListener
|
|||||||
|
|
||||||
if(module instanceof IFrequencyChangeListener)
|
if(module instanceof IFrequencyChangeListener)
|
||||||
{
|
{
|
||||||
mFrequencyChangeEventBroadcaster.addListener(((IFrequencyChangeListener) module).getFrequencyChangeListener());
|
Listener<FrequencyChangeEvent> frequencyChangeEventListener =
|
||||||
|
((IFrequencyChangeListener)module).getFrequencyChangeListener();
|
||||||
|
|
||||||
|
if(frequencyChangeEventListener != null)
|
||||||
|
{
|
||||||
|
mFrequencyChangeEventBroadcaster.addListener(frequencyChangeEventListener);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(module instanceof IMessageListener)
|
if(module instanceof IMessageListener)
|
||||||
@@ -557,25 +561,6 @@ public class ProcessingChain implements IChannelEventListener
|
|||||||
+ "sample type - cannot start processing chain");
|
+ "sample type - cannot start processing chain");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If this is a tuner source, broadcast the frequency to all
|
|
||||||
* of the decoder state's and start the samples flowing */
|
|
||||||
if(mSource instanceof TunerChannelSource)
|
|
||||||
{
|
|
||||||
TunerChannelSource tcs = (TunerChannelSource) mSource;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
long frequency = tcs.getFrequency();
|
|
||||||
|
|
||||||
mDecoderStateEventBroadcaster.broadcast(
|
|
||||||
new DecoderStateEvent(this, Event.SOURCE_FREQUENCY, State.IDLE, frequency));
|
|
||||||
}
|
|
||||||
catch(SourceException e)
|
|
||||||
{
|
|
||||||
mLog.error("Error getting frequency from tuner channel source", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Start each of the modules */
|
/* Start each of the modules */
|
||||||
for(Module module : mModules)
|
for(Module module : mModules)
|
||||||
{
|
{
|
||||||
@@ -588,8 +573,6 @@ public class ProcessingChain implements IChannelEventListener
|
|||||||
mLog.error("Error starting module", e);
|
mLog.error("Error starting module", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mSource.start(ThreadPool.SCHEDULED);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -606,9 +589,16 @@ public class ProcessingChain implements IChannelEventListener
|
|||||||
{
|
{
|
||||||
if(mRunning.compareAndSet(true, false))
|
if(mRunning.compareAndSet(true, false))
|
||||||
{
|
{
|
||||||
|
/* Stop each of the modules */
|
||||||
|
for(Module module : mModules)
|
||||||
|
{
|
||||||
|
module.stop();
|
||||||
|
}
|
||||||
|
|
||||||
if(mSource != null)
|
if(mSource != null)
|
||||||
{
|
{
|
||||||
mSource.stop();
|
removeModule(mSource);
|
||||||
|
|
||||||
mSource.setOverflowListener(null);
|
mSource.setOverflowListener(null);
|
||||||
|
|
||||||
switch(mSource.getSampleType())
|
switch(mSource.getSampleType())
|
||||||
@@ -629,11 +619,6 @@ public class ProcessingChain implements IChannelEventListener
|
|||||||
mSource = null;
|
mSource = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stop each of the modules */
|
|
||||||
for(Module module : mModules)
|
|
||||||
{
|
|
||||||
module.stop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -760,6 +745,24 @@ public class ProcessingChain implements IChannelEventListener
|
|||||||
mMessageBroadcaster.removeListener(listener);
|
mMessageBroadcaster.removeListener(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the listener to receive frequency change events from the processing chain
|
||||||
|
* @param listener to receive events
|
||||||
|
*/
|
||||||
|
public void addFrequencyChangeListener(Listener<FrequencyChangeEvent> listener)
|
||||||
|
{
|
||||||
|
mFrequencyChangeEventBroadcaster.addListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the listener from receiving frequency change events
|
||||||
|
* @param listener to remove
|
||||||
|
*/
|
||||||
|
public void removeFrequencyChangeListener(Listener<FrequencyChangeEvent> listener)
|
||||||
|
{
|
||||||
|
mFrequencyChangeEventBroadcaster.removeListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the listener to receive call events from all modules.
|
* Adds the listener to receive call events from all modules.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ public class DecoderFactory
|
|||||||
|
|
||||||
if(channelType == ChannelType.STANDARD)
|
if(channelType == ChannelType.STANDARD)
|
||||||
{
|
{
|
||||||
modules.add(new TrafficChannelManager(channelModel, channelProcessingManager, decodeConfig,
|
modules.add(new TrafficChannelManager(channelModel, decodeConfig,
|
||||||
channel.getRecordConfiguration(), channel.getSystem(), channel.getSite(),
|
channel.getRecordConfiguration(), channel.getSystem(), channel.getSite(),
|
||||||
(aliasList != null ? aliasList.getName() : null), mptConfig.getTrafficChannelPoolSize()));
|
(aliasList != null ? aliasList.getName() : null), mptConfig.getTrafficChannelPoolSize()));
|
||||||
}
|
}
|
||||||
@@ -263,7 +263,7 @@ public class DecoderFactory
|
|||||||
|
|
||||||
if(channelType == ChannelType.STANDARD)
|
if(channelType == ChannelType.STANDARD)
|
||||||
{
|
{
|
||||||
modules.add(new TrafficChannelManager(channelModel, channelProcessingManager, decodeConfig,
|
modules.add(new TrafficChannelManager(channelModel, decodeConfig,
|
||||||
channel.getRecordConfiguration(), channel.getSystem(), channel.getSite(),
|
channel.getRecordConfiguration(), channel.getSystem(), channel.getSite(),
|
||||||
(aliasList != null ? aliasList.getName() : null), p25Config.getTrafficChannelPoolSize()));
|
(aliasList != null ? aliasList.getName() : null), p25Config.getTrafficChannelPoolSize()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public class LJ1200DecoderState extends DecoderState
|
|||||||
super(aliasList);
|
super(aliasList);
|
||||||
|
|
||||||
mAddressAttribute = new AliasedStringAttributeMonitor(Attribute.SECONDARY_ADDRESS_TO,
|
mAddressAttribute = new AliasedStringAttributeMonitor(Attribute.SECONDARY_ADDRESS_TO,
|
||||||
getAttributeChangeRequestListener(), getAliasList(), AliasIDType.LOJACK);
|
getAttributeChangeRequestListener(), getAliasList(), AliasIDType.SITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -9,19 +9,19 @@ import instrument.tap.stream.FloatTap;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import sample.Listener;
|
import sample.Listener;
|
||||||
import sample.real.RealBuffer;
|
import sample.real.RealBuffer;
|
||||||
import sample.real.RealSampleListener;
|
import sample.real.RealSampleListener;
|
||||||
import sample.real.RealSampleProvider;
|
import sample.real.RealSampleProvider;
|
||||||
|
import source.tuner.TunerChannelSource;
|
||||||
import source.tuner.frequency.FrequencyChangeEvent;
|
import source.tuner.frequency.FrequencyChangeEvent;
|
||||||
import source.tuner.frequency.FrequencyChangeEvent.Event;
|
import source.tuner.frequency.FrequencyChangeEvent.Event;
|
||||||
import source.tuner.frequency.IFrequencyChangeListener;
|
import source.tuner.frequency.IFrequencyChangeListener;
|
||||||
import dsp.gain.DirectGainControl;
|
import dsp.gain.DirectGainControl;
|
||||||
|
|
||||||
public class C4FMSymbolFilter implements Listener<RealBuffer>,
|
public class C4FMSymbolFilter implements Listener<RealBuffer>, IFrequencyChangeListener, RealSampleProvider, Instrumentable
|
||||||
IFrequencyChangeListener,
|
|
||||||
RealSampleProvider,
|
|
||||||
Instrumentable
|
|
||||||
{
|
{
|
||||||
private static final float TAPS[][] =
|
private static final float TAPS[][] =
|
||||||
{
|
{
|
||||||
@@ -198,8 +198,7 @@ public class C4FMSymbolFilter implements Listener<RealBuffer>,
|
|||||||
|
|
||||||
private RealSampleListener mListener;
|
private RealSampleListener mListener;
|
||||||
|
|
||||||
private DirectGainControl mGainController =
|
private DirectGainControl mGainController = new DirectGainControl( 15.0f, 0.1f, 35.0f, 0.3f );
|
||||||
new DirectGainControl( 15.0f, 0.1f, 35.0f, 0.3f );
|
|
||||||
|
|
||||||
private int mFrequencyAdjustmentRequested = 0;
|
private int mFrequencyAdjustmentRequested = 0;
|
||||||
private int mFrequencyCorrection = 0;
|
private int mFrequencyCorrection = 0;
|
||||||
@@ -258,8 +257,7 @@ public class C4FMSymbolFilter implements Listener<RealBuffer>,
|
|||||||
correction = -mFrequencyCorrectionMaximum;
|
correction = -mFrequencyCorrectionMaximum;
|
||||||
}
|
}
|
||||||
|
|
||||||
broadcast( new FrequencyChangeEvent(
|
broadcast( new FrequencyChangeEvent(Event.REQUEST_CHANNEL_FREQUENCY_CORRECTION_CHANGE, correction ) );
|
||||||
Event.REQUEST_CHANNEL_FREQUENCY_CORRECTION_CHANGE, correction ) );
|
|
||||||
|
|
||||||
mFrequencyAdjustmentRequested = 0;
|
mFrequencyAdjustmentRequested = 0;
|
||||||
}
|
}
|
||||||
@@ -452,6 +450,10 @@ public class C4FMSymbolFilter implements Listener<RealBuffer>,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Broadcasts a frequency change event to the registered listener
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
public void broadcast( FrequencyChangeEvent event )
|
public void broadcast( FrequencyChangeEvent event )
|
||||||
{
|
{
|
||||||
if( mFrequencyChangeListener != null )
|
if( mFrequencyChangeListener != null )
|
||||||
@@ -460,6 +462,10 @@ public class C4FMSymbolFilter implements Listener<RealBuffer>,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the listener for frequency change events.
|
||||||
|
* @param listener
|
||||||
|
*/
|
||||||
public void setFrequencyChangeListener( Listener<FrequencyChangeEvent> listener )
|
public void setFrequencyChangeListener( Listener<FrequencyChangeEvent> listener )
|
||||||
{
|
{
|
||||||
mFrequencyChangeListener = listener;
|
mFrequencyChangeListener = listener;
|
||||||
|
|||||||
@@ -4,8 +4,10 @@ import alias.AliasList;
|
|||||||
import instrument.Instrumentable;
|
import instrument.Instrumentable;
|
||||||
import module.decode.Decoder;
|
import module.decode.Decoder;
|
||||||
import module.decode.DecoderType;
|
import module.decode.DecoderType;
|
||||||
|
import source.tuner.frequency.IFrequencyChangeListener;
|
||||||
|
import source.tuner.frequency.IFrequencyChangeProvider;
|
||||||
|
|
||||||
public abstract class P25Decoder extends Decoder implements Instrumentable
|
public abstract class P25Decoder extends Decoder implements IFrequencyChangeListener, IFrequencyChangeProvider, Instrumentable
|
||||||
{
|
{
|
||||||
private P25MessageProcessor mMessageProcessor;
|
private P25MessageProcessor mMessageProcessor;
|
||||||
|
|
||||||
|
|||||||
@@ -315,6 +315,8 @@ public class P25DecoderState extends DecoderState
|
|||||||
*/
|
*/
|
||||||
public void registerCallEvent(P25CallEvent event)
|
public void registerCallEvent(P25CallEvent event)
|
||||||
{
|
{
|
||||||
|
String channel = event.getChannel();
|
||||||
|
|
||||||
if(mChannelCallMap.containsKey(event.getChannel()))
|
if(mChannelCallMap.containsKey(event.getChannel()))
|
||||||
{
|
{
|
||||||
P25CallEvent previousEvent = mChannelCallMap.remove(event.getChannel());
|
P25CallEvent previousEvent = mChannelCallMap.remove(event.getChannel());
|
||||||
@@ -1557,6 +1559,7 @@ public class P25DecoderState extends DecoderState
|
|||||||
break;
|
break;
|
||||||
case IDENTIFIER_UPDATE_NON_VUHF:
|
case IDENTIFIER_UPDATE_NON_VUHF:
|
||||||
case IDENTIFIER_UPDATE_VHF_UHF_BANDS:
|
case IDENTIFIER_UPDATE_VHF_UHF_BANDS:
|
||||||
|
case IDENTIFIER_UPDATE_TDMA:
|
||||||
IdentifierUpdate iu = (IdentifierUpdate)tsbk;
|
IdentifierUpdate iu = (IdentifierUpdate)tsbk;
|
||||||
|
|
||||||
if(!mBands.containsKey(iu.getIdentifier()))
|
if(!mBands.containsKey(iu.getIdentifier()))
|
||||||
@@ -2735,6 +2738,7 @@ public class P25DecoderState extends DecoderState
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
StringBuilder details = new StringBuilder();
|
StringBuilder details = new StringBuilder();
|
||||||
|
details.append(pgvcg.isTDMAChannel() ? "TDMA " : "");
|
||||||
details.append(pgvcg.isEmergency() ? "EMERGENCY " : "");
|
details.append(pgvcg.isEmergency() ? "EMERGENCY " : "");
|
||||||
details.append("PRI:").append(pgvcg.getPriority());
|
details.append("PRI:").append(pgvcg.getPriority());
|
||||||
details.append(pgvcg.isEncryptedChannel() ? " ENCRYPTED" : "");
|
details.append(pgvcg.isEncryptedChannel() ? " ENCRYPTED" : "");
|
||||||
@@ -2742,7 +2746,7 @@ public class P25DecoderState extends DecoderState
|
|||||||
|
|
||||||
P25CallEvent event = new P25CallEvent.Builder(CallEventType.PATCH_GROUP_CALL)
|
P25CallEvent event = new P25CallEvent.Builder(CallEventType.PATCH_GROUP_CALL)
|
||||||
.aliasList(getAliasList())
|
.aliasList(getAliasList())
|
||||||
.channel(channel + (pgvcg.isTDMAChannel() ? " TDMA" : ""))
|
.channel(channel)
|
||||||
.details(details.toString())
|
.details(details.toString())
|
||||||
.frequency(pgvcg.getDownlinkFrequency())
|
.frequency(pgvcg.getDownlinkFrequency())
|
||||||
.from(from)
|
.from(from)
|
||||||
@@ -2775,8 +2779,9 @@ public class P25DecoderState extends DecoderState
|
|||||||
{
|
{
|
||||||
P25CallEvent event = new P25CallEvent.Builder(CallEventType.PATCH_GROUP_CALL)
|
P25CallEvent event = new P25CallEvent.Builder(CallEventType.PATCH_GROUP_CALL)
|
||||||
.aliasList(getAliasList())
|
.aliasList(getAliasList())
|
||||||
.channel(channel + (gvcgu.isTDMAChannel1() ? " TDMA" : ""))
|
.channel(channel)
|
||||||
.details((gvcgu.isEncrypted() ? "ENCRYPTED " : ""))
|
.details((gvcgu.isTDMAChannel1() ? "TDMA " : "") +
|
||||||
|
(gvcgu.isEncrypted() ? "ENCRYPTED " : ""))
|
||||||
.frequency(gvcgu.getDownlinkFrequency1())
|
.frequency(gvcgu.getDownlinkFrequency1())
|
||||||
.to(to)
|
.to(to)
|
||||||
.build();
|
.build();
|
||||||
@@ -2801,8 +2806,9 @@ public class P25DecoderState extends DecoderState
|
|||||||
{
|
{
|
||||||
P25CallEvent event = new P25CallEvent.Builder(CallEventType.PATCH_GROUP_CALL)
|
P25CallEvent event = new P25CallEvent.Builder(CallEventType.PATCH_GROUP_CALL)
|
||||||
.aliasList(getAliasList())
|
.aliasList(getAliasList())
|
||||||
.channel(channel2 + (gvcgu.isTDMAChannel2() ? " TDMA" : ""))
|
.channel(channel2)
|
||||||
.details((gvcgu.isEncrypted() ? "ENCRYPTED " : ""))
|
.details((gvcgu.isTDMAChannel2() ? "TDMA " : "") +
|
||||||
|
(gvcgu.isEncrypted() ? "ENCRYPTED " : ""))
|
||||||
.frequency(gvcgu.getDownlinkFrequency2())
|
.frequency(gvcgu.getDownlinkFrequency2())
|
||||||
.to(to2)
|
.to(to2)
|
||||||
.build();
|
.build();
|
||||||
@@ -2866,6 +2872,7 @@ public class P25DecoderState extends DecoderState
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
StringBuilder details = new StringBuilder();
|
StringBuilder details = new StringBuilder();
|
||||||
|
details.append(gdcg.isTDMAChannel() ? "TDMA " : "");
|
||||||
details.append(gdcg.isEmergency() ? "EMERGENCY " : "");
|
details.append(gdcg.isEmergency() ? "EMERGENCY " : "");
|
||||||
details.append("PRI:").append(gdcg.getPriority()).append(" ");
|
details.append("PRI:").append(gdcg.getPriority()).append(" ");
|
||||||
details.append(gdcg.isEncryptedChannel() ? "ENCRYPTED " : "");
|
details.append(gdcg.isEncryptedChannel() ? "ENCRYPTED " : "");
|
||||||
@@ -2873,7 +2880,7 @@ public class P25DecoderState extends DecoderState
|
|||||||
|
|
||||||
P25CallEvent event = new P25CallEvent.Builder(CallEventType.DATA_CALL)
|
P25CallEvent event = new P25CallEvent.Builder(CallEventType.DATA_CALL)
|
||||||
.aliasList(getAliasList())
|
.aliasList(getAliasList())
|
||||||
.channel(channel + (gdcg.isTDMAChannel() ? " TDMA" : ""))
|
.channel(channel)
|
||||||
.details(details.toString())
|
.details(details.toString())
|
||||||
.frequency(gdcg.getDownlinkFrequency())
|
.frequency(gdcg.getDownlinkFrequency())
|
||||||
.from(from)
|
.from(from)
|
||||||
@@ -2904,6 +2911,7 @@ public class P25DecoderState extends DecoderState
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
StringBuilder details = new StringBuilder();
|
StringBuilder details = new StringBuilder();
|
||||||
|
details.append(gvcg.isTDMAChannel() ? "TDMA " : "");
|
||||||
details.append(gvcg.isEmergency() ? "EMERGENCY " : "");
|
details.append(gvcg.isEmergency() ? "EMERGENCY " : "");
|
||||||
details.append("PRI:").append(gvcg.getPriority()).append(" ");
|
details.append("PRI:").append(gvcg.getPriority()).append(" ");
|
||||||
details.append(gvcg.isEncryptedChannel() ? "ENCRYPTED " : "");
|
details.append(gvcg.isEncryptedChannel() ? "ENCRYPTED " : "");
|
||||||
@@ -2911,7 +2919,7 @@ public class P25DecoderState extends DecoderState
|
|||||||
|
|
||||||
P25CallEvent event = new P25CallEvent.Builder(CallEventType.GROUP_CALL)
|
P25CallEvent event = new P25CallEvent.Builder(CallEventType.GROUP_CALL)
|
||||||
.aliasList(getAliasList())
|
.aliasList(getAliasList())
|
||||||
.channel(channel + (gvcg.isTDMAChannel() ? " TDMA" : ""))
|
.channel(channel)
|
||||||
.details(details.toString())
|
.details(details.toString())
|
||||||
.frequency(gvcg.getDownlinkFrequency())
|
.frequency(gvcg.getDownlinkFrequency())
|
||||||
.from(from)
|
.from(from)
|
||||||
@@ -2928,8 +2936,7 @@ public class P25DecoderState extends DecoderState
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GROUP_VOICE_CHANNEL_GRANT_UPDATE:
|
case GROUP_VOICE_CHANNEL_GRANT_UPDATE:
|
||||||
GroupVoiceChannelGrantUpdate gvcgu =
|
GroupVoiceChannelGrantUpdate gvcgu = (GroupVoiceChannelGrantUpdate)message;
|
||||||
(GroupVoiceChannelGrantUpdate)message;
|
|
||||||
|
|
||||||
channel = gvcgu.getChannel1();
|
channel = gvcgu.getChannel1();
|
||||||
from = null;
|
from = null;
|
||||||
@@ -2942,6 +2949,7 @@ public class P25DecoderState extends DecoderState
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
StringBuilder details = new StringBuilder();
|
StringBuilder details = new StringBuilder();
|
||||||
|
details.append(gvcgu.isTDMAChannel() ? "TDMA " : "");
|
||||||
details.append(gvcgu.isEmergency() ? "EMERGENCY " : "");
|
details.append(gvcgu.isEmergency() ? "EMERGENCY " : "");
|
||||||
details.append("PRI:").append(gvcgu.getPriority()).append(" ");
|
details.append("PRI:").append(gvcgu.getPriority()).append(" ");
|
||||||
details.append(gvcgu.isEncryptedChannel() ? "ENCRYPTED " : "");
|
details.append(gvcgu.isEncryptedChannel() ? "ENCRYPTED " : "");
|
||||||
@@ -2949,7 +2957,7 @@ public class P25DecoderState extends DecoderState
|
|||||||
|
|
||||||
P25CallEvent event = new P25CallEvent.Builder(CallEventType.GROUP_CALL)
|
P25CallEvent event = new P25CallEvent.Builder(CallEventType.GROUP_CALL)
|
||||||
.aliasList(getAliasList())
|
.aliasList(getAliasList())
|
||||||
.channel(gvcgu.getChannel1() + (gvcgu.isTDMAChannel1() ? " TDMA" : ""))
|
.channel(gvcgu.getChannel1())
|
||||||
.details(details.toString())
|
.details(details.toString())
|
||||||
.frequency(gvcgu.getDownlinkFrequency1())
|
.frequency(gvcgu.getDownlinkFrequency1())
|
||||||
.from(from)
|
.from(from)
|
||||||
@@ -2977,6 +2985,7 @@ public class P25DecoderState extends DecoderState
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
StringBuilder details = new StringBuilder();
|
StringBuilder details = new StringBuilder();
|
||||||
|
details.append(gvcgu.isTDMAChannel() ? "TDMA " : "");
|
||||||
details.append(gvcgu.isEmergency() ? "EMERGENCY " : "");
|
details.append(gvcgu.isEmergency() ? "EMERGENCY " : "");
|
||||||
details.append("PRI:").append(gvcgu.getPriority()).append(" ");
|
details.append("PRI:").append(gvcgu.getPriority()).append(" ");
|
||||||
details.append(gvcgu.isEncryptedChannel() ? "ENCRYPTED " : "");
|
details.append(gvcgu.isEncryptedChannel() ? "ENCRYPTED " : "");
|
||||||
@@ -2984,7 +2993,7 @@ public class P25DecoderState extends DecoderState
|
|||||||
|
|
||||||
P25CallEvent event2 = new P25CallEvent.Builder(CallEventType.GROUP_CALL)
|
P25CallEvent event2 = new P25CallEvent.Builder(CallEventType.GROUP_CALL)
|
||||||
.aliasList(getAliasList())
|
.aliasList(getAliasList())
|
||||||
.channel(gvcgu.getChannel2() + (gvcgu.isTDMAChannel2() ? " TDMA" : ""))
|
.channel(gvcgu.getChannel2())
|
||||||
.details(details.toString())
|
.details(details.toString())
|
||||||
.frequency(gvcgu.getDownlinkFrequency2())
|
.frequency(gvcgu.getDownlinkFrequency2())
|
||||||
.to(gvcgu.getGroupAddress2())
|
.to(gvcgu.getGroupAddress2())
|
||||||
@@ -3016,6 +3025,7 @@ public class P25DecoderState extends DecoderState
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
StringBuilder details = new StringBuilder();
|
StringBuilder details = new StringBuilder();
|
||||||
|
details.append(gvcgue.isTDMAChannel() ? "TDMA " : "");
|
||||||
details.append(gvcgue.isEmergency() ? "EMERGENCY " : "");
|
details.append(gvcgue.isEmergency() ? "EMERGENCY " : "");
|
||||||
details.append("PRI:").append(gvcgue.getPriority()).append(" ");
|
details.append("PRI:").append(gvcgue.getPriority()).append(" ");
|
||||||
details.append(gvcgue.isEncryptedChannel() ? "ENCRYPTED " : "");
|
details.append(gvcgue.isEncryptedChannel() ? "ENCRYPTED " : "");
|
||||||
@@ -3023,7 +3033,7 @@ public class P25DecoderState extends DecoderState
|
|||||||
|
|
||||||
P25CallEvent event = new P25CallEvent.Builder(CallEventType.GROUP_CALL)
|
P25CallEvent event = new P25CallEvent.Builder(CallEventType.GROUP_CALL)
|
||||||
.aliasList(getAliasList())
|
.aliasList(getAliasList())
|
||||||
.channel(channel + (gvcgue.isTDMAChannel() ? " TDMA" : ""))
|
.channel(channel)
|
||||||
.details(details.toString())
|
.details(details.toString())
|
||||||
.frequency(gvcgue.getDownlinkFrequency())
|
.frequency(gvcgue.getDownlinkFrequency())
|
||||||
.from(from)
|
.from(from)
|
||||||
@@ -3053,6 +3063,7 @@ public class P25DecoderState extends DecoderState
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
StringBuilder details = new StringBuilder();
|
StringBuilder details = new StringBuilder();
|
||||||
|
details.append(idcg.isTDMAChannel() ? "TDMA " : "");
|
||||||
details.append(idcg.isEmergency() ? "EMERGENCY " : "");
|
details.append(idcg.isEmergency() ? "EMERGENCY " : "");
|
||||||
details.append("PRI:").append(idcg.getPriority()).append(" ");
|
details.append("PRI:").append(idcg.getPriority()).append(" ");
|
||||||
details.append(idcg.isEncryptedChannel() ? "ENCRYPTED " : "");
|
details.append(idcg.isEncryptedChannel() ? "ENCRYPTED " : "");
|
||||||
@@ -3060,7 +3071,7 @@ public class P25DecoderState extends DecoderState
|
|||||||
|
|
||||||
P25CallEvent event = new P25CallEvent.Builder(CallEventType.DATA_CALL)
|
P25CallEvent event = new P25CallEvent.Builder(CallEventType.DATA_CALL)
|
||||||
.aliasList(getAliasList())
|
.aliasList(getAliasList())
|
||||||
.channel(channel + (idcg.isTDMAChannel() ? " TDMA" : ""))
|
.channel(channel)
|
||||||
.details(details.toString())
|
.details(details.toString())
|
||||||
.frequency(idcg.getDownlinkFrequency())
|
.frequency(idcg.getDownlinkFrequency())
|
||||||
.from(from)
|
.from(from)
|
||||||
@@ -3090,13 +3101,14 @@ public class P25DecoderState extends DecoderState
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
StringBuilder details = new StringBuilder();
|
StringBuilder details = new StringBuilder();
|
||||||
|
details.append(sdcg.isTDMAChannel() ? "TDMA " : "");
|
||||||
details.append(sdcg.isEmergency() ? "EMERGENCY " : "");
|
details.append(sdcg.isEmergency() ? "EMERGENCY " : "");
|
||||||
details.append(sdcg.isEncryptedChannel() ? "ENCRYPTED " : "");
|
details.append(sdcg.isEncryptedChannel() ? "ENCRYPTED " : "");
|
||||||
details.append(sdcg.getSessionMode().name());
|
details.append(sdcg.getSessionMode().name());
|
||||||
|
|
||||||
P25CallEvent event = new P25CallEvent.Builder(CallEventType.DATA_CALL)
|
P25CallEvent event = new P25CallEvent.Builder(CallEventType.DATA_CALL)
|
||||||
.aliasList(getAliasList())
|
.aliasList(getAliasList())
|
||||||
.channel(channel + (sdcg.isTDMAChannel() ? " TDMA" : ""))
|
.channel(channel)
|
||||||
.details(details.toString())
|
.details(details.toString())
|
||||||
.frequency(sdcg.getDownlinkFrequency())
|
.frequency(sdcg.getDownlinkFrequency())
|
||||||
.from(from)
|
.from(from)
|
||||||
@@ -3128,6 +3140,7 @@ public class P25DecoderState extends DecoderState
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
StringBuilder details = new StringBuilder();
|
StringBuilder details = new StringBuilder();
|
||||||
|
details.append(tivcg.isTDMAChannel() ? "TDMA " : "");
|
||||||
details.append(tivcg.isEmergency() ? "EMERGENCY " : "");
|
details.append(tivcg.isEmergency() ? "EMERGENCY " : "");
|
||||||
details.append("PRI:").append(tivcg.getPriority()).append(" ");
|
details.append("PRI:").append(tivcg.getPriority()).append(" ");
|
||||||
details.append(tivcg.isEncryptedChannel() ? "ENCRYPTED " : "");
|
details.append(tivcg.isEncryptedChannel() ? "ENCRYPTED " : "");
|
||||||
@@ -3137,7 +3150,7 @@ public class P25DecoderState extends DecoderState
|
|||||||
P25CallEvent event = new P25CallEvent.Builder(
|
P25CallEvent event = new P25CallEvent.Builder(
|
||||||
CallEventType.TELEPHONE_INTERCONNECT)
|
CallEventType.TELEPHONE_INTERCONNECT)
|
||||||
.aliasList(getAliasList())
|
.aliasList(getAliasList())
|
||||||
.channel(channel + (tivcg.isTDMAChannel() ? " TDMA" : ""))
|
.channel(channel)
|
||||||
.details(details.toString())
|
.details(details.toString())
|
||||||
.frequency(tivcg.getDownlinkFrequency())
|
.frequency(tivcg.getDownlinkFrequency())
|
||||||
.from(from)
|
.from(from)
|
||||||
@@ -3170,6 +3183,7 @@ public class P25DecoderState extends DecoderState
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
StringBuilder details = new StringBuilder();
|
StringBuilder details = new StringBuilder();
|
||||||
|
details.append(tivcgu.isTDMAChannel() ? "TDMA " : "");
|
||||||
details.append(tivcgu.isEmergency() ? "EMERGENCY " : "");
|
details.append(tivcgu.isEmergency() ? "EMERGENCY " : "");
|
||||||
details.append("PRI:").append(tivcgu.getPriority()).append(" ");
|
details.append("PRI:").append(tivcgu.getPriority()).append(" ");
|
||||||
details.append(tivcgu.isEncryptedChannel() ? "ENCRYPTED " : "");
|
details.append(tivcgu.isEncryptedChannel() ? "ENCRYPTED " : "");
|
||||||
@@ -3179,7 +3193,7 @@ public class P25DecoderState extends DecoderState
|
|||||||
P25CallEvent event = new P25CallEvent.Builder(
|
P25CallEvent event = new P25CallEvent.Builder(
|
||||||
CallEventType.TELEPHONE_INTERCONNECT)
|
CallEventType.TELEPHONE_INTERCONNECT)
|
||||||
.aliasList(getAliasList())
|
.aliasList(getAliasList())
|
||||||
.channel(channel + (tivcgu.isTDMAChannel() ? " TDMA" : ""))
|
.channel(channel)
|
||||||
.details(details.toString())
|
.details(details.toString())
|
||||||
.frequency(tivcgu.getDownlinkFrequency())
|
.frequency(tivcgu.getDownlinkFrequency())
|
||||||
.from(from)
|
.from(from)
|
||||||
@@ -3209,6 +3223,7 @@ public class P25DecoderState extends DecoderState
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
StringBuilder details = new StringBuilder();
|
StringBuilder details = new StringBuilder();
|
||||||
|
details.append(uuvcg.isTDMAChannel() ? "TDMA " : "");
|
||||||
details.append(uuvcg.isEmergency() ? "EMERGENCY " : "");
|
details.append(uuvcg.isEmergency() ? "EMERGENCY " : "");
|
||||||
details.append("PRI:").append(uuvcg.getPriority()).append(" ");
|
details.append("PRI:").append(uuvcg.getPriority()).append(" ");
|
||||||
details.append(uuvcg.isEncryptedChannel() ? " ENCRYPTED " : "");
|
details.append(uuvcg.isEncryptedChannel() ? " ENCRYPTED " : "");
|
||||||
@@ -3217,7 +3232,7 @@ public class P25DecoderState extends DecoderState
|
|||||||
P25CallEvent event = new P25CallEvent.Builder(
|
P25CallEvent event = new P25CallEvent.Builder(
|
||||||
CallEventType.UNIT_TO_UNIT_CALL)
|
CallEventType.UNIT_TO_UNIT_CALL)
|
||||||
.aliasList(getAliasList())
|
.aliasList(getAliasList())
|
||||||
.channel(channel + (uuvcg.isTDMAChannel() ? " TDMA" : ""))
|
.channel(channel)
|
||||||
.details(details.toString())
|
.details(details.toString())
|
||||||
.frequency(uuvcg.getDownlinkFrequency())
|
.frequency(uuvcg.getDownlinkFrequency())
|
||||||
.from(from)
|
.from(from)
|
||||||
@@ -3247,6 +3262,7 @@ public class P25DecoderState extends DecoderState
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
StringBuilder details = new StringBuilder();
|
StringBuilder details = new StringBuilder();
|
||||||
|
details.append(uuvcgu.isTDMAChannel() ? "TDMA " : "");
|
||||||
details.append(uuvcgu.isEmergency() ? "EMERGENCY " : "");
|
details.append(uuvcgu.isEmergency() ? "EMERGENCY " : "");
|
||||||
details.append("PRI:").append(uuvcgu.getPriority()).append(" ");
|
details.append("PRI:").append(uuvcgu.getPriority()).append(" ");
|
||||||
details.append(uuvcgu.isEncryptedChannel() ? "ENCRYPTED " : "");
|
details.append(uuvcgu.isEncryptedChannel() ? "ENCRYPTED " : "");
|
||||||
@@ -3255,7 +3271,7 @@ public class P25DecoderState extends DecoderState
|
|||||||
P25CallEvent event = new P25CallEvent.Builder(
|
P25CallEvent event = new P25CallEvent.Builder(
|
||||||
CallEventType.UNIT_TO_UNIT_CALL)
|
CallEventType.UNIT_TO_UNIT_CALL)
|
||||||
.aliasList(getAliasList())
|
.aliasList(getAliasList())
|
||||||
.channel(channel + (uuvcgu.isTDMAChannel() ? " TDMA" : ""))
|
.channel(channel)
|
||||||
.details(details.toString())
|
.details(details.toString())
|
||||||
.frequency(uuvcgu.getDownlinkFrequency())
|
.frequency(uuvcgu.getDownlinkFrequency())
|
||||||
.from(from)
|
.from(from)
|
||||||
|
|||||||
@@ -689,8 +689,7 @@ public class P25MessageFramer implements Listener<Dibit>
|
|||||||
private LSMDemodulator mDemodulator;
|
private LSMDemodulator mDemodulator;
|
||||||
private double mCorrection;
|
private double mCorrection;
|
||||||
|
|
||||||
public CostasPhaseErrorDetector( FrameSync frameSync,
|
public CostasPhaseErrorDetector( FrameSync frameSync, LSMDemodulator demodulator, double correction )
|
||||||
LSMDemodulator demodulator, double correction )
|
|
||||||
{
|
{
|
||||||
super( frameSync.getSync() );
|
super( frameSync.getSync() );
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* SDR Trunk
|
* sdrtrunk
|
||||||
* Copyright (C) 2014,2015 Dennis Sheirer
|
* Copyright (C) 2014-2017 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package module.decode.p25;
|
package module.decode.p25;
|
||||||
|
|
||||||
@@ -41,8 +42,7 @@ import dsp.filter.FilterFactory;
|
|||||||
import dsp.filter.Window.WindowType;
|
import dsp.filter.Window.WindowType;
|
||||||
import dsp.filter.fir.real.RealFIRFilter_RB_RB;
|
import dsp.filter.fir.real.RealFIRFilter_RB_RB;
|
||||||
|
|
||||||
public class P25_C4FMDecoder extends P25Decoder
|
public class P25_C4FMDecoder extends P25Decoder implements IFilteredRealBufferListener
|
||||||
implements IFrequencyChangeListener, IFrequencyChangeProvider,IFilteredRealBufferListener
|
|
||||||
{
|
{
|
||||||
private final static Logger mLog = LoggerFactory.getLogger( P25_C4FMDecoder.class );
|
private final static Logger mLog = LoggerFactory.getLogger( P25_C4FMDecoder.class );
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import dsp.filter.fir.complex.ComplexFIRFilter_CB_CB;
|
|||||||
import dsp.gain.ComplexFeedForwardGainControl;
|
import dsp.gain.ComplexFeedForwardGainControl;
|
||||||
import dsp.psk.LSMDemodulator;
|
import dsp.psk.LSMDemodulator;
|
||||||
import dsp.psk.QPSKPolarSlicer;
|
import dsp.psk.QPSKPolarSlicer;
|
||||||
|
import source.tuner.frequency.FrequencyChangeEvent;
|
||||||
|
|
||||||
public class P25_LSMDecoder extends P25Decoder implements IComplexBufferListener
|
public class P25_LSMDecoder extends P25Decoder implements IComplexBufferListener
|
||||||
{
|
{
|
||||||
@@ -56,8 +57,7 @@ public class P25_LSMDecoder extends P25Decoder implements IComplexBufferListener
|
|||||||
private List<TapGroup> mAvailableTaps;
|
private List<TapGroup> mAvailableTaps;
|
||||||
|
|
||||||
private ComplexFIRFilter_CB_CB mBasebandFilter;
|
private ComplexFIRFilter_CB_CB mBasebandFilter;
|
||||||
private ComplexBufferToStreamConverter mStreamConverter =
|
private ComplexBufferToStreamConverter mStreamConverter = new ComplexBufferToStreamConverter();
|
||||||
new ComplexBufferToStreamConverter();
|
|
||||||
private ComplexFeedForwardGainControl mAGC =
|
private ComplexFeedForwardGainControl mAGC =
|
||||||
new ComplexFeedForwardGainControl( 32 );
|
new ComplexFeedForwardGainControl( 32 );
|
||||||
private LSMDemodulator mLSMDemodulator = new LSMDemodulator();
|
private LSMDemodulator mLSMDemodulator = new LSMDemodulator();
|
||||||
@@ -108,6 +108,29 @@ public class P25_LSMDecoder extends P25Decoder implements IComplexBufferListener
|
|||||||
mMessageFramer = null;
|
mMessageFramer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFrequencyChangeListener(Listener<FrequencyChangeEvent> listener)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeFrequencyChangeListener()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Listener<FrequencyChangeEvent> getFrequencyChangeListener()
|
||||||
|
{
|
||||||
|
return new Listener<FrequencyChangeEvent>()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void receive(FrequencyChangeEvent frequencyChangeEvent)
|
||||||
|
{
|
||||||
|
//Ignored
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Listener<ComplexBuffer> getComplexBufferListener()
|
public Listener<ComplexBuffer> getComplexBufferListener()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public class IdentifierUpdateTDMA extends IdentifierUpdate
|
|||||||
|
|
||||||
sb.append( " ID:" + getIdentifier() );
|
sb.append( " ID:" + getIdentifier() );
|
||||||
sb.append( " BASE:" + getBaseFrequency() );
|
sb.append( " BASE:" + getBaseFrequency() );
|
||||||
sb.append( " BW:" + getBandwidth() );
|
sb.append( " BANDWIDTH:" + getBandwidth() );
|
||||||
sb.append( " SPACING:" + getChannelSpacing() );
|
sb.append( " SPACING:" + getChannelSpacing() );
|
||||||
sb.append( " OFFSET:" + getTransmitOffset() );
|
sb.append( " OFFSET:" + getTransmitOffset() );
|
||||||
sb.append( " TYPE:" + getChannelType().toString() );
|
sb.append( " TYPE:" + getChannelType().toString() );
|
||||||
@@ -137,7 +137,7 @@ public class IdentifierUpdateTDMA extends IdentifierUpdate
|
|||||||
|
|
||||||
sb.append( mAccessType.name() );
|
sb.append( mAccessType.name() );
|
||||||
sb.append( " BANDWIDTH:" + mBandwidth );
|
sb.append( " BANDWIDTH:" + mBandwidth );
|
||||||
sb.append( " SLOT/CARRIER:" + mSlotsPerCarrier );
|
sb.append( " TIMESLOTS PER CARRIER:" + mSlotsPerCarrier );
|
||||||
sb.append( " VOCODER:" + mVocoder.name() );
|
sb.append( " VOCODER:" + mVocoder.name() );
|
||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
|
|||||||
@@ -58,6 +58,11 @@ public class Broadcaster<T> implements Listener<T>
|
|||||||
|
|
||||||
public void addListener( Listener<T> listener )
|
public void addListener( Listener<T> listener )
|
||||||
{
|
{
|
||||||
|
if(listener == null)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Listener cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
mListeners.add( listener );
|
mListeners.add( listener );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,11 +20,13 @@ package source;
|
|||||||
import module.Module;
|
import module.Module;
|
||||||
import sample.SampleType;
|
import sample.SampleType;
|
||||||
import sample.real.IOverflowListener;
|
import sample.real.IOverflowListener;
|
||||||
|
import source.tuner.frequency.IFrequencyChangeListener;
|
||||||
|
import source.tuner.frequency.IFrequencyChangeProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract class to define the minimum functionality of a sample data provider.
|
* Abstract class to define the minimum functionality of a sample data provider.
|
||||||
*/
|
*/
|
||||||
public abstract class Source extends Module
|
public abstract class Source extends Module implements IFrequencyChangeListener, IFrequencyChangeProvider
|
||||||
{
|
{
|
||||||
protected SampleType mSampleType;
|
protected SampleType mSampleType;
|
||||||
protected IOverflowListener mOverflowListener;
|
protected IOverflowListener mOverflowListener;
|
||||||
|
|||||||
@@ -36,11 +36,11 @@ import sample.real.RealBuffer;
|
|||||||
import source.RealSource;
|
import source.RealSource;
|
||||||
import source.SourceException;
|
import source.SourceException;
|
||||||
import dsp.gain.AutomaticGainControl;
|
import dsp.gain.AutomaticGainControl;
|
||||||
|
import source.tuner.frequency.FrequencyChangeEvent;
|
||||||
|
|
||||||
public class RealMixerSource extends RealSource
|
public class RealMixerSource extends RealSource
|
||||||
{
|
{
|
||||||
private final static Logger mLog =
|
private final static Logger mLog = LoggerFactory.getLogger( RealMixerSource.class );
|
||||||
LoggerFactory.getLogger( RealMixerSource.class );
|
|
||||||
|
|
||||||
private long mFrequency = 0;
|
private long mFrequency = 0;
|
||||||
private int mBufferSize = 16384;
|
private int mBufferSize = 16384;
|
||||||
@@ -48,13 +48,11 @@ public class RealMixerSource extends RealSource
|
|||||||
private BufferReader mBufferReader = new BufferReader();
|
private BufferReader mBufferReader = new BufferReader();
|
||||||
private TargetDataLine mTargetDataLine;
|
private TargetDataLine mTargetDataLine;
|
||||||
private AudioFormat mAudioFormat;
|
private AudioFormat mAudioFormat;
|
||||||
private String mDisplayName;
|
|
||||||
private int mBytesPerFrame = 0;
|
private int mBytesPerFrame = 0;
|
||||||
private ISampleAdapter mSampleAdapter;
|
private ISampleAdapter mSampleAdapter;
|
||||||
private AutomaticGainControl mAGC = new AutomaticGainControl();
|
private AutomaticGainControl mAGC = new AutomaticGainControl();
|
||||||
|
|
||||||
CopyOnWriteArrayList<Listener<RealBuffer>> mSampleListeners =
|
CopyOnWriteArrayList<Listener<RealBuffer>> mSampleListeners = new CopyOnWriteArrayList<Listener<RealBuffer>>();
|
||||||
new CopyOnWriteArrayList<Listener<RealBuffer>>();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Real Mixer Source - constructs a reader on the mixer/sound card target
|
* Real Mixer Source - constructs a reader on the mixer/sound card target
|
||||||
@@ -81,6 +79,25 @@ public class RealMixerSource extends RealSource
|
|||||||
mSampleAdapter = sampleAdapter;
|
mSampleAdapter = sampleAdapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFrequencyChangeListener(Listener<FrequencyChangeEvent> listener)
|
||||||
|
{
|
||||||
|
//Not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeFrequencyChangeListener()
|
||||||
|
{
|
||||||
|
//Not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Listener<FrequencyChangeEvent> getFrequencyChangeListener()
|
||||||
|
{
|
||||||
|
//Not implemented
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reset()
|
public void reset()
|
||||||
{
|
{
|
||||||
@@ -133,23 +150,15 @@ public class RealMixerSource extends RealSource
|
|||||||
* buffer, otherwise send him a copy of the buffer */
|
* buffer, otherwise send him a copy of the buffer */
|
||||||
if( it.hasNext() )
|
if( it.hasNext() )
|
||||||
{
|
{
|
||||||
// next.receive( mAGC.process( samples.copyOf() ) );
|
|
||||||
next.receive( samples.copyOf() );
|
next.receive( samples.copyOf() );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// next.receive( mAGC.process( samples ) );
|
|
||||||
next.receive( samples );
|
next.receive( samples );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString()
|
|
||||||
{
|
|
||||||
return mDisplayName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSampleRate()
|
public int getSampleRate()
|
||||||
{
|
{
|
||||||
if( mTargetDataLine != null )
|
if( mTargetDataLine != null )
|
||||||
|
|||||||
@@ -34,7 +34,9 @@ import source.ComplexSource;
|
|||||||
import source.SourceException;
|
import source.SourceException;
|
||||||
import source.tuner.frequency.FrequencyChangeEvent;
|
import source.tuner.frequency.FrequencyChangeEvent;
|
||||||
import source.tuner.frequency.FrequencyChangeEvent.Event;
|
import source.tuner.frequency.FrequencyChangeEvent.Event;
|
||||||
|
import source.tuner.frequency.IFrequencyChangeListener;
|
||||||
import source.tuner.frequency.IFrequencyChangeProcessor;
|
import source.tuner.frequency.IFrequencyChangeProcessor;
|
||||||
|
import source.tuner.frequency.IFrequencyChangeProvider;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -65,6 +67,7 @@ public class TunerChannelSource extends ComplexSource implements IFrequencyChang
|
|||||||
private ComplexPrimeCICDecimate mDecimationFilter;
|
private ComplexPrimeCICDecimate mDecimationFilter;
|
||||||
private Listener<ComplexBuffer> mListener;
|
private Listener<ComplexBuffer> mListener;
|
||||||
private IFrequencyChangeProcessor mFrequencyChangeProcessor;
|
private IFrequencyChangeProcessor mFrequencyChangeProcessor;
|
||||||
|
private DownstreamProcessor mDownstreamFrequencyEventProcessor = new DownstreamProcessor();
|
||||||
private ScheduledFuture<?> mTaskHandle;
|
private ScheduledFuture<?> mTaskHandle;
|
||||||
|
|
||||||
private long mTunerFrequency = 0;
|
private long mTunerFrequency = 0;
|
||||||
@@ -75,7 +78,6 @@ public class TunerChannelSource extends ComplexSource implements IFrequencyChang
|
|||||||
|
|
||||||
private AtomicBoolean mRunning = new AtomicBoolean();
|
private AtomicBoolean mRunning = new AtomicBoolean();
|
||||||
private boolean mExpended = false;
|
private boolean mExpended = false;
|
||||||
private int mCount;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a Digital Drop Channel (DDC) to decimate the IQ output from a
|
* Provides a Digital Drop Channel (DDC) to decimate the IQ output from a
|
||||||
@@ -109,7 +111,8 @@ public class TunerChannelSource extends ComplexSource implements IFrequencyChang
|
|||||||
mMixer = new Oscillator(frequencyOffset, mTuner.getTunerController().getSampleRate());
|
mMixer = new Oscillator(frequencyOffset, mTuner.getTunerController().getSampleRate());
|
||||||
|
|
||||||
/* Fire a sample rate change event to setup the decimation chain */
|
/* Fire a sample rate change event to setup the decimation chain */
|
||||||
frequencyChanged(new FrequencyChangeEvent(Event.NOTIFICATION_SAMPLE_RATE_CHANGE, mTuner.getTunerController().getSampleRate()));
|
frequencyChanged(new FrequencyChangeEvent(Event.NOTIFICATION_SAMPLE_RATE_CHANGE,
|
||||||
|
mTuner.getTunerController().getSampleRate()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -131,6 +134,10 @@ public class TunerChannelSource extends ComplexSource implements IFrequencyChang
|
|||||||
|
|
||||||
if(mRunning.compareAndSet(false, true))
|
if(mRunning.compareAndSet(false, true))
|
||||||
{
|
{
|
||||||
|
//Broadcast current frequency and sample rate settings so all downstream components are aware
|
||||||
|
mDownstreamFrequencyEventProcessor.broadcastCurrentFrequency();
|
||||||
|
mDownstreamFrequencyEventProcessor.broadcastCurrentSampleRate();
|
||||||
|
|
||||||
//Schedule the decimation task to run every 9 ms (111 iterations/second), an odd periodicity relative
|
//Schedule the decimation task to run every 9 ms (111 iterations/second), an odd periodicity relative
|
||||||
//to the inbound periodicity of 20 ms, to attempt to avoid thread queue contention
|
//to the inbound periodicity of 20 ms, to attempt to avoid thread queue contention
|
||||||
mTaskHandle = executor.scheduleAtFixedRate(mDecimationProcessor, 0, 9, TimeUnit.MILLISECONDS);
|
mTaskHandle = executor.scheduleAtFixedRate(mDecimationProcessor, 0, 9, TimeUnit.MILLISECONDS);
|
||||||
@@ -184,6 +191,20 @@ public class TunerChannelSource extends ComplexSource implements IFrequencyChang
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the frequency correction value and broadcasts the change to the registered downstream listener.
|
||||||
|
* @param correction current frequency correction value.
|
||||||
|
*/
|
||||||
|
private void setFrequencyCorrection(int correction)
|
||||||
|
{
|
||||||
|
mChannelFrequencyCorrection = correction;
|
||||||
|
|
||||||
|
updateMixerFrequencyOffset();
|
||||||
|
|
||||||
|
mDownstreamFrequencyEventProcessor.broadcast(
|
||||||
|
new FrequencyChangeEvent( Event.NOTIFICATION_CHANNEL_FREQUENCY_CORRECTION_CHANGE, mChannelFrequencyCorrection));
|
||||||
|
}
|
||||||
|
|
||||||
public Tuner getTuner()
|
public Tuner getTuner()
|
||||||
{
|
{
|
||||||
return mTuner;
|
return mTuner;
|
||||||
@@ -242,21 +263,25 @@ public class TunerChannelSource extends ComplexSource implements IFrequencyChang
|
|||||||
case NOTIFICATION_FREQUENCY_CHANGE:
|
case NOTIFICATION_FREQUENCY_CHANGE:
|
||||||
mTunerFrequency = event.getValue().longValue();
|
mTunerFrequency = event.getValue().longValue();
|
||||||
updateMixerFrequencyOffset();
|
updateMixerFrequencyOffset();
|
||||||
break;
|
|
||||||
case REQUEST_CHANNEL_FREQUENCY_CORRECTION_CHANGE:
|
|
||||||
mChannelFrequencyCorrection = event.getValue().intValue();
|
|
||||||
|
|
||||||
updateMixerFrequencyOffset();
|
//Reset frequency correction so that downstream components can recalculate the value
|
||||||
|
setFrequencyCorrection(0);
|
||||||
if(mFrequencyChangeProcessor != null)
|
|
||||||
{
|
|
||||||
mFrequencyChangeProcessor.frequencyChanged(new FrequencyChangeEvent(
|
|
||||||
Event.NOTIFICATION_CHANNEL_FREQUENCY_CORRECTION_CHANGE, mChannelFrequencyCorrection));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case NOTIFICATION_SAMPLE_RATE_CHANGE:
|
case NOTIFICATION_SAMPLE_RATE_CHANGE:
|
||||||
int sampleRate = event.getValue().intValue();
|
int sampleRate = event.getValue().intValue();
|
||||||
|
setSampleRate(sampleRate);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the sample rate to the requested value and notifies any downstream components of the change
|
||||||
|
* @param sampleRate to set
|
||||||
|
*/
|
||||||
|
private void setSampleRate(int sampleRate)
|
||||||
|
{
|
||||||
if(mTunerSampleRate != sampleRate)
|
if(mTunerSampleRate != sampleRate)
|
||||||
{
|
{
|
||||||
mMixer.setSampleRate(sampleRate);
|
mMixer.setSampleRate(sampleRate);
|
||||||
@@ -269,10 +294,8 @@ public class TunerChannelSource extends ComplexSource implements IFrequencyChang
|
|||||||
mDecimationFilter.setListener(mListener);
|
mDecimationFilter.setListener(mListener);
|
||||||
|
|
||||||
mTunerSampleRate = sampleRate;
|
mTunerSampleRate = sampleRate;
|
||||||
}
|
|
||||||
break;
|
mDownstreamFrequencyEventProcessor.broadcastCurrentSampleRate();
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,10 +305,7 @@ public class TunerChannelSource extends ComplexSource implements IFrequencyChang
|
|||||||
*/
|
*/
|
||||||
private void updateMixerFrequencyOffset()
|
private void updateMixerFrequencyOffset()
|
||||||
{
|
{
|
||||||
long offset = mTunerFrequency -
|
long offset = mTunerFrequency - mTunerChannel.getFrequency() - mChannelFrequencyCorrection;
|
||||||
mTunerChannel.getFrequency() -
|
|
||||||
mChannelFrequencyCorrection;
|
|
||||||
|
|
||||||
mMixer.setFrequency(offset);
|
mMixer.setFrequency(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,6 +319,140 @@ public class TunerChannelSource extends ComplexSource implements IFrequencyChang
|
|||||||
return mTunerChannel.getFrequency();
|
return mTunerChannel.getFrequency();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements IFrequencyChangeProvider to enable this source to broadcast frequency change events to downstream
|
||||||
|
* listeners.
|
||||||
|
*
|
||||||
|
* @param listener to receive downstream events
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setFrequencyChangeListener(Listener<FrequencyChangeEvent> listener)
|
||||||
|
{
|
||||||
|
mDownstreamFrequencyEventProcessor.setFrequencyChangeListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements IFrequencyChangeProvider to remove the frequency change listener from receiving down-stream frequency
|
||||||
|
* change events.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void removeFrequencyChangeListener()
|
||||||
|
{
|
||||||
|
mDownstreamFrequencyEventProcessor.removeFrequencyChangeListener();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements IFrequencyChangeListener to receive frequency change events containing requests from downstream
|
||||||
|
* listeners to change frequency values.
|
||||||
|
* @return listener
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Listener<FrequencyChangeEvent> getFrequencyChangeListener()
|
||||||
|
{
|
||||||
|
return mDownstreamFrequencyEventProcessor.getFrequencyChangeListener();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Managers frequency change requests and notifications from/to any downstream component. Downstream
|
||||||
|
* components are those that receive samples from this tuner channel source. These downstream components will be
|
||||||
|
* notified of any frequency or sample rate change events and will also be able to request frequency correction
|
||||||
|
* updates.
|
||||||
|
*/
|
||||||
|
public class DownstreamProcessor implements IFrequencyChangeListener, IFrequencyChangeProvider,
|
||||||
|
Listener<FrequencyChangeEvent>
|
||||||
|
{
|
||||||
|
//Listener to receive downstream events
|
||||||
|
private Listener<FrequencyChangeEvent> mListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Broadcasts the frequency change event to the downstream frequency change listener
|
||||||
|
* @param event to broadcast
|
||||||
|
*/
|
||||||
|
public void broadcast(FrequencyChangeEvent event)
|
||||||
|
{
|
||||||
|
if(mListener != null)
|
||||||
|
{
|
||||||
|
mListener.receive(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Broadcasts the current frequency of this tuner channel source to the downstream listener
|
||||||
|
*/
|
||||||
|
public void broadcastCurrentFrequency()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
long frequency = getFrequency();
|
||||||
|
broadcast(new FrequencyChangeEvent(Event.NOTIFICATION_FREQUENCY_CHANGE, frequency));
|
||||||
|
}
|
||||||
|
catch(SourceException se)
|
||||||
|
{
|
||||||
|
mLog.error("Error obtaining frequency from tuner to broadcast downstream");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Broadcasts the current decimated sample rate of this tuner channel source
|
||||||
|
*/
|
||||||
|
public void broadcastCurrentSampleRate()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//Note: downstream sample rate is currently a fixed value -- it will change in the future
|
||||||
|
broadcast(new FrequencyChangeEvent(Event.NOTIFICATION_SAMPLE_RATE_CHANGE, getSampleRate()));
|
||||||
|
}
|
||||||
|
catch(SourceException se)
|
||||||
|
{
|
||||||
|
mLog.error("Error obtaining sample rate from tuner to broadcast downstream");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the downstream listener to receive frequency change events from this tuner channel source
|
||||||
|
* @param listener to receive events
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setFrequencyChangeListener(Listener<FrequencyChangeEvent> listener)
|
||||||
|
{
|
||||||
|
mListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the downstream listener from receiving frequency change events.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void removeFrequencyChangeListener()
|
||||||
|
{
|
||||||
|
mListener = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener for receiving frequency change events from downstream components
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Listener<FrequencyChangeEvent> getFrequencyChangeListener()
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes frequency change events from downstream components.
|
||||||
|
* @param event to process
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void receive(FrequencyChangeEvent event)
|
||||||
|
{
|
||||||
|
switch(event.getEvent())
|
||||||
|
{
|
||||||
|
//Frequency correction requests are the only change requests supported from downstream components
|
||||||
|
case REQUEST_CHANNEL_FREQUENCY_CORRECTION_CHANGE:
|
||||||
|
setFrequencyCorrection(event.getValue().intValue());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decimates an inbound buffer of I/Q samples from the source down to the
|
* Decimates an inbound buffer of I/Q samples from the source down to the
|
||||||
* standard 48000 channel sample rate
|
* standard 48000 channel sample rate
|
||||||
|
|||||||
@@ -1,9 +1,30 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* sdrtrunk
|
||||||
|
* Copyright (C) 2014-2017 Dennis Sheirer
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
package source.tuner.frequency;
|
package source.tuner.frequency;
|
||||||
|
|
||||||
import sample.Listener;
|
import sample.Listener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provider of Frequency Change Events
|
||||||
|
*/
|
||||||
public interface IFrequencyChangeProvider
|
public interface IFrequencyChangeProvider
|
||||||
{
|
{
|
||||||
public void setFrequencyChangeListener( Listener<FrequencyChangeEvent> listener );
|
void setFrequencyChangeListener( Listener<FrequencyChangeEvent> listener );
|
||||||
public void removeFrequencyChangeListener();
|
void removeFrequencyChangeListener();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* SDR Trunk
|
* sdrtrunk
|
||||||
* Copyright (C) 2014,2015 Dennis Sheirer
|
* Copyright (C) 2014-2017 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package source.wave;
|
package source.wave;
|
||||||
|
|
||||||
@@ -36,6 +37,7 @@ import sample.complex.ComplexBuffer;
|
|||||||
import source.ComplexSource;
|
import source.ComplexSource;
|
||||||
import source.IControllableFileSource;
|
import source.IControllableFileSource;
|
||||||
import source.IFrameLocationListener;
|
import source.IFrameLocationListener;
|
||||||
|
import source.tuner.frequency.FrequencyChangeEvent;
|
||||||
|
|
||||||
public class ComplexWaveSource extends ComplexSource implements IControllableFileSource
|
public class ComplexWaveSource extends ComplexSource implements IControllableFileSource
|
||||||
{
|
{
|
||||||
@@ -55,6 +57,25 @@ public class ComplexWaveSource extends ComplexSource implements IControllableFil
|
|||||||
mFile = file;
|
mFile = file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFrequencyChangeListener(Listener<FrequencyChangeEvent> listener)
|
||||||
|
{
|
||||||
|
//Not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeFrequencyChangeListener()
|
||||||
|
{
|
||||||
|
//Not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Listener<FrequencyChangeEvent> getFrequencyChangeListener()
|
||||||
|
{
|
||||||
|
//Not implemented
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reset()
|
public void reset()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import sample.real.RealBuffer;
|
|||||||
import source.IControllableFileSource;
|
import source.IControllableFileSource;
|
||||||
import source.IFrameLocationListener;
|
import source.IFrameLocationListener;
|
||||||
import source.RealSource;
|
import source.RealSource;
|
||||||
|
import source.tuner.frequency.FrequencyChangeEvent;
|
||||||
|
|
||||||
public class RealWaveSource extends RealSource
|
public class RealWaveSource extends RealSource
|
||||||
implements IControllableFileSource, AutoCloseable
|
implements IControllableFileSource, AutoCloseable
|
||||||
@@ -56,6 +57,25 @@ public class RealWaveSource extends RealSource
|
|||||||
mFile = file;
|
mFile = file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFrequencyChangeListener(Listener<FrequencyChangeEvent> listener)
|
||||||
|
{
|
||||||
|
//Not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeFrequencyChangeListener()
|
||||||
|
{
|
||||||
|
//Not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Listener<FrequencyChangeEvent> getFrequencyChangeListener()
|
||||||
|
{
|
||||||
|
//Not implemented
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reset()
|
public void reset()
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ public class OverlayPanel extends JPanel implements ChannelEventListener, IFrequ
|
|||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private final static Logger mLog = LoggerFactory.getLogger(OverlayPanel.class);
|
private final static Logger mLog = LoggerFactory.getLogger(OverlayPanel.class);
|
||||||
|
private final DecimalFormat PPM_FORMATTER = new DecimalFormat( "#.0" );
|
||||||
|
|
||||||
private final static RenderingHints RENDERING_HINTS = new RenderingHints(RenderingHints.KEY_ANTIALIASING,
|
private final static RenderingHints RENDERING_HINTS = new RenderingHints(RenderingHints.KEY_ANTIALIASING,
|
||||||
RenderingHints.VALUE_ANTIALIAS_ON);
|
RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
@@ -187,7 +188,6 @@ public class OverlayPanel extends JPanel implements ChannelEventListener, IFrequ
|
|||||||
* 6 64x Zoom
|
* 6 64x Zoom
|
||||||
*
|
*
|
||||||
* @param zoom level, 0 - 6.
|
* @param zoom level, 0 - 6.
|
||||||
* @param offset into the FFT bins for start zoom window
|
|
||||||
*/
|
*/
|
||||||
public void setZoom(int zoom)
|
public void setZoom(int zoom)
|
||||||
{
|
{
|
||||||
@@ -412,20 +412,41 @@ public class OverlayPanel extends JPanel implements ChannelEventListener, IFrequ
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws a vertical line at the xaxis
|
* Draws the Automatic Frequency Control (AFC) channel center offset
|
||||||
*/
|
*/
|
||||||
private void drawAFC(Graphics2D graphics, double frequencyAxis, double errorAxis)
|
private void drawAFC(Graphics2D graphics, double frequencyAxis, double errorAxis, double bandwidth,
|
||||||
|
int correction, long frequency)
|
||||||
{
|
{
|
||||||
double height = getSize().getHeight() - mSpectrumInset;
|
double height = getSize().getHeight() - mSpectrumInset;
|
||||||
double lineHeight = height * 0.75d;
|
double verticalAxisTop = height * 0.88d;
|
||||||
|
double verticalAxisBottom = height * 0.98d;
|
||||||
|
|
||||||
|
double halfBandwidth = bandwidth / 2.0;
|
||||||
|
double errorEdgeStart = errorAxis - halfBandwidth;
|
||||||
|
double errorEdgeStop = errorAxis + halfBandwidth;
|
||||||
|
|
||||||
graphics.setColor(Color.YELLOW);
|
graphics.setColor(Color.YELLOW);
|
||||||
|
|
||||||
//Vertical frequency error line
|
//Horizontal line connecting frequency and error line
|
||||||
graphics.draw(new Line2D.Double(errorAxis, lineHeight, errorAxis, height - 1.0d));
|
graphics.draw(new Line2D.Double(errorEdgeStart, verticalAxisBottom, errorEdgeStop, verticalAxisBottom));
|
||||||
|
|
||||||
//Horizontal line connecting frequency and error lines
|
//Vertical band edge lines
|
||||||
graphics.draw(new Line2D.Double(frequencyAxis, lineHeight, errorAxis, lineHeight));
|
graphics.draw(new Line2D.Double(errorEdgeStart, verticalAxisTop, errorEdgeStart, verticalAxisBottom));
|
||||||
|
graphics.draw(new Line2D.Double(errorEdgeStop, verticalAxisTop, errorEdgeStop, verticalAxisBottom));
|
||||||
|
|
||||||
|
double ppm = (double)correction / ((double)frequency / 1E6d);
|
||||||
|
|
||||||
|
String label = "PPM " + PPM_FORMATTER.format(ppm) ;
|
||||||
|
|
||||||
|
FontMetrics fontMetrics = graphics.getFontMetrics(this.getFont());
|
||||||
|
|
||||||
|
Rectangle2D rect = fontMetrics.getStringBounds(label, graphics);
|
||||||
|
|
||||||
|
//Only render the correction value label if the spacing is large enough
|
||||||
|
if(rect.getWidth() <= bandwidth && rect.getHeight() * 5 <= height)
|
||||||
|
{
|
||||||
|
graphics.drawString(label, (float)(errorEdgeStart + 1.0), (float)(verticalAxisBottom - 2.0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -564,7 +585,8 @@ public class OverlayPanel extends JPanel implements ChannelEventListener, IFrequ
|
|||||||
{
|
{
|
||||||
long error = frequency + correction;
|
long error = frequency + correction;
|
||||||
|
|
||||||
drawAFC(graphics, frequencyAxis, getAxisFromFrequency(error));
|
drawAFC(graphics, frequencyAxis, getAxisFromFrequency(error), width, correction,
|
||||||
|
tunerChannel.getFrequency());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* SDR Trunk
|
* sdrtrunk
|
||||||
* Copyright (C) 2014,2015 Dennis Sheirer
|
* Copyright (C) 2014-2017 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -14,56 +14,43 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package spectrum;
|
package spectrum;
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.awt.GradientPaint;
|
|
||||||
import java.awt.Graphics;
|
|
||||||
import java.awt.Graphics2D;
|
|
||||||
import java.awt.Rectangle;
|
|
||||||
import java.awt.RenderingHints;
|
|
||||||
import java.awt.geom.GeneralPath;
|
|
||||||
import java.awt.geom.Line2D;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.Validate;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import settings.ColorSetting;
|
|
||||||
import settings.ColorSetting.ColorSettingName;
|
|
||||||
import settings.Setting;
|
|
||||||
import settings.SettingChangeListener;
|
|
||||||
import settings.SettingsManager;
|
|
||||||
import dsp.filter.smoothing.GaussianSmoothingFilter;
|
import dsp.filter.smoothing.GaussianSmoothingFilter;
|
||||||
import dsp.filter.smoothing.NoSmoothingFilter;
|
import dsp.filter.smoothing.NoSmoothingFilter;
|
||||||
import dsp.filter.smoothing.RectangularSmoothingFilter;
|
import dsp.filter.smoothing.RectangularSmoothingFilter;
|
||||||
import dsp.filter.smoothing.SmoothingFilter;
|
import dsp.filter.smoothing.SmoothingFilter;
|
||||||
import dsp.filter.smoothing.SmoothingFilter.SmoothingType;
|
import dsp.filter.smoothing.SmoothingFilter.SmoothingType;
|
||||||
import dsp.filter.smoothing.TriangularSmoothingFilter;
|
import dsp.filter.smoothing.TriangularSmoothingFilter;
|
||||||
|
import org.apache.commons.lang3.Validate;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import settings.ColorSetting;
|
||||||
|
import settings.ColorSetting.ColorSettingName;
|
||||||
|
import settings.Setting;
|
||||||
|
import settings.SettingChangeListener;
|
||||||
|
import settings.SettingsManager;
|
||||||
|
|
||||||
public class SpectrumPanel extends JPanel
|
import javax.swing.*;
|
||||||
implements DFTResultsListener,
|
import java.awt.*;
|
||||||
SettingChangeListener,
|
import java.awt.geom.GeneralPath;
|
||||||
SpectralDisplayAdjuster
|
import java.awt.geom.Line2D;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class SpectrumPanel extends JPanel implements DFTResultsListener, SettingChangeListener, SpectralDisplayAdjuster
|
||||||
{
|
{
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private final static Logger mLog =
|
private final static Logger mLog = LoggerFactory.getLogger(SpectrumPanel.class);
|
||||||
LoggerFactory.getLogger( SpectrumPanel.class );
|
|
||||||
|
|
||||||
private static final RenderingHints RENDERING_HINTS =
|
private static final RenderingHints RENDERING_HINTS =
|
||||||
new RenderingHints( RenderingHints.KEY_ANTIALIASING,
|
new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
RenderingHints.VALUE_ANTIALIAS_ON );
|
|
||||||
|
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
RENDERING_HINTS.put( RenderingHints.KEY_RENDERING,
|
RENDERING_HINTS.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
|
||||||
RenderingHints.VALUE_RENDER_QUALITY );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Color mColorSpectrumBackground;
|
private Color mColorSpectrumBackground;
|
||||||
@@ -87,7 +74,8 @@ public class SpectrumPanel extends JPanel
|
|||||||
private float mDBScale;
|
private float mDBScale;
|
||||||
|
|
||||||
private int mZoom = 0;
|
private int mZoom = 0;
|
||||||
private int mZoomWindowOffset = 0;;
|
private int mZoomWindowOffset = 0;
|
||||||
|
;
|
||||||
|
|
||||||
private SettingsManager mSettingsManager;
|
private SettingsManager mSettingsManager;
|
||||||
|
|
||||||
@@ -278,12 +266,13 @@ public class SpectrumPanel extends JPanel
|
|||||||
* 3 8x Zoom
|
* 3 8x Zoom
|
||||||
* 4 16x Zoom
|
* 4 16x Zoom
|
||||||
* 5 32x Zoom
|
* 5 32x Zoom
|
||||||
|
* 6 64x Zoom
|
||||||
*
|
*
|
||||||
* @param zoom level, 0 - 5.
|
* @param zoom level, 0 - 6.
|
||||||
*/
|
*/
|
||||||
public void setZoom(int zoom)
|
public void setZoom(int zoom)
|
||||||
{
|
{
|
||||||
Validate.isTrue( 0 <= zoom && zoom <= 5 );
|
Validate.isTrue(0 <= zoom && zoom <= 6, "Unrecognized Zoom Level: " + zoom);
|
||||||
|
|
||||||
mZoom = zoom;
|
mZoom = zoom;
|
||||||
}
|
}
|
||||||
@@ -427,7 +416,8 @@ public class SpectrumPanel extends JPanel
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void settingDeleted( Setting setting ) { /* not implemented */ }
|
public void settingDeleted(Setting setting)
|
||||||
|
{ /* not implemented */ }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current inter-bin smoothing setting
|
* Returns the current inter-bin smoothing setting
|
||||||
|
|||||||
Reference in New Issue
Block a user