Performance improvements (#746)

* Misc minor performance improvements

* Use more concise loop syntax

* Use more concise Collection sort syntax

* Use StringUtils pad methods

* Optimize some loops and double-map-lookups

* Optimize array instantiation

There are two styles to convert a collection to an array: either
using a pre-sized array (like c.toArray(new String[c.size()])) or
using an empty array (like c.toArray(new String[0]).

In older Java versions using pre-sized array was recommended,
as the reflection call which is necessary to create an array
of proper size was quite slow. However since late updates of
OpenJDK 6 this call was intrinsified, making the performance
of the empty array version the same and sometimes even better,
compared to the pre-sized version. Also passing pre-sized array
is dangerous for a concurrent or synchronized collection as
a data race is possible between the size and toArray call
which may result in extra nulls at the end of the array,
if the collection was concurrently shrunk during the operation.

* Cleanup string concatenation

* Use EnumMap where possible

* Use FastMath instead of Math

* Initialize complex things only once

* Reduce method size to aloow more JIT inlining

* remove map of short->float

* Move field to local variable

* Cleanup Map lookup

Co-authored-by: Rob Ekl <xwq876@zebra.com>
This commit is contained in:
robekl
2020-04-25 07:57:56 -04:00
committed by GitHub
parent 649258bd2b
commit 39f6d6c831
186 changed files with 2840 additions and 3464 deletions

View File

@@ -45,13 +45,7 @@ import io.github.dsheirer.sample.Listener;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.ArrayList; import java.util.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
/** /**
* List of aliases that share the same alias list name and provides convenient methods for looking up alias * List of aliases that share the same alias list name and provides convenient methods for looking up alias
@@ -60,8 +54,8 @@ import java.util.TreeMap;
public class AliasList implements Listener<AliasEvent> public class AliasList implements Listener<AliasEvent>
{ {
private final static Logger mLog = LoggerFactory.getLogger(AliasList.class); private final static Logger mLog = LoggerFactory.getLogger(AliasList.class);
private Map<Protocol,TalkgroupAliasList> mTalkgroupProtocolMap = new HashMap<>(); private Map<Protocol,TalkgroupAliasList> mTalkgroupProtocolMap = new EnumMap<>(Protocol.class);
private Map<Protocol,RadioAliasList> mRadioProtocolMap = new HashMap<>(); private Map<Protocol,RadioAliasList> mRadioProtocolMap = new EnumMap<>(Protocol.class);
private Map<String,Alias> mESNMap = new HashMap<>(); private Map<String,Alias> mESNMap = new HashMap<>();
private Map<Integer,Alias> mStatusMap = new HashMap<>(); private Map<Integer,Alias> mStatusMap = new HashMap<>();
private boolean mHasAliasActions = false; private boolean mHasAliasActions = false;
@@ -487,15 +481,7 @@ public class AliasList implements Listener<AliasEvent>
*/ */
public static void remove(Alias alias, Map map) public static void remove(Alias alias, Map map)
{ {
Iterator<Map.Entry> it = map.entrySet().iterator(); map.entrySet().removeIf(entry -> alias.equals(((Map.Entry)entry).getValue()));
while(it.hasNext())
{
if(it.next().getValue().equals(alias))
{
it.remove();
}
}
} }
@@ -515,16 +501,17 @@ public class AliasList implements Listener<AliasEvent>
{ {
int value = identifier.getValue(); int value = identifier.getValue();
if(mTalkgroupAliasMap.containsKey(value)) Alias mapValue = mTalkgroupAliasMap.get(value);
if (mapValue != null)
{ {
return mTalkgroupAliasMap.get(value); return mapValue;
} }
for(TalkgroupRange talkgroupRange: mTalkgroupRangeAliasMap.keySet()) for(Map.Entry<TalkgroupRange, Alias> entry : mTalkgroupRangeAliasMap.entrySet())
{ {
if(talkgroupRange.contains(value)) if(entry.getKey().contains(value))
{ {
return mTalkgroupRangeAliasMap.get(talkgroupRange); return entry.getValue();
} }
} }
@@ -601,16 +588,17 @@ public class AliasList implements Listener<AliasEvent>
{ {
int value = identifier.getValue(); int value = identifier.getValue();
if(mRadioAliasMap.containsKey(value)) Alias mapValue = mRadioAliasMap.get(value);
if(mapValue != null)
{ {
return mRadioAliasMap.get(value); return mapValue;
} }
for(RadioRange radioRange: mRadioRangeAliasMap.keySet()) for(Map.Entry<RadioRange, Alias> entry : mRadioRangeAliasMap.entrySet())
{ {
if(radioRange.contains(value)) if(entry.getKey().contains(value))
{ {
return mRadioRangeAliasMap.get(radioRange); return entry.getValue();
} }
} }

View File

@@ -117,9 +117,9 @@ public class AliasModel extends AbstractTableModel
return new AliasList(name); return new AliasList(name);
} }
if(mAliasListMap.containsKey(name)) AliasList mapValue = mAliasListMap.get(name);
{ if (mapValue != null) {
return mAliasListMap.get(name); return mapValue;
} }
AliasList aliasList = new AliasList(name); AliasList aliasList = new AliasList(name);

View File

@@ -115,7 +115,7 @@ public class AliasNameEditor extends Editor<Alias>
else else
{ {
mGroupCombo.setModel(new DefaultComboBoxModel<String>( mGroupCombo.setModel(new DefaultComboBoxModel<String>(
groups.toArray(new String[groups.size()]))); groups.toArray(new String[0])));
; ;
} }
} }
@@ -243,7 +243,7 @@ public class AliasNameEditor extends Editor<Alias>
else else
{ {
mListCombo.setModel(new DefaultComboBoxModel<String>( mListCombo.setModel(new DefaultComboBoxModel<String>(
listNames.toArray(new String[listNames.size()]))); listNames.toArray(new String[0])));
; ;
} }
@@ -258,7 +258,7 @@ public class AliasNameEditor extends Editor<Alias>
else else
{ {
mGroupCombo.setModel(new DefaultComboBoxModel<String>( mGroupCombo.setModel(new DefaultComboBoxModel<String>(
groupNames.toArray(new String[groupNames.size()]))); groupNames.toArray(new String[0])));
; ;
} }

View File

@@ -266,15 +266,15 @@ public class MultipleAliasEditor extends Editor<List<Alias>>
List<String> listNames = mAliasModel.getListNames(); List<String> listNames = mAliasModel.getListNames();
listNames.add(0, ""); listNames.add(0, "");
mListCombo.setModel(new DefaultComboBoxModel<String>( mListCombo.setModel(new DefaultComboBoxModel<String>(
listNames.toArray(new String[listNames.size()]))); listNames.toArray(new String[0])));
List<String> groupNames = mAliasModel.getGroupNames(); List<String> groupNames = mAliasModel.getGroupNames();
groupNames.add(0, ""); groupNames.add(0, "");
mGroupCombo.setModel(new DefaultComboBoxModel<String>( mGroupCombo.setModel(new DefaultComboBoxModel<String>(
groupNames.toArray(new String[groupNames.size()]))); groupNames.toArray(new String[0])));
List<String> streamNames = mBroadcastModel.getBroadcastConfigurationNames(); List<String> streamNames = mBroadcastModel.getBroadcastConfigurationNames();
mStreamCombo.setModel(new DefaultComboBoxModel<String>(streamNames.toArray(new String[streamNames.size()]))); mStreamCombo.setModel(new DefaultComboBoxModel<String>(streamNames.toArray(new String[0])));
mIconCombo.setModel(new DefaultComboBoxModel<>(mIconManager.getIcons())); mIconCombo.setModel(new DefaultComboBoxModel<>(mIconManager.getIcons()));
@@ -300,12 +300,12 @@ public class MultipleAliasEditor extends Editor<List<Alias>>
List<String> listNames = mAliasModel.getListNames(); List<String> listNames = mAliasModel.getListNames();
listNames.add(0, ""); listNames.add(0, "");
mListCombo.setModel(new DefaultComboBoxModel<String>( mListCombo.setModel(new DefaultComboBoxModel<String>(
listNames.toArray(new String[listNames.size()]))); listNames.toArray(new String[0])));
List<String> groupNames = mAliasModel.getGroupNames(); List<String> groupNames = mAliasModel.getGroupNames();
groupNames.add(0, ""); groupNames.add(0, "");
mGroupCombo.setModel(new DefaultComboBoxModel<String>( mGroupCombo.setModel(new DefaultComboBoxModel<String>(
groupNames.toArray(new String[groupNames.size()]))); groupNames.toArray(new String[0])));
mButtonColor.setForeground(getForeground()); mButtonColor.setForeground(getForeground());
mButtonColor.setBackground(getBackground()); mButtonColor.setBackground(getBackground());

View File

@@ -188,14 +188,7 @@ public class AliasActionEditor extends Editor<Alias>
List<AliasAction> actions = alias.getAction(); List<AliasAction> actions = alias.getAction();
Collections.sort( actions, new Comparator<AliasAction>() actions.sort(Comparator.comparing(Object::toString));
{
@Override
public int compare( AliasAction o1, AliasAction o2 )
{
return o1.toString().compareTo( o2.toString() );
}
} );
for( AliasAction action: actions ) for( AliasAction action: actions )
{ {

View File

@@ -227,14 +227,7 @@ public class AliasIdentifierEditor extends Editor<Alias>
List<AliasID> ids = alias.getId(); List<AliasID> ids = alias.getId();
Collections.sort(ids, new Comparator<AliasID>() ids.sort(Comparator.comparing(Object::toString));
{
@Override
public int compare(AliasID o1, AliasID o2)
{
return o1.toString().compareTo(o2.toString());
}
});
for(AliasID id : ids) for(AliasID id : ids)
{ {

View File

@@ -19,6 +19,7 @@
package io.github.dsheirer.alias.id; package io.github.dsheirer.alias.id;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.apache.commons.math3.util.FastMath;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@@ -95,12 +96,12 @@ public class WildcardID implements Comparable<WildcardID>
{ {
if(mValue.substring(x, x + 1).equals(WILDCARD)) if(mValue.substring(x, x + 1).equals(WILDCARD))
{ {
weight += (int)(Math.pow(2, mValue.length() - x - 1)); //Position weight weight += (int)(FastMath.pow(2, mValue.length() - x - 1)); //Position weight
characterCount++; characterCount++;
} }
} }
weight += (int)(Math.pow(2, characterCount)) * 1000; //Character count weight weight += (int)(FastMath.pow(2, characterCount)) * 1000; //Character count weight
return weight; return weight;
} }

View File

@@ -61,7 +61,7 @@ public class BroadcastChannelEditor extends DocumentListenerEditor<AliasID>
List<String> channelNames = mBroadcastModel.getBroadcastConfigurationNames(); List<String> channelNames = mBroadcastModel.getBroadcastConfigurationNames();
mBroadcastConfigurations = new JComboBox<String>(channelNames.toArray(new String[channelNames.size()])); mBroadcastConfigurations = new JComboBox<String>(channelNames.toArray(new String[0]));
mBroadcastConfigurations.addActionListener(new ActionListener() mBroadcastConfigurations.addActionListener(new ActionListener()
{ {
@Override @Override

View File

@@ -29,6 +29,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.text.ParseException; import java.text.ParseException;
import java.util.EnumMap;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@@ -38,7 +39,7 @@ import java.util.Map;
public class RadioFormatter public class RadioFormatter
{ {
private final static Logger mLog = LoggerFactory.getLogger(RadioFormatter.class); private final static Logger mLog = LoggerFactory.getLogger(RadioFormatter.class);
private static Map<Protocol,IntegerFormatter> mFormatterMap = new HashMap<>(); private static Map<Protocol,IntegerFormatter> mFormatterMap = new EnumMap<>(Protocol.class);
static static
{ {

View File

@@ -32,6 +32,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.text.ParseException; import java.text.ParseException;
import java.util.EnumMap;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@@ -41,7 +42,7 @@ import java.util.Map;
public class TalkgroupFormatter public class TalkgroupFormatter
{ {
private final static Logger mLog = LoggerFactory.getLogger(TalkgroupFormatter.class); private final static Logger mLog = LoggerFactory.getLogger(TalkgroupFormatter.class);
private static Map<Protocol,IntegerFormatter> mFormatterMap = new HashMap<>(); private static Map<Protocol,IntegerFormatter> mFormatterMap = new EnumMap<>(Protocol.class);
static static
{ {

View File

@@ -384,10 +384,7 @@ public class AudioSegment implements Listener<IdentifierUpdateNotification>
} }
//Add all broadcast channels for the alias ... let the set handle duplication. //Add all broadcast channels for the alias ... let the set handle duplication.
for(BroadcastChannel broadcastChannel: alias.getBroadcastChannels()) mBroadcastChannels.addAll(alias.getBroadcastChannels());
{
mBroadcastChannels.add(broadcastChannel);
}
//Only assign a playback priority if it is lower priority than the current setting. //Only assign a playback priority if it is lower priority than the current setting.
int playbackPriority = alias.getPlaybackPriority(); int playbackPriority = alias.getPlaybackPriority();

View File

@@ -25,6 +25,7 @@ import io.github.dsheirer.audio.convert.ISilenceGenerator;
import io.github.dsheirer.identifier.IdentifierCollection; import io.github.dsheirer.identifier.IdentifierCollection;
import io.github.dsheirer.sample.Listener; import io.github.dsheirer.sample.Listener;
import io.github.dsheirer.util.ThreadPool; import io.github.dsheirer.util.ThreadPool;
import org.apache.commons.math3.util.FastMath;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -360,7 +361,7 @@ public abstract class AudioBroadcaster implements Listener<AudioRecording>
//Trim length to whole-frame intervals (144 byte frame) //Trim length to whole-frame intervals (144 byte frame)
bytesToStream -= (bytesToStream % 144); bytesToStream -= (bytesToStream % 144);
int length = Math.min(bytesToStream, mInputStream.available()); int length = FastMath.min(bytesToStream, mInputStream.available());
byte[] audio = new byte[length]; byte[] audio = new byte[length];

View File

@@ -174,7 +174,7 @@ public class UserFeedSelectionDialog extends JDialog implements DocumentListener
mLog.info("RR User:" + userInfo.getUserName() + " Expiration Date:" + userInfo.getExpirationDate()); mLog.info("RR User:" + userInfo.getUserName() + " Expiration Date:" + userInfo.getExpirationDate());
List<UserFeedBroadcast> feeds = service.getUserFeeds(); List<UserFeedBroadcast> feeds = service.getUserFeeds();
mUserFeedBroadcastList.setListData(feeds.toArray(new UserFeedBroadcast[feeds.size()])); mUserFeedBroadcastList.setListData(feeds.toArray(new UserFeedBroadcast[0]));
} }
catch(RadioReferenceException rre) catch(RadioReferenceException rre)
{ {

View File

@@ -50,6 +50,7 @@ import io.github.dsheirer.identifier.IdentifierCollection;
import io.github.dsheirer.identifier.Role; import io.github.dsheirer.identifier.Role;
import io.github.dsheirer.properties.SystemProperties; import io.github.dsheirer.properties.SystemProperties;
import io.github.dsheirer.util.ThreadPool; import io.github.dsheirer.util.ThreadPool;
import org.apache.commons.math3.util.FastMath;
import org.apache.mina.core.RuntimeIoException; import org.apache.mina.core.RuntimeIoException;
import org.apache.mina.core.future.ConnectFuture; import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoHandlerAdapter; import org.apache.mina.core.service.IoHandlerAdapter;
@@ -363,7 +364,7 @@ public class ShoutcastV2AudioBroadcaster extends AudioBroadcaster implements IBr
int pointer = 0; int pointer = 0;
int messageCounter = 1; int messageCounter = 1;
int messageCount = (int) Math.ceil((double) xml.length / (double) (mMaxPayloadSize - 6)); int messageCount = (int) FastMath.ceil((double) xml.length / (double) (mMaxPayloadSize - 6));
if(messageCount > 32) if(messageCount > 32)
{ {
@@ -375,7 +376,7 @@ public class ShoutcastV2AudioBroadcaster extends AudioBroadcaster implements IBr
while(pointer < xml.length && messageCounter <= messageCount) while(pointer < xml.length && messageCounter <= messageCount)
{ {
int payloadSize = Math.min(mMaxPayloadSize - 6, xml.length - pointer); int payloadSize = FastMath.min(mMaxPayloadSize - 6, xml.length - pointer);
byte[] payload = new byte[payloadSize + 6]; byte[] payload = new byte[payloadSize + 6];

View File

@@ -23,6 +23,7 @@ import io.github.dsheirer.audio.AudioUtils;
import net.sourceforge.lame.lowlevel.LameEncoder; import net.sourceforge.lame.lowlevel.LameEncoder;
import net.sourceforge.lame.mp3.Lame; import net.sourceforge.lame.mp3.Lame;
import net.sourceforge.lame.mp3.MPEGMode; import net.sourceforge.lame.mp3.MPEGMode;
import org.apache.commons.math3.util.FastMath;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -59,7 +60,7 @@ public class MP3AudioConverter implements IAudioConverter
byte[] pcmBytes = AudioUtils.convertTo16BitSamples(audioPackets); byte[] pcmBytes = AudioUtils.convertTo16BitSamples(audioPackets);
int pcmBufferSize = Math.min(mMP3Buffer.length, pcmBytes.length); int pcmBufferSize = FastMath.min(mMP3Buffer.length, pcmBytes.length);
int mp3BufferSize = 0; int mp3BufferSize = 0;
@@ -70,7 +71,7 @@ public class MP3AudioConverter implements IAudioConverter
while (0 < (mp3BufferSize = mEncoder.encodeBuffer(pcmBytes, pcmBytesPosition, pcmBufferSize, mMP3Buffer))) while (0 < (mp3BufferSize = mEncoder.encodeBuffer(pcmBytes, pcmBytesPosition, pcmBufferSize, mMP3Buffer)))
{ {
pcmBytesPosition += pcmBufferSize; pcmBytesPosition += pcmBufferSize;
pcmBufferSize = Math.min(mMP3Buffer.length, pcmBytes.length - pcmBytesPosition); pcmBufferSize = FastMath.min(mMP3Buffer.length, pcmBytes.length - pcmBytesPosition);
mMP3Stream.write(mMP3Buffer, 0, mp3BufferSize); mMP3Stream.write(mMP3Buffer, 0, mp3BufferSize);
} }
@@ -89,7 +90,7 @@ public class MP3AudioConverter implements IAudioConverter
byte[] pcmBytes = AudioUtils.convert(audioBuffers); byte[] pcmBytes = AudioUtils.convert(audioBuffers);
int pcmBufferSize = Math.min(mMP3Buffer.length, pcmBytes.length); int pcmBufferSize = FastMath.min(mMP3Buffer.length, pcmBytes.length);
int mp3BufferSize = 0; int mp3BufferSize = 0;
@@ -100,7 +101,7 @@ public class MP3AudioConverter implements IAudioConverter
while (0 < (mp3BufferSize = mEncoder.encodeBuffer(pcmBytes, pcmBytesPosition, pcmBufferSize, mMP3Buffer))) while (0 < (mp3BufferSize = mEncoder.encodeBuffer(pcmBytes, pcmBytesPosition, pcmBufferSize, mMP3Buffer)))
{ {
pcmBytesPosition += pcmBufferSize; pcmBytesPosition += pcmBufferSize;
pcmBufferSize = Math.min(mMP3Buffer.length, pcmBytes.length - pcmBytesPosition); pcmBufferSize = FastMath.min(mMP3Buffer.length, pcmBytes.length - pcmBytesPosition);
mMP3Stream.write(mMP3Buffer, 0, mp3BufferSize); mMP3Stream.write(mMP3Buffer, 0, mp3BufferSize);
} }

View File

@@ -195,7 +195,7 @@ public class AudioPlaybackManager implements Listener<AudioSegment>, IAudioContr
//Sort audio segments by playback priority and assign to empty audio outputs //Sort audio segments by playback priority and assign to empty audio outputs
if(!mAudioSegments.isEmpty()) if(!mAudioSegments.isEmpty())
{ {
Collections.sort(mAudioSegments, Comparator.comparingInt(o -> o.monitorPriorityProperty().get())); mAudioSegments.sort(Comparator.comparingInt(o -> o.monitorPriorityProperty().get()));
//Assign empty audio outputs first //Assign empty audio outputs first
for(AudioOutput audioOutput: mAudioOutputs) for(AudioOutput audioOutput: mAudioOutputs)
@@ -347,14 +347,7 @@ public class AudioPlaybackManager implements Listener<AudioSegment>, IAudioContr
{ {
List<AudioOutput> outputs = new ArrayList<>(mAudioOutputs); List<AudioOutput> outputs = new ArrayList<>(mAudioOutputs);
Collections.sort(outputs, new Comparator<AudioOutput>() outputs.sort(Comparator.comparing(AudioOutput::getChannelName));
{
@Override
public int compare(AudioOutput first, AudioOutput second)
{
return first.getChannelName().compareTo(second.getChannelName());
}
});
return outputs; return outputs;
} }

View File

@@ -23,6 +23,7 @@ package io.github.dsheirer.bits;
import io.github.dsheirer.edac.CRC; import io.github.dsheirer.edac.CRC;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.apache.commons.math3.util.FastMath;
import java.util.BitSet; import java.util.BitSet;
@@ -593,7 +594,7 @@ public class BinaryMessage extends BitSet
*/ */
public byte[] getBytes() public byte[] getBytes()
{ {
byte[] bytes = new byte[(int)Math.ceil((double)size() / 8.0)]; byte[] bytes = new byte[(int)FastMath.ceil((double)size() / 8.0)];
for(int x = 0; x < bytes.length; x++) for(int x = 0; x < bytes.length; x++)
{ {
@@ -795,7 +796,7 @@ public class BinaryMessage extends BitSet
*/ */
public int getInt(int start, int end) public int getInt(int start, int end)
{ {
if(Math.abs(end - start) > 32) if(FastMath.abs(end - start) > 32)
{ {
throw new IllegalArgumentException("Overflow - must be 32 bits " throw new IllegalArgumentException("Overflow - must be 32 bits "
+ "or less to fit into a primitive integer value"); + "or less to fit into a primitive integer value");
@@ -847,7 +848,7 @@ public class BinaryMessage extends BitSet
*/ */
public long getLong(int start, int end) public long getLong(int start, int end)
{ {
if(Math.abs(end - start) > 64) if(FastMath.abs(end - start) > 64)
{ {
throw new IllegalArgumentException("Overflow - must be 64 bits " throw new IllegalArgumentException("Overflow - must be 64 bits "
+ "or less to fit into a primitive long value"); + "or less to fit into a primitive long value");

View File

@@ -171,9 +171,8 @@ public class MessageFramer implements IBinarySymbolProcessor, Listener<Boolean>,
this(messageLength); this(messageLength);
/* Pre-load the message with the sync pattern */ /* Pre-load the message with the sync pattern */
for(int x = 0; x < initialFill.length; x++) for (boolean b : initialFill) {
{ receive(b);
receive(initialFill[x]);
} }
} }

View File

@@ -23,6 +23,7 @@ package io.github.dsheirer.bits;
import io.github.dsheirer.dsp.symbol.ISyncDetectListener; import io.github.dsheirer.dsp.symbol.ISyncDetectListener;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.apache.commons.math3.util.FastMath;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -57,7 +58,7 @@ public class MultiSyncPatternMatcher
Validate.isTrue(syncSize < 64); Validate.isTrue(syncSize < 64);
//Setup a bit mask of all ones the length of the sync pattern //Setup a bit mask of all ones the length of the sync pattern
mMask = (long)((Math.pow(2, syncSize)) - 1); mMask = (long)((FastMath.pow(2, syncSize)) - 1);
} }
public void dispose() public void dispose()

View File

@@ -18,6 +18,8 @@
package io.github.dsheirer.bits; package io.github.dsheirer.bits;
import org.apache.commons.math3.util.FastMath;
/** /**
* Sync pattern matcher. * Sync pattern matcher.
* *
@@ -37,7 +39,7 @@ public class SyncPatternMatcher
public SyncPatternMatcher(boolean[] syncPattern) public SyncPatternMatcher(boolean[] syncPattern)
{ {
//Setup a bit mask of all ones the length of the sync pattern //Setup a bit mask of all ones the length of the sync pattern
mMask = (long)((Math.pow(2, syncPattern.length)) - 1); mMask = (long)((FastMath.pow(2, syncPattern.length)) - 1);
//Convert the sync bits into a long value for comparison //Convert the sync bits into a long value for comparison
for(int x = 0; x < syncPattern.length; x++) for(int x = 0; x < syncPattern.length; x++)

View File

@@ -76,10 +76,8 @@ public class BooleanAveragingBuffer
mTrueCount = 0; mTrueCount = 0;
for(int x = 0; x < mBuffer.length; x++) for (boolean b : mBuffer) {
{ if (b) {
if(mBuffer[x])
{
mTrueCount++; mTrueCount++;
} }
} }

View File

@@ -55,6 +55,7 @@ import java.awt.Component;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.EnumMap;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -68,8 +69,8 @@ public class ChannelMetadataPanel extends JPanel implements ListSelectionListene
private UserPreferences mUserPreferences; private UserPreferences mUserPreferences;
private JTable mTable; private JTable mTable;
private Broadcaster<ProcessingChain> mSelectedProcessingChainBroadcaster = new Broadcaster<>(); private Broadcaster<ProcessingChain> mSelectedProcessingChainBroadcaster = new Broadcaster<>();
private Map<State,Color> mBackgroundColors = new HashMap<>(); private Map<State,Color> mBackgroundColors = new EnumMap<>(State.class);
private Map<State,Color> mForegroundColors = new HashMap<>(); private Map<State,Color> mForegroundColors = new EnumMap<>(State.class);
private JTableColumnWidthMonitor mTableColumnMonitor; private JTableColumnWidthMonitor mTableColumnMonitor;
/** /**

View File

@@ -128,11 +128,11 @@ public class DecoderStateEvent
{ {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("Decoder State Event - source[" + mSource.getClass() + sb.append("Decoder State Event - source[").append(mSource.getClass())
"] event[" + mEvent.toString() + .append("] event[").append(mEvent)
"] state[" + mState.toString() + .append("] state[").append(mState)
"] timeslot[" + mTimeslot + .append("] timeslot[").append(mTimeslot)
"] frequency [" + mFrequency + "]"); .append("] frequency [").append(mFrequency).append("]");
return sb.toString(); return sb.toString();
} }

View File

@@ -251,26 +251,16 @@ public class ChannelModel extends AbstractTableModel implements Listener<Channel
} }
} }
Collections.sort(autoStartChannels, new Comparator<Channel>() autoStartChannels.sort((channel1, channel2) -> {
{ if (channel1.hasAutoStartOrder() && channel2.hasAutoStartOrder()) {
@Override return Integer.compare(channel1.getAutoStartOrder(), channel2.getAutoStartOrder());
public int compare(Channel channel1, Channel channel2) } else if (channel1.hasAutoStartOrder()) {
{ return -1;
if(channel1.hasAutoStartOrder() && channel2.hasAutoStartOrder()) } else if (channel2.hasAutoStartOrder()) {
{ return 1;
return Integer.compare(channel1.getAutoStartOrder(), channel2.getAutoStartOrder());
}
else if(channel1.hasAutoStartOrder())
{
return -1;
}
else if(channel2.hasAutoStartOrder())
{
return 1;
}
return 0;
} }
return 0;
}); });
return autoStartChannels; return autoStartChannels;

View File

@@ -110,7 +110,7 @@ public class NameConfigurationEditor extends Editor<Channel> implements Document
else else
{ {
mSiteNameCombo.setModel(new DefaultComboBoxModel<String>( mSiteNameCombo.setModel(new DefaultComboBoxModel<String>(
sites.toArray(new String[sites.size()]))); sites.toArray(new String[0])));
; ;
} }
@@ -267,7 +267,7 @@ public class NameConfigurationEditor extends Editor<Channel> implements Document
else else
{ {
mSystemNameCombo.setModel(new DefaultComboBoxModel<String>( mSystemNameCombo.setModel(new DefaultComboBoxModel<String>(
systems.toArray(new String[systems.size()]))); systems.toArray(new String[0])));
; ;
} }
@@ -282,7 +282,7 @@ public class NameConfigurationEditor extends Editor<Channel> implements Document
else else
{ {
mSiteNameCombo.setModel(new DefaultComboBoxModel<String>( mSiteNameCombo.setModel(new DefaultComboBoxModel<String>(
sites.toArray(new String[sites.size()]))); sites.toArray(new String[0])));
; ;
} }
@@ -294,7 +294,7 @@ public class NameConfigurationEditor extends Editor<Channel> implements Document
List<String> lists = mAliasModel.getListNames(); List<String> lists = mAliasModel.getListNames();
Collections.sort(lists); Collections.sort(lists);
mAliasListCombo.setModel(new DefaultComboBoxModel<String>( mAliasListCombo.setModel(new DefaultComboBoxModel<String>(
lists.toArray(new String[lists.size()]))); lists.toArray(new String[0])));
if(channel.getAliasListName() != null) if(channel.getAliasListName() != null)
{ {

View File

@@ -60,13 +60,13 @@ public class ChannelRange
if(isValid()) if(isValid())
{ {
sb.append("First: "); sb.append("First: ");
sb.append(mFirst + "="); sb.append(mFirst).append("=");
long frequency = getFrequency(mFirst); long frequency = getFrequency(mFirst);
sb.append(FREQUENCY_FORMATTER.format((double)frequency / 1E6D)); sb.append(FREQUENCY_FORMATTER.format((double)frequency / 1E6D));
sb.append(" Last: "); sb.append(" Last: ");
sb.append(mLast + "="); sb.append(mLast).append("=");
frequency = getFrequency(mLast); frequency = getFrequency(mLast);
sb.append(FREQUENCY_FORMATTER.format((double)frequency / 1E6D)); sb.append(FREQUENCY_FORMATTER.format((double)frequency / 1E6D));

View File

@@ -26,6 +26,7 @@ import io.github.dsheirer.dsp.mixer.IOscillator;
import io.github.dsheirer.dsp.mixer.Oscillator; import io.github.dsheirer.dsp.mixer.Oscillator;
import io.github.dsheirer.sample.Listener; import io.github.dsheirer.sample.Listener;
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer; import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
import org.apache.commons.math3.util.FastMath;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -247,7 +248,7 @@ public class AFSK1200Decoder implements Listener<ReusableFloatBuffer>
//Add the absolute value of correlation accumulator value to the averaging buffer and store the current //Add the absolute value of correlation accumulator value to the averaging buffer and store the current
//average as the correlation value for this sample. We use absolute value because we don't care if the //average as the correlation value for this sample. We use absolute value because we don't care if the
//signal is out of phase with the reference samples //signal is out of phase with the reference samples
mCorrelationValues[x] = mAveragingBuffer.get(Math.abs(mCorrelationAccumulator)); mCorrelationValues[x] = mAveragingBuffer.get(FastMath.abs(mCorrelationAccumulator));
} }
return mCorrelationValues; return mCorrelationValues;

View File

@@ -19,6 +19,7 @@ import io.github.dsheirer.buffer.FloatAveragingBuffer;
import io.github.dsheirer.dsp.mixer.IOscillator; import io.github.dsheirer.dsp.mixer.IOscillator;
import io.github.dsheirer.dsp.mixer.Oscillator; import io.github.dsheirer.dsp.mixer.Oscillator;
import io.github.dsheirer.sample.complex.Complex; import io.github.dsheirer.sample.complex.Complex;
import org.apache.commons.math3.util.FastMath;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -110,8 +111,8 @@ public class AFSKTest
correlation1800 += reference1800[x] * samples[x + offset]; correlation1800 += reference1800[x] * samples[x + offset];
} }
correlation1200 = avg1200.get(Math.abs(correlation1200)); correlation1200 = avg1200.get(FastMath.abs(correlation1200));
correlation1800 = avg1800.get(Math.abs(correlation1800)); correlation1800 = avg1800.get(FastMath.abs(correlation1800));
mLog.debug(offset + " 1200:" + format(correlation1200) + " 1800:" + format(correlation1800) + mLog.debug(offset + " 1200:" + format(correlation1200) + " 1800:" + format(correlation1800) +
" Decision: " + (correlation1200 > correlation1800 ? "0" : "1")); " Decision: " + (correlation1200 > correlation1800 ? "0" : "1"));

View File

@@ -18,6 +18,7 @@ package io.github.dsheirer.dsp.am;
import io.github.dsheirer.sample.buffer.ReusableBufferQueue; import io.github.dsheirer.sample.buffer.ReusableBufferQueue;
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer; import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer; import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
import org.apache.commons.math3.util.FastMath;
/** /**
* Performs AM demodulation on baseband I/Q samples to produce demodulated float output. * Performs AM demodulation on baseband I/Q samples to produce demodulated float output.
@@ -55,7 +56,7 @@ public class AMDemodulator
*/ */
public float demodulate(float inphase, float quadrature) public float demodulate(float inphase, float quadrature)
{ {
return (float)Math.sqrt((inphase * inphase) + (quadrature * quadrature)) * mGain; return (float) FastMath.sqrt((inphase * inphase) + (quadrature * quadrature)) * mGain;
} }
/** /**

View File

@@ -26,6 +26,7 @@ import io.github.dsheirer.dsp.filter.design.FilterDesignException;
import io.github.dsheirer.dsp.filter.fir.FIRFilterSpecification; import io.github.dsheirer.dsp.filter.fir.FIRFilterSpecification;
import io.github.dsheirer.dsp.filter.fir.remez.RemezFIRFilterDesigner; import io.github.dsheirer.dsp.filter.fir.remez.RemezFIRFilterDesigner;
import io.github.dsheirer.dsp.filter.fir.remez.RemezFIRFilterDesignerWithLagrange; import io.github.dsheirer.dsp.filter.fir.remez.RemezFIRFilterDesignerWithLagrange;
import org.apache.commons.math3.util.FastMath;
import org.jtransforms.fft.FloatFFT_1D; import org.jtransforms.fft.FloatFFT_1D;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -109,9 +110,8 @@ public class FilterFactory
{ {
float accumulator = 0; float accumulator = 0;
for(int x = 0; x < coefficients.length; x++) for (float coefficient : coefficients) {
{ accumulator += FastMath.abs(coefficient);
accumulator += Math.abs(coefficients[x]);
} }
for(int x = 0; x < coefficients.length; x++) for(int x = 0; x < coefficients.length; x++)
@@ -133,9 +133,8 @@ public class FilterFactory
{ {
float accumulator = 0; float accumulator = 0;
for(int x = 0; x < coefficients.length; x++) for (float coefficient : coefficients) {
{ accumulator += FastMath.abs(coefficient);
accumulator += Math.abs(coefficients[x]);
} }
accumulator /= objective; accumulator /= objective;
@@ -171,7 +170,7 @@ public class FilterFactory
if(length % 2 == 0) //even length if(length % 2 == 0) //even length
{ {
int binCount = (int)((Math.round((float)frequency / (float)sampleRate * (float)length))); int binCount = (int)((FastMath.round((float)frequency / (float)sampleRate * (float)length)));
for(int x = 0; x < binCount; x++) for(int x = 0; x < binCount; x++)
{ {
@@ -181,7 +180,7 @@ public class FilterFactory
} }
else //odd length else //odd length
{ {
int binCount = (int)((Math.round((float)frequency / (float)sampleRate * (float)length + 0.5))); int binCount = (int)((FastMath.round((float)frequency / (float)sampleRate * (float)length + 0.5)));
unityArray[0] = 1.0f; unityArray[0] = 1.0f;
@@ -316,7 +315,7 @@ public class FilterFactory
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for(int x = 0; x < array.length; x++) for(int x = 0; x < array.length; x++)
{ {
sb.append(x + ": " + array[x]); sb.append(x).append(": ").append(array[x]);
if(breaks) if(breaks)
{ {
@@ -354,7 +353,7 @@ public class FilterFactory
{ {
double frequency = ((double)stop - (double)pass) / sampleRate; double frequency = ((double)stop - (double)pass) / sampleRate;
return (int)(Math.round((double)attenuation / (22.0d * frequency))); return (int)(FastMath.round((double)attenuation / (22.0d * frequency)));
} }
/** /**
@@ -431,7 +430,7 @@ public class FilterFactory
for(Integer factor : factors) for(Integer factor : factors)
{ {
int testDelta = Math.abs(desiredFactor - factor); int testDelta = FastMath.abs(desiredFactor - factor);
if(testDelta < bestDelta) if(testDelta < bestDelta)
{ {
@@ -484,7 +483,7 @@ public class FilterFactory
{ {
double ratio = getBandwidthRatio(passFrequency, stopFrequency); double ratio = getBandwidthRatio(passFrequency, stopFrequency);
double numerator = 1.0d - (Math.sqrt((double)decimation * ratio / (2.0d - ratio))); double numerator = 1.0d - (FastMath.sqrt((double)decimation * ratio / (2.0d - ratio)));
double denominator = 2.0d - (ratio * (decimation + 1.0d)); double denominator = 2.0d - (ratio * (decimation + 1.0d));
@@ -559,18 +558,18 @@ public class FilterFactory
{ {
float[] cicArray = new float[length * 2]; float[] cicArray = new float[length * 2];
int binCount = (int)((Math.round( int binCount = (int)((FastMath.round(
(double)frequency / (double)sampleRate * 2.0d * (double)length))); (double)frequency / (double)sampleRate * 2.0d * (double)length)));
cicArray[0] = 1.0f; cicArray[0] = 1.0f;
float unityResponse = (float)(Math.sin(1.0d / (double)length) / float unityResponse = (float)(FastMath.sin(1.0d / (double)length) /
(1.0d / (double)length)); (1.0d / (double)length));
for(int x = 1; x <= binCount; x++) for(int x = 1; x <= binCount; x++)
{ {
/* Calculate unity response plus amplification for droop */ /* Calculate unity response plus amplification for droop */
float compensated = 1.0f + (unityResponse - (float)(Math.sin((double)x / (double)length) / ((double)x / (double)length))); float compensated = 1.0f + (unityResponse - (float)(FastMath.sin((double)x / (double)length) / ((double)x / (double)length)));
cicArray[x] = compensated; cicArray[x] = compensated;
cicArray[length - x] = compensated; cicArray[length - x] = compensated;
@@ -612,25 +611,25 @@ public class FilterFactory
{ {
float index = (float)x - ((float)taps / 2.0f); float index = (float)x - ((float)taps / 2.0f);
float x1 = (float)Math.PI * index / (float)samplesPerSymbol; float x1 = (float)FastMath.PI * index / (float)samplesPerSymbol;
float x2 = 4.0f * alpha * index / (float)samplesPerSymbol; float x2 = 4.0f * alpha * index / (float)samplesPerSymbol;
float x3 = x2 * x2 - 1.0f; float x3 = x2 * x2 - 1.0f;
float numerator, denominator; float numerator, denominator;
if(Math.abs(x3) >= 0.000001) if(FastMath.abs(x3) >= 0.000001)
{ {
if(x != taps / 2) if(x != taps / 2)
{ {
numerator = (float)Math.cos((1.0 + alpha) * x1) + numerator = (float)FastMath.cos((1.0 + alpha) * x1) +
(float)Math.sin((1.0f - alpha) * x1) / (4.0f * alpha * index / (float)samplesPerSymbol); (float)FastMath.sin((1.0f - alpha) * x1) / (4.0f * alpha * index / (float)samplesPerSymbol);
} }
else else
{ {
numerator = (float)Math.cos((1.0f + alpha) * x1) + (1.0f - alpha) * (float)Math.PI / (4.0f * alpha); numerator = (float)FastMath.cos((1.0f + alpha) * x1) + (1.0f - alpha) * (float)FastMath.PI / (4.0f * alpha);
} }
denominator = x3 * (float)Math.PI; denominator = x3 * (float)FastMath.PI;
} }
else else
{ {
@@ -643,11 +642,11 @@ public class FilterFactory
x3 = (1.0f - alpha) * x1; x3 = (1.0f - alpha) * x1;
x2 = (1.0f + alpha) * x1; x2 = (1.0f + alpha) * x1;
numerator = (float)(Math.sin(x2) * (1.0f + alpha) * Math.PI - Math.cos(x3) * ((1.0 - alpha) * Math.PI * numerator = (float)(FastMath.sin(x2) * (1.0f + alpha) * FastMath.PI - FastMath.cos(x3) * ((1.0 - alpha) * FastMath.PI *
(double)samplesPerSymbol) / (4.0 * alpha * index) + Math.sin(x3) * (double)samplesPerSymbol * (double)samplesPerSymbol) / (4.0 * alpha * index) + FastMath.sin(x3) * (double)samplesPerSymbol *
(double)samplesPerSymbol / (4.0 * alpha * index * index)); (double)samplesPerSymbol / (4.0 * alpha * index * index));
denominator = (float)(-32.0 * Math.PI * alpha * alpha * index / (double)samplesPerSymbol); denominator = (float)(-32.0 * FastMath.PI * alpha * alpha * index / (double)samplesPerSymbol);
} }
coefficients[x] = 4.0f * alpha * numerator / denominator; coefficients[x] = 4.0f * alpha * numerator / denominator;
@@ -699,8 +698,8 @@ public class FilterFactory
for(int x = 0; x < filter.length; x++) for(int x = 0; x < filter.length; x++)
{ {
real += filter[x] * Math.cos(Math.PI * frequency * (double)x); real += filter[x] * FastMath.cos(FastMath.PI * frequency * (double)x);
imag += filter[x] * Math.sin(Math.PI * frequency * (double)x); imag += filter[x] * FastMath.sin(FastMath.PI * frequency * (double)x);
} }
return decibel(real, imag); return decibel(real, imag);
@@ -715,7 +714,7 @@ public class FilterFactory
*/ */
public static double decibel(double real, double imag) public static double decibel(double real, double imag)
{ {
return (float)(10.0 * Math.log10(Math.pow(real, 2.0) + Math.pow(imag, 2.0))); return (float)(10.0 * FastMath.log10(FastMath.pow(real, 2.0) + FastMath.pow(imag, 2.0)));
} }
@@ -738,9 +737,9 @@ public class FilterFactory
double bandEdgeFrequency = (double)channelBandwidth / (double)(channels * channelBandwidth * 2); double bandEdgeFrequency = (double)channelBandwidth / (double)(channels * channelBandwidth * 2);
double response = decibel(designer.getFrequencyResponse(Math.cos(bandEdgeFrequency * Math.PI)), 0.0); double response = decibel(designer.getFrequencyResponse(FastMath.cos(bandEdgeFrequency * FastMath.PI)), 0.0);
mLog.debug("Frequency Response at 1.0: " + response); mLog.debug("Frequency Response at 1.0: " + response);
response = decibel(designer.getFrequencyResponse(Math.cos(bandEdgeFrequency * Math.PI * 2.0)), 0.0); response = decibel(designer.getFrequencyResponse(FastMath.cos(bandEdgeFrequency * FastMath.PI * 2.0)), 0.0);
mLog.debug("Frequency Response at 2.0: " + response); mLog.debug("Frequency Response at 2.0: " + response);
return taps; return taps;
@@ -946,14 +945,14 @@ public class FilterFactory
double[] window = Window.getWindow(windowType, length); double[] window = Window.getWindow(windowType, length);
double scalor = 2.0 * cutoff; double scalor = 2.0 * cutoff;
double piScalor = Math.PI * scalor; double piScalor = FastMath.PI * scalor;
coefficients[half] = (float)(1.0 * scalor * window[half]); coefficients[half] = (float)(1.0 * scalor * window[half]);
for(int x = 1; x <= half; x++) for(int x = 1; x <= half; x++)
{ {
double a = piScalor * x; double a = piScalor * x;
double coefficient = scalor * Math.sin(a) / a; double coefficient = scalor * FastMath.sin(a) / a;
coefficient *= window[half + x]; coefficient *= window[half + x];
coefficients[half + x] = (float)coefficient; coefficients[half + x] = (float)coefficient;
@@ -985,14 +984,14 @@ public class FilterFactory
double[] window = Window.getKaiser(length, attenuation); double[] window = Window.getKaiser(length, attenuation);
double scalor = 2.0 * cutoff; double scalor = 2.0 * cutoff;
double piScalor = Math.PI * scalor; double piScalor = FastMath.PI * scalor;
coefficients[half] = (float)(1.0 * scalor * window[half]); coefficients[half] = (float)(1.0 * scalor * window[half]);
for(int x = 1; x <= half; x++) for(int x = 1; x <= half; x++)
{ {
double a = piScalor * x; double a = piScalor * x;
double coefficient = scalor * Math.sin(a) / a; double coefficient = scalor * FastMath.sin(a) / a;
coefficient *= window[half + x]; coefficient *= window[half + x];
coefficients[half + x] = (float)coefficient; coefficients[half + x] = (float)coefficient;
@@ -1011,7 +1010,7 @@ public class FilterFactory
*/ */
private static boolean matchesObjective(double a, double objective, double marginOfError) private static boolean matchesObjective(double a, double objective, double marginOfError)
{ {
return Math.abs(a - objective) <= marginOfError; return FastMath.abs(a - objective) <= marginOfError;
} }
public static void main(String[] args) public static void main(String[] args)

View File

@@ -126,7 +126,7 @@ public class FloatFIRFilter implements RealSampleListener
{ {
for( int y = 0; y < mCoefficients.length; y++ ) for( int y = 0; y < mCoefficients.length; y++ )
{ {
sb.append( mIndexMap[ x ][ y ] + " " ); sb.append(mIndexMap[x][y]).append(" ");
} }
sb.append( "\n" ); sb.append( "\n" );
} }

View File

@@ -18,6 +18,7 @@
package io.github.dsheirer.dsp.filter; package io.github.dsheirer.dsp.filter;
import io.github.dsheirer.dsp.filter.Window.WindowType; import io.github.dsheirer.dsp.filter.Window.WindowType;
import org.apache.commons.math3.util.FastMath;
/** /**
@@ -68,7 +69,7 @@ public class GoertzelFilter
private void init() private void init()
{ {
double normalizedFrequency = (double) mTargetFrequency / mSampleRate; double normalizedFrequency = (double) mTargetFrequency / mSampleRate;
mCoefficient = 2.0D * Math.cos( 2 * Math.PI * normalizedFrequency ); mCoefficient = 2.0D * FastMath.cos( 2 * FastMath.PI * normalizedFrequency );
} }
@@ -101,20 +102,19 @@ public class GoertzelFilter
double s = 0.0D; double s = 0.0D;
double s_prev = 0.0D; double s_prev = 0.0D;
double s_prev2 = 0.0D; double s_prev2 = 0.0D;
for ( int x = 0; x < samples.length; x++ ) for (float sample : samples) {
{ s = sample + (mCoefficient * s_prev) - s_prev2;
s = samples[x] + ( mCoefficient * s_prev ) - s_prev2; s_prev2 = s_prev;
s_prev2 = s_prev; s_prev = s;
s_prev = s; }
}
//power = s_prev2 * s_prev2 + s_prev * s_prev - coeff * s_prev * s_prev2 ; //power = s_prev2 * s_prev2 + s_prev * s_prev - coeff * s_prev * s_prev2 ;
double magnitude = ( s_prev2 * s_prev2 ) + ( s_prev * s_prev) - (mCoefficient * s_prev * s_prev2); double magnitude = ( s_prev2 * s_prev2 ) + ( s_prev * s_prev) - (mCoefficient * s_prev * s_prev2);
int binZero = getBinZeroPower( samples ); int binZero = getBinZeroPower( samples );
int power = (int) (20 * Math.log10( magnitude / binZero ) ); int power = (int) (20 * FastMath.log10( magnitude / binZero ) );
return power; return power;
} }
@@ -125,10 +125,9 @@ public class GoertzelFilter
private int getBinZeroPower( float[] samples ) private int getBinZeroPower( float[] samples )
{ {
int retVal = 0; int retVal = 0;
for( int x = 0; x < samples.length; x++ ) for (float sample : samples) {
{ retVal += sample;
retVal += samples[ x ];
} }
return retVal; return retVal;

View File

@@ -17,6 +17,8 @@
******************************************************************************/ ******************************************************************************/
package io.github.dsheirer.dsp.filter; package io.github.dsheirer.dsp.filter;
import org.apache.commons.math3.util.FastMath;
/*************************************************************************** /***************************************************************************
* Copyright (C) 2011 by Paul Lutus * * Copyright (C) 2011 by Paul Lutus *
* lutusp@arachnoid.com * * lutusp@arachnoid.com *
@@ -93,12 +95,12 @@ final public class IIRBiQuadraticFilter {
public void reconfigure(double cf) { public void reconfigure(double cf) {
center_freq = cf; center_freq = cf;
// only used for peaking and shelving filters // only used for peaking and shelving filters
gain_abs = Math.pow(10, gainDB / 40); gain_abs = FastMath.pow(10, gainDB / 40);
double omega = 2 * Math.PI * cf / sample_rate; double omega = 2 * FastMath.PI * cf / sample_rate;
double sn = Math.sin(omega); double sn = FastMath.sin(omega);
double cs = Math.cos(omega); double cs = FastMath.cos(omega);
double alpha = sn / (2 * Q); double alpha = sn / (2 * Q);
double beta = Math.sqrt(gain_abs + gain_abs); double beta = FastMath.sqrt(gain_abs + gain_abs);
switch (type) { switch (type) {
case BANDPASS: case BANDPASS:
b0 = alpha; b0 = alpha;
@@ -167,8 +169,8 @@ final public class IIRBiQuadraticFilter {
// provide a static amplitude result for testing // provide a static amplitude result for testing
public double result(double f) { public double result(double f) {
double phi = Math.pow((Math.sin(2.0 * Math.PI * f / (2.0 * sample_rate))), 2.0); double phi = FastMath.pow((FastMath.sin(2.0 * FastMath.PI * f / (2.0 * sample_rate))), 2.0);
return (Math.pow(b0 + b1 + b2, 2.0) - 4.0 * (b0 * b1 + 4.0 * b0 * b2 + b1 * b2) * phi + 16.0 * b0 * b2 * phi * phi) / (Math.pow(1.0 + a1 + a2, 2.0) - 4.0 * (a1 + 4.0 * a2 + a1 * a2) * phi + 16.0 * a2 * phi * phi); return (FastMath.pow(b0 + b1 + b2, 2.0) - 4.0 * (b0 * b1 + 4.0 * b0 * b2 + b1 * b2) * phi + 16.0 * b0 * b2 * phi * phi) / (FastMath.pow(1.0 + a1 + a2, 2.0) - 4.0 * (a1 + 4.0 * a2 + a1 * a2) * phi + 16.0 * a2 * phi * phi);
} }
// provide a static decibel result for testing // provide a static decibel result for testing
@@ -176,7 +178,7 @@ final public class IIRBiQuadraticFilter {
{ {
double r; double r;
try { try {
r = 10 * Math.log10(result(f)); r = 10 * FastMath.log10(result(f));
} catch (Exception e) { } catch (Exception e) {
r = -100; r = -100;
} }

View File

@@ -36,6 +36,7 @@
*/ */
package io.github.dsheirer.dsp.filter; package io.github.dsheirer.dsp.filter;
import org.apache.commons.math3.util.FastMath;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -48,10 +49,10 @@ public class Window
{ {
private final static Logger mLog = LoggerFactory.getLogger(Window.class); private final static Logger mLog = LoggerFactory.getLogger(Window.class);
private static final double TWO_PI = Math.PI * 2.0d; private static final double TWO_PI = FastMath.PI * 2.0d;
private static final double FOUR_PI = Math.PI * 4.0d; private static final double FOUR_PI = FastMath.PI * 4.0d;
private static final double SIX_PI = Math.PI * 6.0d; private static final double SIX_PI = FastMath.PI * 6.0d;
private static final double EIGHT_PI = Math.PI * 8.0d; private static final double EIGHT_PI = FastMath.PI * 8.0d;
/** /**
* Creates a window of the specified type and length. * Creates a window of the specified type and length.
@@ -121,8 +122,8 @@ public class Window
for(int x = -half; x < length / 2 + 1; x++) for(int x = -half; x < length / 2 + 1; x++)
{ {
coefficients[x + half] = Math.cos( coefficients[x + half] = FastMath.cos(
((double)x * Math.PI) / ((double)length + 1.0d)); ((double)x * FastMath.PI) / ((double)length + 1.0d));
} }
} }
else //Odd length else //Odd length
@@ -131,8 +132,8 @@ public class Window
for(int x = -half; x < half + 1; x++) for(int x = -half; x < half + 1; x++)
{ {
coefficients[x + half] = Math.cos( coefficients[x + half] = FastMath.cos(
((double)x * Math.PI) / ((double)length + 1.0d)); ((double)x * FastMath.PI) / ((double)length + 1.0d));
} }
} }
@@ -158,8 +159,8 @@ public class Window
for(int x = 0; x < length; x++) for(int x = 0; x < length; x++)
{ {
coefficients[x] = a0 - coefficients[x] = a0 -
(a1 * Math.cos((TWO_PI * (double)x) / denominator)) + (a1 * FastMath.cos((TWO_PI * (double)x) / denominator)) +
(a2 * Math.cos((FOUR_PI * (double)x) / denominator)); (a2 * FastMath.cos((FOUR_PI * (double)x) / denominator));
} }
return coefficients; return coefficients;
@@ -184,9 +185,9 @@ public class Window
for(int x = 0; x < length; x++) for(int x = 0; x < length; x++)
{ {
coefficients[x] = a0 - coefficients[x] = a0 -
(a1 * Math.cos(TWO_PI * (double)x / denominator)) + (a1 * FastMath.cos(TWO_PI * (double)x / denominator)) +
(a2 * Math.cos(FOUR_PI * (double)x / denominator)) - (a2 * FastMath.cos(FOUR_PI * (double)x / denominator)) -
(a3 * Math.cos(SIX_PI * (double)x / denominator)); (a3 * FastMath.cos(SIX_PI * (double)x / denominator));
} }
return coefficients; return coefficients;
@@ -211,9 +212,9 @@ public class Window
for(int x = 0; x < length; x++) for(int x = 0; x < length; x++)
{ {
coefficients[x] = a0 - coefficients[x] = a0 -
(a1 * Math.cos(TWO_PI * (double)x / denominator)) + (a1 * FastMath.cos(TWO_PI * (double)x / denominator)) +
(a2 * Math.cos(FOUR_PI * (double)x / denominator)) - (a2 * FastMath.cos(FOUR_PI * (double)x / denominator)) -
(a3 * Math.cos(SIX_PI * (double)x / denominator)); (a3 * FastMath.cos(SIX_PI * (double)x / denominator));
} }
return coefficients; return coefficients;
@@ -238,9 +239,9 @@ public class Window
for(int x = 0; x < length; x++) for(int x = 0; x < length; x++)
{ {
coefficients[x] = a0 - coefficients[x] = a0 -
(a1 * Math.cos(TWO_PI * (double)x / denominator)) + (a1 * FastMath.cos(TWO_PI * (double)x / denominator)) +
(a2 * Math.cos(FOUR_PI * (double)x / denominator)) - (a2 * FastMath.cos(FOUR_PI * (double)x / denominator)) -
(a3 * Math.cos(SIX_PI * (double)x / denominator)); (a3 * FastMath.cos(SIX_PI * (double)x / denominator));
} }
return coefficients; return coefficients;
@@ -272,12 +273,12 @@ public class Window
double w = TWO_PI * (double)x / denominator; double w = TWO_PI * (double)x / denominator;
coefficients[x] = a0 - coefficients[x] = a0 -
(a1 * Math.cos(w)) + (a1 * FastMath.cos(w)) +
(a2 * Math.cos(2.0 * w)) - (a2 * FastMath.cos(2.0 * w)) -
(a3 * Math.cos(3.0 * w)) + (a3 * FastMath.cos(3.0 * w)) +
(a4 * Math.cos(4.0 * w)) - (a4 * FastMath.cos(4.0 * w)) -
(a5 * Math.cos(5.0 * w)) + (a5 * FastMath.cos(5.0 * w)) +
(a6 * Math.cos(6.0 * w)); (a6 * FastMath.cos(6.0 * w));
} }
return coefficients; return coefficients;
@@ -299,7 +300,7 @@ public class Window
for(int x = 0; x < length; x++) for(int x = 0; x < length; x++)
{ {
coefficients[x] = a0 - (a1 * Math.cos(TWO_PI * (double)x / denominator)); coefficients[x] = a0 - (a1 * FastMath.cos(TWO_PI * (double)x / denominator));
} }
return coefficients; return coefficients;
@@ -321,7 +322,7 @@ public class Window
for(int x = 0; x < length; x++) for(int x = 0; x < length; x++)
{ {
coefficients[x] = a0 - (a1 * Math.cos(TWO_PI * (double)x / denominator)); coefficients[x] = a0 - (a1 * FastMath.cos(TWO_PI * (double)x / denominator));
} }
return coefficients; return coefficients;
@@ -348,10 +349,10 @@ public class Window
for(int x = 0; x < length; x++) for(int x = 0; x < length; x++)
{ {
coefficients[x] = a0 - coefficients[x] = a0 -
(a1 * Math.cos(TWO_PI * (double)x / denominator)) + (a1 * FastMath.cos(TWO_PI * (double)x / denominator)) +
(a2 * Math.cos(FOUR_PI * (double)x / denominator)) - (a2 * FastMath.cos(FOUR_PI * (double)x / denominator)) -
(a3 * Math.cos(SIX_PI * (double)x / denominator)) + (a3 * FastMath.cos(SIX_PI * (double)x / denominator)) +
(a4 * Math.cos(EIGHT_PI * (double)x / denominator)); (a4 * FastMath.cos(EIGHT_PI * (double)x / denominator));
} }
return coefficients; return coefficients;
@@ -371,7 +372,7 @@ public class Window
} }
else if(attenuation >= 21.0) else if(attenuation >= 21.0)
{ {
return (0.5842 * Math.pow(attenuation - 21.0, 0.4)) + (0.07886 * (attenuation - 21.0)); return (0.5842 * FastMath.pow(attenuation - 21.0, 0.4)) + (0.07886 * (attenuation - 21.0));
} }
else else
{ {
@@ -398,7 +399,7 @@ public class Window
for(int x = 0; x < coefficients.length; x++) for(int x = 0; x < coefficients.length; x++)
{ {
temp = beta * Math.sqrt(1.0 - Math.pow(2.0 * x / (length - 1) - 1.0, 2)); temp = beta * FastMath.sqrt(1.0 - FastMath.pow(2.0 * x / (length - 1) - 1.0, 2));
coefficients[x] = getBesselZerothOrder(temp) / betaBesselZerothOrder; coefficients[x] = getBesselZerothOrder(temp) / betaBesselZerothOrder;
} }

View File

@@ -17,6 +17,7 @@
package io.github.dsheirer.dsp.filter.channelizer; package io.github.dsheirer.dsp.filter.channelizer;
import io.github.dsheirer.source.tuner.channel.TunerChannel; import io.github.dsheirer.source.tuner.channel.TunerChannel;
import org.apache.commons.math3.util.FastMath;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -293,7 +294,7 @@ public class ChannelCalculator
{ {
double offset = frequency - getCenterFrequency(); double offset = frequency - getCenterFrequency();
if(Math.abs(offset) < getHalfChannelBandwidth()) if(FastMath.abs(offset) < getHalfChannelBandwidth())
{ {
return 0; //Center index return 0; //Center index
} }

View File

@@ -24,6 +24,7 @@ import io.github.dsheirer.sample.IOverflowListener;
import io.github.dsheirer.sample.Listener; import io.github.dsheirer.sample.Listener;
import io.github.dsheirer.sample.buffer.ReusableChannelResultsBuffer; import io.github.dsheirer.sample.buffer.ReusableChannelResultsBuffer;
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer; import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import org.apache.commons.math3.util.FastMath;
import org.jtransforms.fft.FloatFFT_1D; import org.jtransforms.fft.FloatFFT_1D;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -71,8 +72,6 @@ public class ComplexPolyphaseChannelizerM2 extends AbstractComplexPolyphaseChann
private FloatFFT_1D mFFT; private FloatFFT_1D mFFT;
private float[] mInlineSamples; private float[] mInlineSamples;
private float[] mInlineFilter; private float[] mInlineFilter;
private float[] mInlineInterimOutput;
private float[] mFilterAccumulator;
private boolean mTopBlockIndicator = true; private boolean mTopBlockIndicator = true;
private int[] mTopBlockMap; private int[] mTopBlockMap;
private int[] mMiddleBlockMap; private int[] mMiddleBlockMap;
@@ -100,7 +99,7 @@ public class ComplexPolyphaseChannelizerM2 extends AbstractComplexPolyphaseChann
throw new IllegalArgumentException("Channel count must be an even multiple of the over-sample rate (2x)"); throw new IllegalArgumentException("Channel count must be an even multiple of the over-sample rate (2x)");
} }
mTapsPerChannel = (int)Math.ceil((double)taps.length / (double)channelCount); mTapsPerChannel = (int) FastMath.ceil((double)taps.length / (double)channelCount);
init(taps); init(taps);
} }
@@ -204,9 +203,10 @@ public class ComplexPolyphaseChannelizerM2 extends AbstractComplexPolyphaseChann
{ {
samplesToCopy = mSamplesPerBlock - mSampleBufferPointer; samplesToCopy = mSamplesPerBlock - mSampleBufferPointer;
if((samples.length - samplesPointer) < samplesToCopy) int samplesDiff = samples.length - samplesPointer;
if(samplesDiff < samplesToCopy)
{ {
samplesToCopy = (samples.length - samplesPointer); samplesToCopy = samplesDiff;
} }
System.arraycopy(samples, samplesPointer, mInlineSamples, mSampleBufferPointer, samplesToCopy); System.arraycopy(samples, samplesPointer, mInlineSamples, mSampleBufferPointer, samplesToCopy);
@@ -336,13 +336,16 @@ public class ComplexPolyphaseChannelizerM2 extends AbstractComplexPolyphaseChann
*/ */
private void process(ReusableChannelResultsBuffer channelResultsBuffer) private void process(ReusableChannelResultsBuffer channelResultsBuffer)
{ {
int bufferLength = getSubChannelCount() * mTapsPerChannel;
float[] inlineInterimOutput = new float[bufferLength];
//Multiply each of the samples by the corresponding filter tap //Multiply each of the samples by the corresponding filter tap
for(int x = 0; x < mInlineSamples.length; x++) for(int x = 0; x < mInlineSamples.length; x++)
{ {
mInlineInterimOutput[x] = mInlineSamples[x] * mInlineFilter[x]; inlineInterimOutput[x] = mInlineSamples[x] * mInlineFilter[x];
} }
Arrays.fill(mFilterAccumulator, 0.0f); float[] filterAccumulator = new float[getSubChannelCount()];
int tapOffset = 0; int tapOffset = 0;
@@ -353,7 +356,7 @@ public class ComplexPolyphaseChannelizerM2 extends AbstractComplexPolyphaseChann
for(int channel = 0; channel < getSubChannelCount(); channel++) for(int channel = 0; channel < getSubChannelCount(); channel++)
{ {
mFilterAccumulator[channel] += mInlineInterimOutput[tapOffset + channel]; filterAccumulator[channel] += inlineInterimOutput[tapOffset + channel];
} }
} }
@@ -363,14 +366,14 @@ public class ComplexPolyphaseChannelizerM2 extends AbstractComplexPolyphaseChann
{ {
for(int x = 0; x < getSubChannelCount(); x++) for(int x = 0; x < getSubChannelCount(); x++)
{ {
processed[x] = mFilterAccumulator[mTopBlockMap[x]]; processed[x] = filterAccumulator[mTopBlockMap[x]];
} }
} }
else else
{ {
for(int x = 0; x < getSubChannelCount(); x++) for(int x = 0; x < getSubChannelCount(); x++)
{ {
processed[x] = mFilterAccumulator[mMiddleBlockMap[x]]; processed[x] = filterAccumulator[mMiddleBlockMap[x]];
} }
} }
@@ -394,8 +397,6 @@ public class ComplexPolyphaseChannelizerM2 extends AbstractComplexPolyphaseChann
mMiddleBlockMap = getMiddleBlockMap(channelCount); mMiddleBlockMap = getMiddleBlockMap(channelCount);
mInlineFilter = getAlignedFilter(coefficients, channelCount, mTapsPerChannel); mInlineFilter = getAlignedFilter(coefficients, channelCount, mTapsPerChannel);
mInlineSamples = new float[bufferLength]; mInlineSamples = new float[bufferLength];
mInlineInterimOutput = new float[bufferLength];
mFilterAccumulator = new float[getSubChannelCount()];
} }
/** /**
@@ -413,32 +414,20 @@ public class ComplexPolyphaseChannelizerM2 extends AbstractComplexPolyphaseChann
//dispatcher thread that is part of this continuous buffer processor. We perform an IFFT on each //dispatcher thread that is part of this continuous buffer processor. We perform an IFFT on each
//channel results array contained in each results buffer and then dispatch the buffer //channel results array contained in each results buffer and then dispatch the buffer
//so that it can be distributed to each channel listener. //so that it can be distributed to each channel listener.
setListener(new Listener<List<ReusableChannelResultsBuffer>>() setListener(buffers -> {
{ for(ReusableChannelResultsBuffer buffer: buffers)
@Override
public void receive(List<ReusableChannelResultsBuffer> buffers)
{ {
for(ReusableChannelResultsBuffer buffer: buffers) for(float[] channelResults: buffer.getChannelResults())
{ {
for(float[] channelResults: buffer.getChannelResults()) //Rotate each of the channels to the correct phase using the IFFT
{ mFFT.complexInverse(channelResults, true);
//Rotate each of the channels to the correct phase using the IFFT
mFFT.complexInverse(channelResults, true);
}
dispatch(buffer);
} }
dispatch(buffer);
} }
}); });
setOverflowListener(new IOverflowListener() setOverflowListener(overflow -> mLog.debug("IFFTProcessor overflow changed - overflow:" + overflow));
{
@Override
public void sourceOverflow(boolean overflow)
{
mLog.debug("IFFTProcessor overflow changed - overflow:" + overflow);
}
});
} }
/** /**

View File

@@ -38,6 +38,7 @@ import io.github.dsheirer.source.tuner.TunerController;
import io.github.dsheirer.source.tuner.channel.ChannelSpecification; import io.github.dsheirer.source.tuner.channel.ChannelSpecification;
import io.github.dsheirer.source.tuner.channel.TunerChannel; import io.github.dsheirer.source.tuner.channel.TunerChannel;
import io.github.dsheirer.source.tuner.channel.TunerChannelSource; import io.github.dsheirer.source.tuner.channel.TunerChannelSource;
import org.apache.commons.math3.util.FastMath;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -339,7 +340,7 @@ public class PolyphaseChannelManager implements ISourceEventProcessor
double tunerSampleRate = mChannelCalculator.getSampleRate(); double tunerSampleRate = mChannelCalculator.getSampleRate();
//If the channelizer is not setup, or setup to the wrong sample rate, recreate it //If the channelizer is not setup, or setup to the wrong sample rate, recreate it
if(mPolyphaseChannelizer == null || Math.abs(mPolyphaseChannelizer.getSampleRate() - tunerSampleRate) > 0.5) if(mPolyphaseChannelizer == null || FastMath.abs(mPolyphaseChannelizer.getSampleRate() - tunerSampleRate) > 0.5)
{ {
if(mPolyphaseChannelizer != null && mPolyphaseChannelizer.getRegisteredChannelCount() > 0) if(mPolyphaseChannelizer != null && mPolyphaseChannelizer.getRegisteredChannelCount() > 0)
{ {

View File

@@ -286,9 +286,10 @@ public class PolyphaseChannelSource extends TunerChannelSource
private float[] getLowPassFilter(double sampleRate, double passFrequency, double stopFrequency) throws FilterDesignException private float[] getLowPassFilter(double sampleRate, double passFrequency, double stopFrequency) throws FilterDesignException
{ {
//Use existing filter if we've already designed one //Use existing filter if we've already designed one
if(sLowPassFilters.containsKey((int)sampleRate)) float[] filter = sLowPassFilters.get((int) sampleRate);
if(filter != null)
{ {
return sLowPassFilters.get((int)sampleRate); return filter;
} }
FIRFilterSpecification specification = FIRFilterSpecification.lowPassBuilder() FIRFilterSpecification specification = FIRFilterSpecification.lowPassBuilder()

View File

@@ -17,6 +17,7 @@ package io.github.dsheirer.dsp.filter.channelizer;
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer; import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.sample.buffer.ReusableComplexBufferQueue; import io.github.dsheirer.sample.buffer.ReusableComplexBufferQueue;
import org.apache.commons.math3.util.FastMath;
import org.jtransforms.fft.FloatFFT_1D; import org.jtransforms.fft.FloatFFT_1D;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -49,7 +50,6 @@ public class TwoChannelSynthesizerM2
private float[] mSerpentineDataBuffer; private float[] mSerpentineDataBuffer;
private float[] mIQInterleavedFilter; private float[] mIQInterleavedFilter;
private float[] mFilterVectorProduct; private float[] mFilterVectorProduct;
private float[] mIFFTBuffer = new float[4];
private float mIAccumulator; private float mIAccumulator;
private float mQAccumulator; private float mQAccumulator;
private FloatFFT_1D mFFT = new FloatFFT_1D(2); private FloatFFT_1D mFFT = new FloatFFT_1D(2);
@@ -72,7 +72,7 @@ public class TwoChannelSynthesizerM2
*/ */
private void init(float[] filter) private void init(float[] filter)
{ {
int tapsPerChannel = (int)Math.ceil(filter.length / 2); int tapsPerChannel = (int) FastMath.ceil(filter.length / 2);
mIQInterleavedFilter = getInterleavedFilter(filter, tapsPerChannel); mIQInterleavedFilter = getInterleavedFilter(filter, tapsPerChannel);
mSerpentineDataBuffer = new float[mIQInterleavedFilter.length]; mSerpentineDataBuffer = new float[mIQInterleavedFilter.length];
@@ -100,17 +100,18 @@ public class TwoChannelSynthesizerM2
ReusableComplexBuffer synthesizedComplexBuffer = mReusableComplexBufferQueue.getBuffer(channel1.length); ReusableComplexBuffer synthesizedComplexBuffer = mReusableComplexBufferQueue.getBuffer(channel1.length);
float[] output = synthesizedComplexBuffer.getSamples(); float[] output = synthesizedComplexBuffer.getSamples();
float[] IFFTBuffer = new float[4];
for(int x = 0; x < channel1.length; x += 2) for(int x = 0; x < channel1.length; x += 2)
{ {
//Load samples from each channel into buffer for IFFT //Load samples from each channel into buffer for IFFT
mIFFTBuffer[0] = channel1[x]; //i IFFTBuffer[0] = channel1[x]; //i
mIFFTBuffer[1] = channel1[x + 1]; //q IFFTBuffer[1] = channel1[x + 1]; //q
mIFFTBuffer[2] = channel2[x]; //i IFFTBuffer[2] = channel2[x]; //i
mIFFTBuffer[3] = channel2[x + 1]; //q IFFTBuffer[3] = channel2[x + 1]; //q
//Perform Inverse FFT (IFFT) //Perform Inverse FFT (IFFT)
mFFT.complexInverse(mIFFTBuffer, true); mFFT.complexInverse(IFFTBuffer, true);
//Perform serpentine shift of data blocks in the data buffer - make room for 4 new samples //Perform serpentine shift of data blocks in the data buffer - make room for 4 new samples
System.arraycopy(mSerpentineDataBuffer, 0, mSerpentineDataBuffer, 4, mSerpentineDataBuffer.length - 4); System.arraycopy(mSerpentineDataBuffer, 0, mSerpentineDataBuffer, 4, mSerpentineDataBuffer.length - 4);
@@ -118,13 +119,13 @@ public class TwoChannelSynthesizerM2
//Top Block - load samples into data buffer in normal order //Top Block - load samples into data buffer in normal order
if(mTopBlockFlag) if(mTopBlockFlag)
{ {
System.arraycopy(mIFFTBuffer, 0, mSerpentineDataBuffer, 0, mIFFTBuffer.length); System.arraycopy(IFFTBuffer, 0, mSerpentineDataBuffer, 0, IFFTBuffer.length);
} }
//Bottom Block - swap samples via data loading to account for phase shift //Bottom Block - swap samples via data loading to account for phase shift
else else
{ {
System.arraycopy(mIFFTBuffer, 0, mSerpentineDataBuffer, 2, 2); System.arraycopy(IFFTBuffer, 0, mSerpentineDataBuffer, 2, 2);
System.arraycopy(mIFFTBuffer, 2, mSerpentineDataBuffer, 0, 2); System.arraycopy(IFFTBuffer, 2, mSerpentineDataBuffer, 0, 2);
} }
//Note: in order to use Java's ability to leverage SIMD intrinsics, we perform filtering in two steps //Note: in order to use Java's ability to leverage SIMD intrinsics, we perform filtering in two steps

View File

@@ -29,6 +29,7 @@ import io.github.dsheirer.sample.buffer.ReusableComplexBufferAssembler;
import io.github.dsheirer.sample.complex.ComplexSampleListener; import io.github.dsheirer.sample.complex.ComplexSampleListener;
import io.github.dsheirer.sample.decimator.ComplexDecimator; import io.github.dsheirer.sample.decimator.ComplexDecimator;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.apache.commons.math3.primes.Primes;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@@ -49,38 +50,6 @@ public class ComplexPrimeCICDecimate implements Listener<ReusableComplexBuffer>
{ {
// private final static Logger mLog = LoggerFactory.getLogger(ComplexPrimeCICDecimate.class); // private final static Logger mLog = LoggerFactory.getLogger(ComplexPrimeCICDecimate.class);
/**
* PRIME numbers to use for decimation stage sizing. This list contains values that should
* support input sample rates up to 70 MHz with an output channel rate of at least 25 kHz.
*/
public static int[] PRIMES = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53,
59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251,
257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359,
367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593,
599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701,
709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827,
829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953,
967, 971, 977, 983, 991, 997, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051,
1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163,
1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279,
1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399,
1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489,
1493, 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601,
1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699, 1709,
1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831,
1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951,
1973, 1979, 1987, 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069,
2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161, 2179,
2203, 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297,
2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, 2381, 2383, 2389, 2393, 2399,
2411, 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543,
2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, 2659, 2663, 2671,
2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, 2749, 2753,
2767, 2777, 2789, 2791, 2797, 2801
};
private static Map<Integer,float[]> sLowPassFilters = new HashMap(); private static Map<Integer,float[]> sLowPassFilters = new HashMap();
private static Map<Integer,List<Integer>> sPrimeFactors = new HashMap(); private static Map<Integer,List<Integer>> sPrimeFactors = new HashMap();
@@ -111,8 +80,6 @@ public class ComplexPrimeCICDecimate implements Listener<ReusableComplexBuffer>
public ComplexPrimeCICDecimate(double sampleRate, int decimation, double passFrequency, double stopFrequency) public ComplexPrimeCICDecimate(double sampleRate, int decimation, double passFrequency, double stopFrequency)
throws FilterDesignException throws FilterDesignException
{ {
Validate.isTrue(decimation <= PRIMES[PRIMES.length - 1]);
List<Integer> stageSizes = getPrimeFactors(decimation); List<Integer> stageSizes = getPrimeFactors(decimation);
for(int x = 0; x < stageSizes.size(); x++) for(int x = 0; x < stageSizes.size(); x++)
@@ -180,35 +147,13 @@ public class ComplexPrimeCICDecimate implements Listener<ReusableComplexBuffer>
*/ */
public static List<Integer> getPrimeFactors(int decimation) public static List<Integer> getPrimeFactors(int decimation)
{ {
if(decimation > PRIMES[PRIMES.length - 1]) List<Integer> primeFactors = sPrimeFactors.get(decimation);
if(primeFactors != null)
{ {
throw new IllegalArgumentException("Decimation rates higher than [" + PRIMES[PRIMES.length - 1] + return primeFactors;
"] are not supported. Update the PRIMES array to add support for higher decimation rates");
} }
if(sPrimeFactors.containsKey(decimation)) primeFactors = Primes.primeFactors(decimation);
{
return sPrimeFactors.get(decimation);
}
List<Integer> primeFactors = new ArrayList<Integer>();
int pointer = 0;
while(decimation > 0 && pointer < PRIMES.length)
{
int prime = PRIMES[pointer];
if(decimation % prime == 0)
{
primeFactors.add(prime);
decimation /= prime;
}
else
{
pointer++;
}
}
sPrimeFactors.put(decimation, primeFactors); sPrimeFactors.put(decimation, primeFactors);
@@ -481,9 +426,10 @@ public class ComplexPrimeCICDecimate implements Listener<ReusableComplexBuffer>
private float[] getLowPassFilter(double sampleRate, double passFrequency, double stopFrequency) throws FilterDesignException private float[] getLowPassFilter(double sampleRate, double passFrequency, double stopFrequency) throws FilterDesignException
{ {
//Use existing filter if we've already designed one //Use existing filter if we've already designed one
if(sLowPassFilters.containsKey((int)sampleRate)) float[] existingFilter = sLowPassFilters.get((int) sampleRate);
if(existingFilter != null)
{ {
return sLowPassFilters.get((int)sampleRate); return existingFilter;
} }
FIRFilterSpecification specification = FIRFilterSpecification.lowPassBuilder() FIRFilterSpecification specification = FIRFilterSpecification.lowPassBuilder()

View File

@@ -28,6 +28,7 @@ import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
import io.github.dsheirer.sample.decimator.RealDecimator; import io.github.dsheirer.sample.decimator.RealDecimator;
import io.github.dsheirer.sample.real.RealSampleListener; import io.github.dsheirer.sample.real.RealSampleListener;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.apache.commons.math3.primes.Primes;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -38,14 +39,6 @@ public class RealPrimeCICDecimate
{ {
private final static Logger mLog = LoggerFactory.getLogger(RealPrimeCICDecimate.class); private final static Logger mLog = LoggerFactory.getLogger(RealPrimeCICDecimate.class);
public static int[] PRIMES = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53,
59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251,
257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359,
367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593,
599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691};
private List<DecimatingStage> mDecimatingStages = new ArrayList<DecimatingStage>(); private List<DecimatingStage> mDecimatingStages = new ArrayList<DecimatingStage>();
private DecimatingStage mFirstDecimatingStage; private DecimatingStage mFirstDecimatingStage;
private Output mOutput; private Output mOutput;
@@ -79,7 +72,7 @@ public class RealPrimeCICDecimate
mOutputBufferSize = outputBufferSize; mOutputBufferSize = outputBufferSize;
List<Integer> stageSizes = getPrimeFactors(decimation); List<Integer> stageSizes = Primes.primeFactors(decimation);
for(int x = 0; x < stageSizes.size(); x++) for(int x = 0; x < stageSizes.size(); x++)
{ {
@@ -137,39 +130,6 @@ public class RealPrimeCICDecimate
mOutput.removeListener(); mOutput.removeListener();
} }
/**
* Calculates the prime factors of the decimation rate up to a maximum
* decimation rate of 700. If you wish to have decimation rates higher
* than 700, then add additional prime factors to the PRIMES array.
*
* @param decimation - integral decimation rate
* @return - ordered list (smallest to largest) of prime factors
*/
public static List<Integer> getPrimeFactors(int decimation)
{
ArrayList<Integer> stages = new ArrayList<Integer>();
int pointer = 0;
while(decimation > 0 && pointer < PRIMES.length)
{
int prime = PRIMES[pointer];
if(decimation % prime == 0)
{
stages.add(prime);
decimation /= prime;
}
else
{
pointer++;
}
}
return stages;
}
/** /**
* Primary input method for receiving real buffers. * Primary input method for receiving real buffers.
*/ */

View File

@@ -43,9 +43,8 @@ public class BufferDCFilter
{ {
mAccumulator = 0.0; mAccumulator = 0.0;
for(int x = 0; x < samples.length; x++) for (float sample : samples) {
{ mAccumulator += sample;
mAccumulator += samples[x];
} }
return (float)(mAccumulator / (double)samples.length); return (float)(mAccumulator / (double)samples.length);

View File

@@ -23,6 +23,7 @@ import javafx.scene.chart.XYChart.Series;
import javafx.scene.layout.BorderPane; import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority; import javafx.scene.layout.Priority;
import org.apache.commons.math3.util.FastMath;
import org.jtransforms.fft.FloatFFT_1D; import org.jtransforms.fft.FloatFFT_1D;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -140,7 +141,7 @@ public class FilterView extends BorderPane
mImpulseXAxis.setUpperBound(taps.length - 1); mImpulseXAxis.setUpperBound(taps.length - 1);
mImpulseXAxis.setTickUnit(1.0); mImpulseXAxis.setTickUnit(1.0);
double padding = Math.abs(largest - smallest) * .1; double padding = FastMath.abs(largest - smallest) * .1;
mImpulseYAxis.setLowerBound(smallest - padding); mImpulseYAxis.setLowerBound(smallest - padding);
mImpulseYAxis.setUpperBound(largest + padding); mImpulseYAxis.setUpperBound(largest + padding);
@@ -180,7 +181,7 @@ public class FilterView extends BorderPane
{ {
index = x * 2; index = x * 2;
decibels[x] = 20.0f * (float)Math.log10(((dft[index] * dft[index]) + decibels[x] = 20.0f * (float)FastMath.log10(((dft[index] * dft[index]) +
(dft[index + 1] * dft[index + 1]))); (dft[index + 1] * dft[index + 1])));
} }

View File

@@ -2,6 +2,7 @@ package io.github.dsheirer.dsp.filter.fir;
import io.github.dsheirer.dsp.filter.fir.remez.FIRLinearPhaseFilterType; import io.github.dsheirer.dsp.filter.fir.remez.FIRLinearPhaseFilterType;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.apache.commons.math3.util.FastMath;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -887,7 +888,7 @@ public class FIRFilterSpecification
*/ */
private static int getFilterOrder(double length) private static int getFilterOrder(double length)
{ {
return (int)(Math.ceil(length) - 1); return (int)(FastMath.ceil(length) - 1);
} }
/** /**
@@ -908,10 +909,10 @@ public class FIRFilterSpecification
public static int estimateFilterOrder(double sampleRate, double frequency1, double frequency2, public static int estimateFilterOrder(double sampleRate, double frequency1, double frequency2,
double passBandRipple, double stopBandRipple) double passBandRipple, double stopBandRipple)
{ {
double df = Math.abs(frequency2 - frequency1) / sampleRate; double df = FastMath.abs(frequency2 - frequency1) / sampleRate;
double ddp = Math.log10(stopBandRipple <= passBandRipple ? passBandRipple : stopBandRipple); double ddp = FastMath.log10(FastMath.max(stopBandRipple, passBandRipple));
double dds = Math.log10(stopBandRipple <= passBandRipple ? stopBandRipple : passBandRipple); double dds = FastMath.log10(FastMath.min(stopBandRipple, passBandRipple));
double a1 = 5.309e-3; double a1 = 5.309e-3;
double a2 = 7.114e-2; double a2 = 7.114e-2;
@@ -932,7 +933,7 @@ public class FIRFilterSpecification
double ff = b1 + b2 * (ddp - dds); double ff = b1 + b2 * (ddp - dds);
double n = dinf / df - ff * df + 1.0; double n = dinf / df - ff * df + 1.0;
return (int)Math.ceil(n); return (int)FastMath.ceil(n);
} }
/** /**
@@ -946,9 +947,9 @@ public class FIRFilterSpecification
public static int estimateBandPassOrder(double sampleRate, int passBandStart, int passBandEnd, public static int estimateBandPassOrder(double sampleRate, int passBandStart, int passBandEnd,
double passBandRippleDb, double stopBandRippleDb) double passBandRippleDb, double stopBandRippleDb)
{ {
double df = (double)Math.abs(passBandEnd - passBandStart) / sampleRate; double df = (double)FastMath.abs(passBandEnd - passBandStart) / sampleRate;
double ddp = Math.log10(passBandRippleDb); double ddp = FastMath.log10(passBandRippleDb);
double dds = Math.log10(stopBandRippleDb); double dds = FastMath.log10(stopBandRippleDb);
double a1 = 0.01201; double a1 = 0.01201;
double a2 = 0.09664; double a2 = 0.09664;
@@ -963,10 +964,10 @@ public class FIRFilterSpecification
double t4 = a5 * ddp; double t4 = a5 * ddp;
double cinf = dds * (t1 + t2 + a3) + t3 + t4 + a6; double cinf = dds * (t1 + t2 + a3) + t3 + t4 + a6;
double ginf = -14.6f * (double)Math.log10(passBandRippleDb / stopBandRippleDb) - 16.9; double ginf = -14.6f * (double)FastMath.log10(passBandRippleDb / stopBandRippleDb) - 16.9;
double n = cinf / df + ginf * df + 1.0; double n = cinf / df + ginf * df + 1.0;
return (int)Math.ceil(n); return (int)FastMath.ceil(n);
} }
/** /**
@@ -1040,7 +1041,7 @@ public class FIRFilterSpecification
public void setGridSize(int totalGridSize, double totalBandwidth) public void setGridSize(int totalGridSize, double totalBandwidth)
{ {
mGridSize = Math.max(1, (int)Math.ceil((double)totalGridSize * (getBandWidth() / totalBandwidth))); mGridSize = FastMath.max(1, (int)FastMath.ceil((double)totalGridSize * (getBandWidth() / totalBandwidth)));
} }
public String toString() public String toString()
@@ -1104,8 +1105,8 @@ public class FIRFilterSpecification
*/ */
public double getRippleAmplitude() public double getRippleAmplitude()
{ {
return (Math.pow(10.0, (mRippleDB / 20)) - 1) return (FastMath.pow(10.0, (mRippleDB / 20)) - 1)
/ (Math.pow(10.0, (mRippleDB / 20)) + 1); / (FastMath.pow(10.0, (mRippleDB / 20)) + 1);
} }
/** /**

View File

@@ -1,10 +1,11 @@
package io.github.dsheirer.dsp.filter.fir.remez; package io.github.dsheirer.dsp.filter.fir.remez;
import io.github.dsheirer.dsp.filter.fir.FIRFilterSpecification; import io.github.dsheirer.dsp.filter.fir.FIRFilterSpecification;
import org.apache.commons.math3.util.FastMath;
public class Grid public class Grid
{ {
public static final double TWO_PI = 2.0 * Math.PI; public static final double TWO_PI = 2.0 * FastMath.PI;
private double[] mFrequencyGrid; private double[] mFrequencyGrid;
private double[] mCosineOfFrequencyGrid; private double[] mCosineOfFrequencyGrid;
@@ -59,7 +60,7 @@ public class Grid
//gridFrequencyInterval increments //gridFrequencyInterval increments
mFrequencyGrid[ j ] = lowFrequency; mFrequencyGrid[ j ] = lowFrequency;
mCosineOfFrequencyGrid[ j ] = Math.cos( TWO_PI * mFrequencyGrid[ j ] ); mCosineOfFrequencyGrid[ j ] = FastMath.cos( TWO_PI * mFrequencyGrid[ j ] );
lowFrequency += gridFrequencyInterval; lowFrequency += gridFrequencyInterval;

View File

@@ -19,6 +19,7 @@
package io.github.dsheirer.dsp.filter.fir.remez; package io.github.dsheirer.dsp.filter.fir.remez;
import io.github.dsheirer.dsp.filter.fir.FIRFilterSpecification; import io.github.dsheirer.dsp.filter.fir.FIRFilterSpecification;
import org.apache.commons.math3.util.FastMath;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -26,7 +27,7 @@ public class PolyphaseChannelizerFilterFactory
{ {
private final static Logger mLog = LoggerFactory.getLogger(PolyphaseChannelizerFilterFactory.class); private final static Logger mLog = LoggerFactory.getLogger(PolyphaseChannelizerFilterFactory.class);
private static final double OBJECTIVE_BAND_EDGE_COEFFICIENT_AMPLITUDE = Math.sqrt(2.0) / 2.0; //.707xxx private static final double OBJECTIVE_BAND_EDGE_COEFFICIENT_AMPLITUDE = FastMath.sqrt(2.0) / 2.0; //.707xxx
public static float[] getFilter(int sampleRate, int channelBandwidth, double alpha) public static float[] getFilter(int sampleRate, int channelBandwidth, double alpha)
{ {
@@ -77,7 +78,7 @@ public class PolyphaseChannelizerFilterFactory
specification.addFrequencyBand(transitionBand); specification.addFrequencyBand(transitionBand);
specification.addFrequencyBand(stopBand); specification.addFrequencyBand(stopBand);
double bandEdgeFrequency = Math.cos(Math.PI * (double)channelBandwidth / (double)(sampleRate / 2)); double bandEdgeFrequency = FastMath.cos(FastMath.PI * (double)channelBandwidth / (double)(sampleRate / 2));
float[] filter = null; float[] filter = null;
try try

View File

@@ -2,6 +2,7 @@ package io.github.dsheirer.dsp.filter.fir.remez;
import io.github.dsheirer.dsp.filter.design.FilterDesignException; import io.github.dsheirer.dsp.filter.design.FilterDesignException;
import io.github.dsheirer.dsp.filter.fir.FIRFilterSpecification; import io.github.dsheirer.dsp.filter.fir.FIRFilterSpecification;
import org.apache.commons.math3.util.FastMath;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -16,7 +17,7 @@ public class RemezFIRFilterDesigner
private static final double CONVERGENCE_THRESHOLD = 0.0001; private static final double CONVERGENCE_THRESHOLD = 0.0001;
public static final int MAXIMUM_ITERATION_COUNT = 40; public static final int MAXIMUM_ITERATION_COUNT = 40;
public static final double TWO_PI = 2.0 * Math.PI; public static final double TWO_PI = 2.0 * FastMath.PI;
private static final DecimalFormat DECIMAL_FORMATTER = new DecimalFormat( "0.00000000" ); private static final DecimalFormat DECIMAL_FORMATTER = new DecimalFormat( "0.00000000" );
@@ -164,7 +165,7 @@ public class RemezFIRFilterDesigner
for( int k = 1; k <= M; k++ ) for( int k = 1; k <= M; k++ )
{ {
accumulator += 2.0 * frequencyResponse[ k ] * Math.cos( frequency * (double)k ); accumulator += 2.0 * frequencyResponse[ k ] * FastMath.cos( frequency * (double)k );
} }
impulseResponse[ n ] = accumulator / (double)length; impulseResponse[ n ] = accumulator / (double)length;
@@ -181,7 +182,7 @@ public class RemezFIRFilterDesigner
for( int k = 1; k < frequencyResponse.length; k++ ) for( int k = 1; k < frequencyResponse.length; k++ )
{ {
accumulator += 2.0 * frequencyResponse[ k ] * Math.cos( frequency * (double)k ); accumulator += 2.0 * frequencyResponse[ k ] * FastMath.cos( frequency * (double)k );
} }
impulseResponse[ n ] = accumulator / (double)length; impulseResponse[ n ] = accumulator / (double)length;
@@ -214,7 +215,7 @@ public class RemezFIRFilterDesigner
double cosineDelta = cosineOfFrequency - mGrid.getCosineFrequencyGrid()[ mExtremalIndices.get( k ) ]; double cosineDelta = cosineOfFrequency - mGrid.getCosineFrequencyGrid()[ mExtremalIndices.get( k ) ];
//If this frequency is close to one of the polynomial points, use the polynomial point for the response //If this frequency is close to one of the polynomial points, use the polynomial point for the response
if( Math.abs( cosineDelta ) < 1.0e-7 ) if( FastMath.abs( cosineDelta ) < 1.0e-7 )
{ {
return mIdealFrequencyResponse[ k ]; return mIdealFrequencyResponse[ k ];
} }
@@ -319,7 +320,7 @@ public class RemezFIRFilterDesigner
double denominator = xk - xi; double denominator = xk - xi;
if( Math.abs( denominator ) < 0.00001 ) if( FastMath.abs( denominator ) < 0.00001 )
{ {
denominator = 0.00001; denominator = 0.00001;
} }
@@ -496,7 +497,7 @@ public class RemezFIRFilterDesigner
//Check for consecutive (redundant) indices on same side of zero axis - retain largest //Check for consecutive (redundant) indices on same side of zero axis - retain largest
if( !( positiveAxis ^ ( mGridErrors[ next ] > 0.0 ) ) ) if( !( positiveAxis ^ ( mGridErrors[ next ] > 0.0 ) ) )
{ {
if( Math.abs( mGridErrors[ next ] ) <= Math.abs( mGridErrors[ current ] )) if( FastMath.abs( mGridErrors[ next ] ) <= FastMath.abs( mGridErrors[ current ] ))
{ {
//Remove next error index that is less than current index and on //Remove next error index that is less than current index and on
it.remove(); it.remove();
@@ -530,8 +531,8 @@ public class RemezFIRFilterDesigner
{ {
int lastIndex = mExtremalIndices.size() - 1; int lastIndex = mExtremalIndices.size() - 1;
if( Math.abs( mGridErrors[ mExtremalIndices.get( 0 )] ) > if( FastMath.abs( mGridErrors[ mExtremalIndices.get( 0 )] ) >
Math.abs( mGridErrors[ mExtremalIndices.get( lastIndex )] ) ) FastMath.abs( mGridErrors[ mExtremalIndices.get( lastIndex )] ) )
{ {
mExtremalIndices.remove( lastIndex ); mExtremalIndices.remove( lastIndex );
} }
@@ -560,7 +561,7 @@ public class RemezFIRFilterDesigner
*/ */
private boolean isGTEDelta( double value ) private boolean isGTEDelta( double value )
{ {
return Math.abs( value ) - Math.abs( mDelta ) > -1.0e-5; return FastMath.abs( value ) - FastMath.abs( mDelta ) > -1.0e-5;
} }
/** /**
@@ -570,11 +571,11 @@ public class RemezFIRFilterDesigner
*/ */
public void checkConvergence() public void checkConvergence()
{ {
double maximum = Math.abs( mGridErrors[ mExtremalIndices.get( 0 ) ] ); double maximum = FastMath.abs( mGridErrors[ mExtremalIndices.get( 0 ) ] );
for( int i = 1; i < mExtremalIndices.size(); i++ ) for( int i = 1; i < mExtremalIndices.size(); i++ )
{ {
double current = Math.abs( mGridErrors[ mExtremalIndices.get( i ) ] ); double current = FastMath.abs( mGridErrors[ mExtremalIndices.get( i ) ] );
if( current > maximum ) if( current > maximum )
{ {
@@ -582,7 +583,7 @@ public class RemezFIRFilterDesigner
} }
} }
double convergence = maximum - Math.abs( mDelta ); double convergence = maximum - FastMath.abs( mDelta );
mConverged = convergence < CONVERGENCE_THRESHOLD; mConverged = convergence < CONVERGENCE_THRESHOLD;
} }
@@ -619,11 +620,11 @@ public class RemezFIRFilterDesigner
double half = (double)length / 2.0; double half = (double)length / 2.0;
double[] resampled = new double[ (int)Math.ceil( half ) ] ; double[] resampled = new double[ (int)FastMath.ceil( half ) ] ;
for( int x = 0; x < resampled.length; x++ ) for( int x = 0; x < resampled.length; x++ )
{ {
resampled[ x ] = getFrequencyResponse( Math.cos( Math.PI * (double)x / half ) ); resampled[ x ] = getFrequencyResponse( FastMath.cos( FastMath.PI * (double)x / half ) );
} }
return resampled; return resampled;
@@ -651,15 +652,15 @@ public class RemezFIRFilterDesigner
case TYPE_3_ODD_LENGTH_EVEN_ORDER_ANTI_SYMMETRICAL: case TYPE_3_ODD_LENGTH_EVEN_ORDER_ANTI_SYMMETRICAL:
for( int x = 0; x < frequencyResponse.length; x++ ) for( int x = 0; x < frequencyResponse.length; x++ )
{ {
double frequencyRadians = Math.PI * ( ( (double)x ) / filterLength ); double frequencyRadians = FastMath.PI * ( ( (double)x ) / filterLength );
frequencyResponse[ x ] *= Math.sin( TWO_PI * frequencyRadians ); frequencyResponse[ x ] *= FastMath.sin( TWO_PI * frequencyRadians );
} }
break; break;
case TYPE_4_EVEN_LENGTH_ODD_ORDER_ANTI_SYMMETRICAL: case TYPE_4_EVEN_LENGTH_ODD_ORDER_ANTI_SYMMETRICAL:
for( int x = 0; x < frequencyResponse.length; x++ ) for( int x = 0; x < frequencyResponse.length; x++ )
{ {
double frequencyRadians = Math.PI * ( ( (double)x ) / filterLength ); double frequencyRadians = FastMath.PI * ( ( (double)x ) / filterLength );
frequencyResponse[ x ] *= Math.sin( Math.PI * frequencyRadians ); frequencyResponse[ x ] *= FastMath.sin( FastMath.PI * frequencyRadians );
} }
break; break;
default: default:

View File

@@ -20,6 +20,7 @@ package io.github.dsheirer.dsp.filter.fir.remez;
import io.github.dsheirer.dsp.filter.design.FilterDesignException; import io.github.dsheirer.dsp.filter.design.FilterDesignException;
import io.github.dsheirer.dsp.filter.fir.FIRFilterSpecification; import io.github.dsheirer.dsp.filter.fir.FIRFilterSpecification;
import org.apache.commons.math3.util.FastMath;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -35,7 +36,7 @@ public class RemezFIRFilterDesigner2
private static final double CONVERGENCE_THRESHOLD = 0.0001; private static final double CONVERGENCE_THRESHOLD = 0.0001;
public static final int MAXIMUM_ITERATION_COUNT = 40; public static final int MAXIMUM_ITERATION_COUNT = 40;
public static final double TWO_PI = 2.0 * Math.PI; public static final double TWO_PI = 2.0 * FastMath.PI;
public static final double FREQUENCY_PROXIMITY_THRESHOLD = 1.0e-7; public static final double FREQUENCY_PROXIMITY_THRESHOLD = 1.0e-7;
private FIRFilterSpecification mSpecification; private FIRFilterSpecification mSpecification;
@@ -189,7 +190,7 @@ public class RemezFIRFilterDesigner2
for(int k = 1; k <= M; k++) for(int k = 1; k <= M; k++)
{ {
accumulator += 2.0 * frequencyResponse[k] * Math.cos(frequency * (double)k); accumulator += 2.0 * frequencyResponse[k] * FastMath.cos(frequency * (double)k);
} }
impulseResponse[n] = accumulator / (double)length; impulseResponse[n] = accumulator / (double)length;
@@ -206,7 +207,7 @@ public class RemezFIRFilterDesigner2
for(int k = 1; k < frequencyResponse.length; k++) for(int k = 1; k < frequencyResponse.length; k++)
{ {
accumulator += 2.0 * frequencyResponse[k] * Math.cos(frequency * (double)k); accumulator += 2.0 * frequencyResponse[k] * FastMath.cos(frequency * (double)k);
} }
impulseResponse[n] = accumulator / (double)length; impulseResponse[n] = accumulator / (double)length;
@@ -238,7 +239,7 @@ public class RemezFIRFilterDesigner2
double cosineDelta = cosineOfFrequency - mGrid.getCosineFrequencyGrid()[mExtremalIndices.get(k)]; double cosineDelta = cosineOfFrequency - mGrid.getCosineFrequencyGrid()[mExtremalIndices.get(k)];
//If this frequency is close to one of the polynomial points, use the point as the response value //If this frequency is close to one of the polynomial points, use the point as the response value
if(Math.abs(cosineDelta) < FREQUENCY_PROXIMITY_THRESHOLD) if(FastMath.abs(cosineDelta) < FREQUENCY_PROXIMITY_THRESHOLD)
{ {
return mIdealFrequencyResponse[k]; return mIdealFrequencyResponse[k];
} }
@@ -360,7 +361,7 @@ public class RemezFIRFilterDesigner2
double denominator = xk - xi; double denominator = xk - xi;
if(Math.abs(denominator) < 0.00001) if(FastMath.abs(denominator) < 0.00001)
{ {
denominator = 0.00001; denominator = 0.00001;
} }
@@ -537,7 +538,7 @@ public class RemezFIRFilterDesigner2
//Check for consecutive (redundant) indices on same side of zero axis - retain largest //Check for consecutive (redundant) indices on same side of zero axis - retain largest
if(!(positiveAxis ^ (mGridErrors[next] > 0.0))) if(!(positiveAxis ^ (mGridErrors[next] > 0.0)))
{ {
if(Math.abs(mGridErrors[next]) <= Math.abs(mGridErrors[current])) if(FastMath.abs(mGridErrors[next]) <= FastMath.abs(mGridErrors[current]))
{ {
//Remove next error index that is less than current index and on //Remove next error index that is less than current index and on
it.remove(); it.remove();
@@ -571,8 +572,8 @@ public class RemezFIRFilterDesigner2
{ {
int lastIndex = mExtremalIndices.size() - 1; int lastIndex = mExtremalIndices.size() - 1;
if(Math.abs(mGridErrors[mExtremalIndices.get(0)]) > if(FastMath.abs(mGridErrors[mExtremalIndices.get(0)]) >
Math.abs(mGridErrors[mExtremalIndices.get(lastIndex)])) FastMath.abs(mGridErrors[mExtremalIndices.get(lastIndex)]))
{ {
mExtremalIndices.remove(lastIndex); mExtremalIndices.remove(lastIndex);
} }
@@ -600,7 +601,7 @@ public class RemezFIRFilterDesigner2
*/ */
private boolean isGTEDelta(double value) private boolean isGTEDelta(double value)
{ {
return Math.abs(value) - Math.abs(mDelta) > -1.0e-5; return FastMath.abs(value) - FastMath.abs(mDelta) > -1.0e-5;
} }
/** /**
@@ -610,11 +611,11 @@ public class RemezFIRFilterDesigner2
*/ */
public void checkConvergence() public void checkConvergence()
{ {
double maximum = Math.abs(mGridErrors[mExtremalIndices.get(0)]); double maximum = FastMath.abs(mGridErrors[mExtremalIndices.get(0)]);
for(int i = 1; i < mExtremalIndices.size(); i++) for(int i = 1; i < mExtremalIndices.size(); i++)
{ {
double current = Math.abs(mGridErrors[mExtremalIndices.get(i)]); double current = FastMath.abs(mGridErrors[mExtremalIndices.get(i)]);
if(current > maximum) if(current > maximum)
{ {
@@ -622,7 +623,7 @@ public class RemezFIRFilterDesigner2
} }
} }
double convergence = maximum - Math.abs(mDelta); double convergence = maximum - FastMath.abs(mDelta);
mConverged = convergence < CONVERGENCE_THRESHOLD; mConverged = convergence < CONVERGENCE_THRESHOLD;
} }
@@ -659,11 +660,11 @@ public class RemezFIRFilterDesigner2
double half = (double)length / 2.0; double half = (double)length / 2.0;
double[] resampled = new double[(int)Math.ceil(half)]; double[] resampled = new double[(int)FastMath.ceil(half)];
for(int x = 0; x < resampled.length; x++) for(int x = 0; x < resampled.length; x++)
{ {
resampled[x] = getFrequencyResponse(Math.cos(Math.PI * (double)x / half)); resampled[x] = getFrequencyResponse(FastMath.cos(FastMath.PI * (double)x / half));
} }
return resampled; return resampled;
@@ -690,15 +691,15 @@ public class RemezFIRFilterDesigner2
case TYPE_3_ODD_LENGTH_EVEN_ORDER_ANTI_SYMMETRICAL: case TYPE_3_ODD_LENGTH_EVEN_ORDER_ANTI_SYMMETRICAL:
for(int x = 0; x < frequencyResponse.length; x++) for(int x = 0; x < frequencyResponse.length; x++)
{ {
double frequencyRadians = Math.PI * (((double)x) / filterLength); double frequencyRadians = FastMath.PI * (((double)x) / filterLength);
frequencyResponse[x] *= Math.sin(TWO_PI * frequencyRadians); frequencyResponse[x] *= FastMath.sin(TWO_PI * frequencyRadians);
} }
break; break;
case TYPE_4_EVEN_LENGTH_ODD_ORDER_ANTI_SYMMETRICAL: case TYPE_4_EVEN_LENGTH_ODD_ORDER_ANTI_SYMMETRICAL:
for(int x = 0; x < frequencyResponse.length; x++) for(int x = 0; x < frequencyResponse.length; x++)
{ {
double frequencyRadians = Math.PI * (((double)x) / filterLength); double frequencyRadians = FastMath.PI * (((double)x) / filterLength);
frequencyResponse[x] *= Math.sin(Math.PI * frequencyRadians); frequencyResponse[x] *= FastMath.sin(FastMath.PI * frequencyRadians);
} }
break; break;
default: default:

View File

@@ -21,6 +21,7 @@ package io.github.dsheirer.dsp.filter.fir.remez;
import io.github.dsheirer.dsp.filter.design.FilterDesignException; import io.github.dsheirer.dsp.filter.design.FilterDesignException;
import io.github.dsheirer.dsp.filter.fir.FIRFilterSpecification; import io.github.dsheirer.dsp.filter.fir.FIRFilterSpecification;
import org.apache.commons.math3.analysis.polynomials.PolynomialFunctionLagrangeForm; import org.apache.commons.math3.analysis.polynomials.PolynomialFunctionLagrangeForm;
import org.apache.commons.math3.util.FastMath;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -36,7 +37,7 @@ public class RemezFIRFilterDesignerWithLagrange
private static final double CONVERGENCE_THRESHOLD = 0.0001; private static final double CONVERGENCE_THRESHOLD = 0.0001;
public static final int MAXIMUM_ITERATION_COUNT = 40; public static final int MAXIMUM_ITERATION_COUNT = 40;
public static final double TWO_PI = 2.0 * Math.PI; public static final double TWO_PI = 2.0 * FastMath.PI;
private static final DecimalFormat DECIMAL_FORMATTER = new DecimalFormat("0.00000000"); private static final DecimalFormat DECIMAL_FORMATTER = new DecimalFormat("0.00000000");
@@ -178,7 +179,7 @@ public class RemezFIRFilterDesignerWithLagrange
for(int k = 1; k <= M; k++) for(int k = 1; k <= M; k++)
{ {
accumulator += 2.0 * frequencyResponse[k] * Math.cos(frequency * (double)k); accumulator += 2.0 * frequencyResponse[k] * FastMath.cos(frequency * (double)k);
} }
impulseResponse[n] = accumulator / (double)length; impulseResponse[n] = accumulator / (double)length;
@@ -195,7 +196,7 @@ public class RemezFIRFilterDesignerWithLagrange
for(int k = 1; k < frequencyResponse.length; k++) for(int k = 1; k < frequencyResponse.length; k++)
{ {
accumulator += 2.0 * frequencyResponse[k] * Math.cos(frequency * (double)k); accumulator += 2.0 * frequencyResponse[k] * FastMath.cos(frequency * (double)k);
} }
impulseResponse[n] = accumulator / (double)length; impulseResponse[n] = accumulator / (double)length;
@@ -351,7 +352,7 @@ public class RemezFIRFilterDesignerWithLagrange
double denominator = xk - xi; double denominator = xk - xi;
if(Math.abs(denominator) < 0.00001) if(FastMath.abs(denominator) < 0.00001)
{ {
denominator = 0.00001; denominator = 0.00001;
} }
@@ -511,7 +512,7 @@ public class RemezFIRFilterDesignerWithLagrange
//Check for consecutive (redundant) indices on same side of zero axis - retain largest //Check for consecutive (redundant) indices on same side of zero axis - retain largest
if(!(positiveAxis ^ (mGridErrors[next] > 0.0))) if(!(positiveAxis ^ (mGridErrors[next] > 0.0)))
{ {
if(Math.abs(mGridErrors[next]) <= Math.abs(mGridErrors[current])) if(FastMath.abs(mGridErrors[next]) <= FastMath.abs(mGridErrors[current]))
{ {
//Remove next error index that is less than current index and on //Remove next error index that is less than current index and on
it.remove(); it.remove();
@@ -545,8 +546,8 @@ public class RemezFIRFilterDesignerWithLagrange
{ {
int lastIndex = mExtremalIndices.size() - 1; int lastIndex = mExtremalIndices.size() - 1;
if(Math.abs(mGridErrors[mExtremalIndices.get(0)]) > if(FastMath.abs(mGridErrors[mExtremalIndices.get(0)]) >
Math.abs(mGridErrors[mExtremalIndices.get(lastIndex)])) FastMath.abs(mGridErrors[mExtremalIndices.get(lastIndex)]))
{ {
mExtremalIndices.remove(lastIndex); mExtremalIndices.remove(lastIndex);
} }
@@ -574,7 +575,7 @@ public class RemezFIRFilterDesignerWithLagrange
*/ */
private boolean isGTEDelta(double value) private boolean isGTEDelta(double value)
{ {
return Math.abs(value) - Math.abs(mDelta) > -1.0e-5; return FastMath.abs(value) - FastMath.abs(mDelta) > -1.0e-5;
} }
/** /**
@@ -584,11 +585,11 @@ public class RemezFIRFilterDesignerWithLagrange
*/ */
public void checkConvergence() public void checkConvergence()
{ {
double maximum = Math.abs(mGridErrors[mExtremalIndices.get(0)]); double maximum = FastMath.abs(mGridErrors[mExtremalIndices.get(0)]);
for(int i = 1; i < mExtremalIndices.size(); i++) for(int i = 1; i < mExtremalIndices.size(); i++)
{ {
double current = Math.abs(mGridErrors[mExtremalIndices.get(i)]); double current = FastMath.abs(mGridErrors[mExtremalIndices.get(i)]);
if(current > maximum) if(current > maximum)
{ {
@@ -596,7 +597,7 @@ public class RemezFIRFilterDesignerWithLagrange
} }
} }
double convergence = maximum - Math.abs(mDelta); double convergence = maximum - FastMath.abs(mDelta);
mLog.debug("Convergence: " + convergence); mLog.debug("Convergence: " + convergence);
@@ -635,11 +636,11 @@ public class RemezFIRFilterDesignerWithLagrange
double half = (double)length / 2.0; double half = (double)length / 2.0;
double[] resampled = new double[(int)Math.ceil(half)]; double[] resampled = new double[(int)FastMath.ceil(half)];
for(int x = 0; x < resampled.length; x++) for(int x = 0; x < resampled.length; x++)
{ {
resampled[x] = getFrequencyResponse(Math.cos(Math.PI * (double)x / half)); resampled[x] = getFrequencyResponse(FastMath.cos(FastMath.PI * (double)x / half));
} }
return resampled; return resampled;
@@ -666,15 +667,15 @@ public class RemezFIRFilterDesignerWithLagrange
case TYPE_3_ODD_LENGTH_EVEN_ORDER_ANTI_SYMMETRICAL: case TYPE_3_ODD_LENGTH_EVEN_ORDER_ANTI_SYMMETRICAL:
for(int x = 0; x < frequencyResponse.length; x++) for(int x = 0; x < frequencyResponse.length; x++)
{ {
double frequencyRadians = Math.PI * (((double)x) / filterLength); double frequencyRadians = FastMath.PI * (((double)x) / filterLength);
frequencyResponse[x] *= Math.sin(TWO_PI * frequencyRadians); frequencyResponse[x] *= FastMath.sin(TWO_PI * frequencyRadians);
} }
break; break;
case TYPE_4_EVEN_LENGTH_ODD_ORDER_ANTI_SYMMETRICAL: case TYPE_4_EVEN_LENGTH_ODD_ORDER_ANTI_SYMMETRICAL:
for(int x = 0; x < frequencyResponse.length; x++) for(int x = 0; x < frequencyResponse.length; x++)
{ {
double frequencyRadians = Math.PI * (((double)x) / filterLength); double frequencyRadians = FastMath.PI * (((double)x) / filterLength);
frequencyResponse[x] *= Math.sin(Math.PI * frequencyRadians); frequencyResponse[x] *= FastMath.sin(FastMath.PI * frequencyRadians);
} }
break; break;
default: default:

View File

@@ -16,6 +16,7 @@
package io.github.dsheirer.dsp.filter.hilbert; package io.github.dsheirer.dsp.filter.hilbert;
import io.github.dsheirer.dsp.filter.Filters; import io.github.dsheirer.dsp.filter.Filters;
import org.apache.commons.math3.util.FastMath;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -230,11 +231,11 @@ public class HilbertTransform
{ {
if(x < middle) if(x < middle)
{ {
mHilbertFilter[x] = 2.0f * -Math.abs(coefficients[x]); mHilbertFilter[x] = 2.0f * -FastMath.abs(coefficients[x]);
} }
else if(x > middle) else if(x > middle)
{ {
mHilbertFilter[x] = 2.0f * Math.abs(coefficients[x]); mHilbertFilter[x] = 2.0f * FastMath.abs(coefficients[x]);
} }
else else
{ {

View File

@@ -15,6 +15,8 @@
******************************************************************************/ ******************************************************************************/
package io.github.dsheirer.dsp.filter.iir; package io.github.dsheirer.dsp.filter.iir;
import org.apache.commons.math3.util.FastMath;
public class DeemphasisFilter public class DeemphasisFilter
{ {
private static final float MAX_SAMPLE_VALUE = 0.95f; private static final float MAX_SAMPLE_VALUE = 0.95f;
@@ -24,7 +26,7 @@ public class DeemphasisFilter
public DeemphasisFilter( float sampleRate, float cutoff, float gain ) public DeemphasisFilter( float sampleRate, float cutoff, float gain )
{ {
mAlpha = (float)Math.exp( -2.0 * Math.PI * cutoff * ( 1.0 / sampleRate ) ); mAlpha = (float)FastMath.exp( -2.0 * FastMath.PI * cutoff * ( 1.0 / sampleRate ) );
mGain = gain; mGain = gain;
} }
@@ -41,12 +43,7 @@ public class DeemphasisFilter
{ {
return MAX_SAMPLE_VALUE; return MAX_SAMPLE_VALUE;
} }
else if( value < -MAX_SAMPLE_VALUE ) else return FastMath.max(value, -MAX_SAMPLE_VALUE);
{
return -MAX_SAMPLE_VALUE;
}
else return value;
} }
public float[] filter( float[] samples ) public float[] filter( float[] samples )

View File

@@ -2,6 +2,7 @@ package io.github.dsheirer.dsp.filter.interpolator;
import io.github.dsheirer.sample.complex.Complex; import io.github.dsheirer.sample.complex.Complex;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.apache.commons.math3.util.FastMath;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -70,13 +71,13 @@ public class RealInterpolator extends Interpolator
RealInterpolator interpolator = new RealInterpolator(1.0f); RealInterpolator interpolator = new RealInterpolator(1.0f);
DecimalFormat decimalFormat = new DecimalFormat("0.0000"); DecimalFormat decimalFormat = new DecimalFormat("0.0000");
double TWO_PI = Math.PI * 2.0; double TWO_PI = FastMath.PI * 2.0;
float[] samples = new float[16]; float[] samples = new float[16];
for(int x = 0; x < 16; x++) for(int x = 0; x < 16; x++)
{ {
samples[x] = (float)Math.sin(TWO_PI * (double)x / 8.0); samples[x] = (float) FastMath.sin(TWO_PI * (double)x / 8.0);
} }
mLog.debug("Samples: " + Arrays.toString(samples)); mLog.debug("Samples: " + Arrays.toString(samples));

View File

@@ -21,6 +21,7 @@ import io.github.dsheirer.sample.buffer.ReusableBufferQueue;
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer; import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer; import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
import io.github.dsheirer.sample.complex.Complex; import io.github.dsheirer.sample.complex.Complex;
import org.apache.commons.math3.util.FastMath;
/** /**
* FM Demodulator for demodulating complex samples and producing demodulated floating point samples. * FM Demodulator for demodulating complex samples and producing demodulated floating point samples.
@@ -81,7 +82,7 @@ public class FMDemodulator
* serves as the instantaneous amplitude of the demodulated signal * serves as the instantaneous amplitude of the demodulated signal
*/ */
double denominator = 1.0d / inphase; double denominator = 1.0d / inphase;
angle = Math.atan((double)quadrature * denominator); angle = FastMath.atan((double)quadrature * denominator);
} }
/** /**
@@ -116,7 +117,7 @@ public class FMDemodulator
* serves as the instantaneous amplitude of the demodulated signal * serves as the instantaneous amplitude of the demodulated signal
*/ */
double denominator = 1.0d / inphase; double denominator = 1.0d / inphase;
angle = Math.atan((double)quadrature * denominator); angle = FastMath.atan((double)quadrature * denominator);
} }
return angle; return angle;

View File

@@ -15,6 +15,7 @@
******************************************************************************/ ******************************************************************************/
package io.github.dsheirer.dsp.fsk; package io.github.dsheirer.dsp.fsk;
import org.apache.commons.math3.util.FastMath;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -47,7 +48,7 @@ public class SampleBuffer
mIntegerSamplesPerSymbol = (int)(samplesPerSymbol + 0.5f); mIntegerSamplesPerSymbol = (int)(samplesPerSymbol + 0.5f);
mHalfIntegerSamplesPerSymbol = (int)(samplesPerSymbol / 2.0f + 0.5f); mHalfIntegerSamplesPerSymbol = (int)(samplesPerSymbol / 2.0f + 0.5f);
mMidSymbolSamplingPoint = samplesPerSymbol + mHalfIntegerSamplesPerSymbol; mMidSymbolSamplingPoint = samplesPerSymbol + mHalfIntegerSamplesPerSymbol;
mTwiceSamplesPerSymbol = (int)Math.floor(2.0 * samplesPerSymbol); mTwiceSamplesPerSymbol = (int) FastMath.floor(2.0 * samplesPerSymbol);
mDelayLine = new boolean[2 * mTwiceSamplesPerSymbol]; mDelayLine = new boolean[2 * mTwiceSamplesPerSymbol];
} }

View File

@@ -15,6 +15,8 @@
******************************************************************************/ ******************************************************************************/
package io.github.dsheirer.dsp.fsk; package io.github.dsheirer.dsp.fsk;
import org.apache.commons.math3.util.FastMath;
/** /**
* Zero crossing error detector. Provides symbol timing error correction values by detecting zero-crossings within * Zero crossing error detector. Provides symbol timing error correction values by detecting zero-crossings within
* each symbol period. Ideally there should be only 0 or 1 zero crossings within each symbol period. However, when * each symbol period. Ideally there should be only 0 or 1 zero crossings within each symbol period. However, when
@@ -45,7 +47,7 @@ public class ZeroCrossingErrorDetector
*/ */
public ZeroCrossingErrorDetector(float samplesPerSymbol) public ZeroCrossingErrorDetector(float samplesPerSymbol)
{ {
mBuffer = new boolean[(int)Math.ceil(samplesPerSymbol)]; mBuffer = new boolean[(int)FastMath.ceil(samplesPerSymbol)];
// mZeroCrossingIdeal = mBuffer.length - 1.5f - (samplesPerSymbol / 2.0f); //Preserve this for LTR // mZeroCrossingIdeal = mBuffer.length - 1.5f - (samplesPerSymbol / 2.0f); //Preserve this for LTR
mZeroCrossingIdeal = (samplesPerSymbol / 2.0f); mZeroCrossingIdeal = (samplesPerSymbol / 2.0f);
} }
@@ -108,7 +110,7 @@ public class ZeroCrossingErrorDetector
float errorDistanceOne = mZeroCrossingIdeal - mZeroCrossingOne; float errorDistanceOne = mZeroCrossingIdeal - mZeroCrossingOne;
float errorDistanceTwo = mZeroCrossingCount - mZeroCrossingTwo; float errorDistanceTwo = mZeroCrossingCount - mZeroCrossingTwo;
if(Math.abs(errorDistanceOne) < Math.abs(errorDistanceTwo)) if(FastMath.abs(errorDistanceOne) < FastMath.abs(errorDistanceTwo))
{ {
mDetectedZeroCrossing = mZeroCrossingOne; mDetectedZeroCrossing = mZeroCrossingOne;
} }

View File

@@ -4,6 +4,7 @@ import io.github.dsheirer.buffer.DoubleCircularBuffer;
import io.github.dsheirer.buffer.RealCircularBuffer; import io.github.dsheirer.buffer.RealCircularBuffer;
import io.github.dsheirer.sample.buffer.ReusableBufferQueue; import io.github.dsheirer.sample.buffer.ReusableBufferQueue;
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer; import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
import org.apache.commons.math3.util.FastMath;
/******************************************************************************* /*******************************************************************************
* SDR Trunk * SDR Trunk
@@ -74,10 +75,10 @@ public class AutomaticGainControl
private static final double ATTACK_FALL_TIME_CONSTANT = 0.005; private static final double ATTACK_FALL_TIME_CONSTANT = 0.005;
private static final double ATTACK_RISE_ALPHA = 1.0 - private static final double ATTACK_RISE_ALPHA = 1.0 -
Math.exp(-1.0 / SAMPLE_RATE * ATTACK_RISE_TIME_CONSTANT); FastMath.exp(-1.0 / SAMPLE_RATE * ATTACK_RISE_TIME_CONSTANT);
private static final double ATTACK_FALL_ALPHA = 1.0 - private static final double ATTACK_FALL_ALPHA = 1.0 -
Math.exp(-1.0 / SAMPLE_RATE * ATTACK_FALL_TIME_CONSTANT); FastMath.exp(-1.0 / SAMPLE_RATE * ATTACK_FALL_TIME_CONSTANT);
/* AGC decay value in milliseconds (20 to 5000) */ /* AGC decay value in milliseconds (20 to 5000) */
private static final double DECAY = 200; private static final double DECAY = 200;
@@ -87,10 +88,10 @@ public class AutomaticGainControl
private static final double DECAY_RISEFALL_RATIO = 0.3; private static final double DECAY_RISEFALL_RATIO = 0.3;
private static final double DECAY_RISE_ALPHA = 1.0 - private static final double DECAY_RISE_ALPHA = 1.0 -
Math.exp(-1.0 / (SAMPLE_RATE * DECAY * .001 * DECAY_RISEFALL_RATIO)); FastMath.exp(-1.0 / (SAMPLE_RATE * DECAY * .001 * DECAY_RISEFALL_RATIO));
private static final double DECAY_FALL_ALPHA = 1.0 - private static final double DECAY_FALL_ALPHA = 1.0 -
Math.exp(-1.0 / (SAMPLE_RATE * DECAY * .001)); FastMath.exp(-1.0 / (SAMPLE_RATE * DECAY * .001));
/* Hang timer release decay time constant in seconds */ /* Hang timer release decay time constant in seconds */
@SuppressWarnings("unused") @SuppressWarnings("unused")
@@ -110,7 +111,7 @@ public class AutomaticGainControl
private static final double MANUAL_GAIN = 0.0; private static final double MANUAL_GAIN = 0.0;
private static final double MANUAL_AGC_GAIN = MAX_MANUAL_AMPLITUDE * private static final double MANUAL_AGC_GAIN = MAX_MANUAL_AMPLITUDE *
Math.pow(10.0, MANUAL_GAIN / 20.0); FastMath.pow(10.0, MANUAL_GAIN / 20.0);
/* Specifies dB reduction in output at knee from max output level (0 - 10dB) */ /* Specifies dB reduction in output at knee from max output level (0 - 10dB) */
private static final double SLOPE_FACTOR = 2.0; private static final double SLOPE_FACTOR = 2.0;
@@ -120,7 +121,7 @@ public class AutomaticGainControl
private static final double GAIN_SLOPE = SLOPE_FACTOR / 100.0; private static final double GAIN_SLOPE = SLOPE_FACTOR / 100.0;
private static final double FIXED_GAIN = AGC_OUT_SCALE * private static final double FIXED_GAIN = AGC_OUT_SCALE *
Math.pow(10.0, KNEE * (GAIN_SLOPE - 1.0)); FastMath.pow(10.0, KNEE * (GAIN_SLOPE - 1.0));
/* Constant for calc log() so that a value of 0 magnitude = -8 */ /* Constant for calc log() so that a value of 0 magnitude = -8 */
private static final double MIN_CONSTANT = 3.2767E-4; private static final double MIN_CONSTANT = 3.2767E-4;
@@ -178,7 +179,7 @@ public class AutomaticGainControl
if(mAGCEnabled) if(mAGCEnabled)
{ {
double currentMagnitude = Math.log10(Math.abs(currentSample) + MIN_CONSTANT) - Math.log10(MAX_AMPLITUDE); double currentMagnitude = FastMath.log10(FastMath.abs(currentSample) + MIN_CONSTANT) - FastMath.log10(MAX_AMPLITUDE);
double delayedMagnitude = mMagnitudeBuffer.get(currentMagnitude); double delayedMagnitude = mMagnitudeBuffer.get(currentMagnitude);
@@ -212,7 +213,7 @@ public class AutomaticGainControl
mDecayAverage = ((1.0 - DECAY_FALL_ALPHA) * mDecayAverage) + (DECAY_RISE_ALPHA * mPeakMagnitude); mDecayAverage = ((1.0 - DECAY_FALL_ALPHA) * mDecayAverage) + (DECAY_RISE_ALPHA * mPeakMagnitude);
} }
double magnitude = (mAttackAverage > mDecayAverage) ? mAttackAverage : mDecayAverage; double magnitude = FastMath.max(mAttackAverage, mDecayAverage);
if(magnitude < KNEE) if(magnitude < KNEE)
{ {
@@ -220,7 +221,7 @@ public class AutomaticGainControl
} }
else else
{ {
gain = AGC_OUT_SCALE * Math.pow(10.0, magnitude * (GAIN_SLOPE - 1.0)); gain = AGC_OUT_SCALE * FastMath.pow(10.0, magnitude * (GAIN_SLOPE - 1.0));
} }
} }

View File

@@ -5,6 +5,7 @@ import io.github.dsheirer.buffer.DoubleCircularBuffer;
import io.github.dsheirer.sample.Listener; import io.github.dsheirer.sample.Listener;
import io.github.dsheirer.sample.Provider; import io.github.dsheirer.sample.Provider;
import io.github.dsheirer.sample.complex.Complex; import io.github.dsheirer.sample.complex.Complex;
import org.apache.commons.math3.util.FastMath;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
@@ -77,10 +78,10 @@ public class ComplexAutomaticGainControl implements Listener<Complex>,
private static final double ATTACK_FALL_TIME_CONSTANT = 0.005; private static final double ATTACK_FALL_TIME_CONSTANT = 0.005;
private static final double ATTACK_RISE_ALPHA = 1.0 - private static final double ATTACK_RISE_ALPHA = 1.0 -
Math.exp( -1.0 / SAMPLE_RATE * ATTACK_RISE_TIME_CONSTANT ); FastMath.exp( -1.0 / SAMPLE_RATE * ATTACK_RISE_TIME_CONSTANT );
private static final double ATTACK_FALL_ALPHA = 1.0 - private static final double ATTACK_FALL_ALPHA = 1.0 -
Math.exp( -1.0 / SAMPLE_RATE * ATTACK_FALL_TIME_CONSTANT ); FastMath.exp( -1.0 / SAMPLE_RATE * ATTACK_FALL_TIME_CONSTANT );
/* AGC decay value in milliseconds (20 to 5000) */ /* AGC decay value in milliseconds (20 to 5000) */
private static final double DECAY = 200; private static final double DECAY = 200;
@@ -90,10 +91,10 @@ public class ComplexAutomaticGainControl implements Listener<Complex>,
private static final double DECAY_RISEFALL_RATIO = 0.3; private static final double DECAY_RISEFALL_RATIO = 0.3;
private static final double DECAY_RISE_ALPHA = 1.0 - private static final double DECAY_RISE_ALPHA = 1.0 -
Math.exp( -1.0 / ( SAMPLE_RATE * DECAY * .001 * DECAY_RISEFALL_RATIO ) ); FastMath.exp( -1.0 / ( SAMPLE_RATE * DECAY * .001 * DECAY_RISEFALL_RATIO ) );
private static final double DECAY_FALL_ALPHA = 1.0 - private static final double DECAY_FALL_ALPHA = 1.0 -
Math.exp( -1.0 / ( SAMPLE_RATE * DECAY * .001 ) ); FastMath.exp( -1.0 / ( SAMPLE_RATE * DECAY * .001 ) );
/* Hang timer release decay time constant in seconds */ /* Hang timer release decay time constant in seconds */
@SuppressWarnings( "unused" ) @SuppressWarnings( "unused" )
@@ -113,7 +114,7 @@ public class ComplexAutomaticGainControl implements Listener<Complex>,
private static final double MANUAL_GAIN = 0.0; private static final double MANUAL_GAIN = 0.0;
private static final double MANUAL_AGC_GAIN = MAX_MANUAL_AMPLITUDE * private static final double MANUAL_AGC_GAIN = MAX_MANUAL_AMPLITUDE *
Math.pow( 10.0, MANUAL_GAIN / 20.0 ); FastMath.pow( 10.0, MANUAL_GAIN / 20.0 );
/* Specifies dB reduction in output at knee from max output level (0 - 10dB) */ /* Specifies dB reduction in output at knee from max output level (0 - 10dB) */
private static final double SLOPE_FACTOR = 2.0; private static final double SLOPE_FACTOR = 2.0;
@@ -123,7 +124,7 @@ public class ComplexAutomaticGainControl implements Listener<Complex>,
private static final double GAIN_SLOPE = SLOPE_FACTOR / 100.0; private static final double GAIN_SLOPE = SLOPE_FACTOR / 100.0;
private static final double FIXED_GAIN = AGC_OUT_SCALE * private static final double FIXED_GAIN = AGC_OUT_SCALE *
Math.pow( 10.0, KNEE * ( GAIN_SLOPE - 1.0 ) ); FastMath.pow( 10.0, KNEE * ( GAIN_SLOPE - 1.0 ) );
/* Constant for calc log() so that a value of 0 magnitude = -8 */ /* Constant for calc log() so that a value of 0 magnitude = -8 */
private static final double MIN_CONSTANT = 3.2767E-4; private static final double MIN_CONSTANT = 3.2767E-4;
@@ -156,8 +157,8 @@ public class ComplexAutomaticGainControl implements Listener<Complex>,
{ {
float max = currentSample.maximumAbsolute(); float max = currentSample.maximumAbsolute();
double currentMagnitude = Math.log10( max + MIN_CONSTANT ) - double currentMagnitude = FastMath.log10( max + MIN_CONSTANT ) -
Math.log10( MAX_AMPLITUDE ); FastMath.log10( MAX_AMPLITUDE );
double delayedMagnitude = mMagnitudeBuffer.get( currentMagnitude ); double delayedMagnitude = mMagnitudeBuffer.get( currentMagnitude );
@@ -195,8 +196,7 @@ public class ComplexAutomaticGainControl implements Listener<Complex>,
( DECAY_RISE_ALPHA * mPeakMagnitude ); ( DECAY_RISE_ALPHA * mPeakMagnitude );
} }
double magnitude = ( mAttackAverage > mDecayAverage ) ? double magnitude = FastMath.max(mAttackAverage, mDecayAverage);
mAttackAverage : mDecayAverage;
if( magnitude < KNEE ) if( magnitude < KNEE )
{ {
@@ -204,7 +204,7 @@ public class ComplexAutomaticGainControl implements Listener<Complex>,
} }
else else
{ {
gain = AGC_OUT_SCALE * Math.pow( 10.0, gain = AGC_OUT_SCALE * FastMath.pow( 10.0,
magnitude * ( GAIN_SLOPE - 1.0 ) ); magnitude * ( GAIN_SLOPE - 1.0 ) );
} }

View File

@@ -15,6 +15,7 @@
******************************************************************************/ ******************************************************************************/
package io.github.dsheirer.dsp.mixer; package io.github.dsheirer.dsp.mixer;
import org.apache.commons.math3.util.FastMath;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -26,7 +27,7 @@ public class LowPhaseNoiseOscillator extends AbstractOscillator
{ {
private final static Logger mLog = LoggerFactory.getLogger(LowPhaseNoiseOscillator.class); private final static Logger mLog = LoggerFactory.getLogger(LowPhaseNoiseOscillator.class);
private static final double TWO_PI = 2.0 * Math.PI; private static final double TWO_PI = 2.0 * FastMath.PI;
private static final double THREE_HALVES = 3.0 / 2.0; private static final double THREE_HALVES = 3.0 / 2.0;
private double mInphase = 1.0; private double mInphase = 1.0;
private double mQuadrature = 0.0; private double mQuadrature = 0.0;
@@ -68,8 +69,8 @@ public class LowPhaseNoiseOscillator extends AbstractOscillator
{ {
double anglePerSample = TWO_PI * getFrequency() / getSampleRate(); double anglePerSample = TWO_PI * getFrequency() / getSampleRate();
mCosineAngle = Math.cos(anglePerSample); mCosineAngle = FastMath.cos(anglePerSample);
mSineAngle = Math.sin(anglePerSample); mSineAngle = FastMath.sin(anglePerSample);
} }
/** /**

View File

@@ -16,6 +16,7 @@
package io.github.dsheirer.dsp.mixer; package io.github.dsheirer.dsp.mixer;
import io.github.dsheirer.sample.complex.Complex; import io.github.dsheirer.sample.complex.Complex;
import org.apache.commons.math3.util.FastMath;
public class Oscillator extends AbstractOscillator public class Oscillator extends AbstractOscillator
{ {
@@ -62,7 +63,7 @@ public class Oscillator extends AbstractOscillator
@Override @Override
protected void update() protected void update()
{ {
float anglePerSample = (float)(2.0d * Math.PI * getFrequency() / getSampleRate()); float anglePerSample = (float)(2.0d * FastMath.PI * getFrequency() / getSampleRate());
mAnglePerSample = Complex.fromAngle(anglePerSample); mAnglePerSample = Complex.fromAngle(anglePerSample);
} }
} }

View File

@@ -26,6 +26,7 @@ import io.github.dsheirer.dsp.psk.pll.IPhaseLockedLoop;
import io.github.dsheirer.sample.Listener; import io.github.dsheirer.sample.Listener;
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer; import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.sample.complex.Complex; import io.github.dsheirer.sample.complex.Complex;
import org.apache.commons.math3.util.FastMath;
public class DQPSKDecisionDirectedDemodulatorInstrumented extends DQPSKDecisionDirectedDemodulator public class DQPSKDecisionDirectedDemodulatorInstrumented extends DQPSKDecisionDirectedDemodulator
{ {
@@ -102,7 +103,7 @@ public class DQPSKDecisionDirectedDemodulatorInstrumented extends DQPSKDecisionD
{ {
double loopFrequency = ((CostasLoop)getPLL()).getLoopFrequency(); double loopFrequency = ((CostasLoop)getPLL()).getLoopFrequency();
loopFrequency *= mSampleRate / (2.0 * Math.PI); loopFrequency *= mSampleRate / (2.0 * FastMath.PI);
mPLLFrequencyListener.receive(loopFrequency); mPLLFrequencyListener.receive(loopFrequency);
} }

View File

@@ -17,13 +17,14 @@ package io.github.dsheirer.dsp.psk;
import io.github.dsheirer.dsp.symbol.Dibit; import io.github.dsheirer.dsp.symbol.Dibit;
import io.github.dsheirer.sample.complex.Complex; import io.github.dsheirer.sample.complex.Complex;
import org.apache.commons.math3.util.FastMath;
public class DQPSKDecisionDirectedSymbolEvaluator implements IPSKSymbolEvaluator<Dibit> public class DQPSKDecisionDirectedSymbolEvaluator implements IPSKSymbolEvaluator<Dibit>
{ {
private static final Complex ROTATE_FROM_PLUS_135 = Complex.fromAngle(-3.0 * Math.PI / 4.0); private static final Complex ROTATE_FROM_PLUS_135 = Complex.fromAngle(-3.0 * FastMath.PI / 4.0);
private static final Complex ROTATE_FROM_PLUS_45 = Complex.fromAngle(-1.0 * Math.PI / 4.0); private static final Complex ROTATE_FROM_PLUS_45 = Complex.fromAngle(-1.0 * FastMath.PI / 4.0);
private static final Complex ROTATE_FROM_MINUS_45 = Complex.fromAngle(1.0 * Math.PI / 4.0); private static final Complex ROTATE_FROM_MINUS_45 = Complex.fromAngle(1.0 * FastMath.PI / 4.0);
private static final Complex ROTATE_FROM_MINUS_135 = Complex.fromAngle(3.0 * Math.PI / 4.0); private static final Complex ROTATE_FROM_MINUS_135 = Complex.fromAngle(3.0 * FastMath.PI / 4.0);
private Complex mEvaluationSymbol = new Complex(0, 0); private Complex mEvaluationSymbol = new Complex(0, 0);
private float mPhaseError = 0.0f; private float mPhaseError = 0.0f;

View File

@@ -26,6 +26,7 @@ import io.github.dsheirer.dsp.psk.pll.IPhaseLockedLoop;
import io.github.dsheirer.sample.Listener; import io.github.dsheirer.sample.Listener;
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer; import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.sample.complex.Complex; import io.github.dsheirer.sample.complex.Complex;
import org.apache.commons.math3.util.FastMath;
public class DQPSKGardnerDemodulatorInstrumented extends DQPSKGardnerDemodulator public class DQPSKGardnerDemodulatorInstrumented extends DQPSKGardnerDemodulator
{ {
@@ -99,7 +100,7 @@ public class DQPSKGardnerDemodulatorInstrumented extends DQPSKGardnerDemodulator
{ {
double loopFrequency = ((CostasLoop)getPLL()).getLoopFrequency(); double loopFrequency = ((CostasLoop)getPLL()).getLoopFrequency();
loopFrequency *= mSampleRate / (2.0 * Math.PI); loopFrequency *= mSampleRate / (2.0 * FastMath.PI);
mPLLFrequencyListener.receive(loopFrequency); mPLLFrequencyListener.receive(loopFrequency);
} }

View File

@@ -17,13 +17,14 @@ package io.github.dsheirer.dsp.psk;
import io.github.dsheirer.dsp.symbol.Dibit; import io.github.dsheirer.dsp.symbol.Dibit;
import io.github.dsheirer.sample.complex.Complex; import io.github.dsheirer.sample.complex.Complex;
import org.apache.commons.math3.util.FastMath;
public class DQPSKGardnerSymbolEvaluator implements IPSKSymbolEvaluator<Dibit> public class DQPSKGardnerSymbolEvaluator implements IPSKSymbolEvaluator<Dibit>
{ {
private static final Complex ROTATE_FROM_PLUS_135 = Complex.fromAngle(-3.0 * Math.PI / 4.0); private static final Complex ROTATE_FROM_PLUS_135 = Complex.fromAngle(-3.0 * FastMath.PI / 4.0);
private static final Complex ROTATE_FROM_PLUS_45 = Complex.fromAngle(-1.0 * Math.PI / 4.0); private static final Complex ROTATE_FROM_PLUS_45 = Complex.fromAngle(-1.0 * FastMath.PI / 4.0);
private static final Complex ROTATE_FROM_MINUS_45 = Complex.fromAngle(1.0 * Math.PI / 4.0); private static final Complex ROTATE_FROM_MINUS_45 = Complex.fromAngle(1.0 * FastMath.PI / 4.0);
private static final Complex ROTATE_FROM_MINUS_135 = Complex.fromAngle(3.0 * Math.PI / 4.0); private static final Complex ROTATE_FROM_MINUS_135 = Complex.fromAngle(3.0 * FastMath.PI / 4.0);
private float mPhaseError = 0.0f; private float mPhaseError = 0.0f;
private float mTimingError = 0.0f; private float mTimingError = 0.0f;

View File

@@ -16,6 +16,7 @@
package io.github.dsheirer.dsp.psk; package io.github.dsheirer.dsp.psk;
import io.github.dsheirer.sample.complex.Complex; import io.github.dsheirer.sample.complex.Complex;
import org.apache.commons.math3.util.FastMath;
public class GardnerDetector public class GardnerDetector
{ {
@@ -41,8 +42,8 @@ public class GardnerDetector
*/ */
public float getError(Complex previous, Complex middle, Complex current) public float getError(Complex previous, Complex middle, Complex current)
{ {
mErrorInphase = (Math.abs(previous.inphase()) - Math.abs(current.inphase())) * Math.abs(middle.inphase()); mErrorInphase = (FastMath.abs(previous.inphase()) - FastMath.abs(current.inphase())) * FastMath.abs(middle.inphase());
mErrorQuadrature = (Math.abs(previous.quadrature()) - Math.abs(current.quadrature())) * Math.abs(middle.quadrature()); mErrorQuadrature = (FastMath.abs(previous.quadrature()) - FastMath.abs(current.quadrature())) * FastMath.abs(middle.quadrature());
mError = normalize(mErrorInphase + mErrorQuadrature, 1.0f); mError = normalize(mErrorInphase + mErrorQuadrature, 1.0f);
return mError; return mError;

View File

@@ -23,6 +23,7 @@ package io.github.dsheirer.dsp.psk;
import io.github.dsheirer.dsp.filter.interpolator.RealInterpolator; import io.github.dsheirer.dsp.filter.interpolator.RealInterpolator;
import io.github.dsheirer.sample.complex.Complex; import io.github.dsheirer.sample.complex.Complex;
import org.apache.commons.math3.util.FastMath;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -60,7 +61,7 @@ public class InterpolatingSampleBuffer
mDetectedSamplesPerSymbol = samplesPerSymbol; mDetectedSamplesPerSymbol = samplesPerSymbol;
mMaximumSamplesPerSymbol = samplesPerSymbol * (1.0f + MAXIMUM_DEVIATION_SAMPLES_PER_SYMBOL); mMaximumSamplesPerSymbol = samplesPerSymbol * (1.0f + MAXIMUM_DEVIATION_SAMPLES_PER_SYMBOL);
mMinimumSamplesPerSymbol = samplesPerSymbol * (1.0f - MAXIMUM_DEVIATION_SAMPLES_PER_SYMBOL); mMinimumSamplesPerSymbol = samplesPerSymbol * (1.0f - MAXIMUM_DEVIATION_SAMPLES_PER_SYMBOL);
mTwiceSamplesPerSymbol = (int)Math.floor(2.0 * samplesPerSymbol); mTwiceSamplesPerSymbol = (int) FastMath.floor(2.0 * samplesPerSymbol);
mDelayLineInphase = new float[2 * mTwiceSamplesPerSymbol]; mDelayLineInphase = new float[2 * mTwiceSamplesPerSymbol];
mDelayLineQuadrature = new float[2 * mTwiceSamplesPerSymbol]; mDelayLineQuadrature = new float[2 * mTwiceSamplesPerSymbol];
@@ -190,7 +191,7 @@ public class InterpolatingSampleBuffer
} }
else else
{ {
int offset = (int)Math.floor(interpolation); int offset = (int)FastMath.floor(interpolation);
return mInterpolator.filter(mDelayLineInphase, mDelayLinePointer + offset, interpolation - offset); return mInterpolator.filter(mDelayLineInphase, mDelayLinePointer + offset, interpolation - offset);
} }
} }
@@ -208,7 +209,7 @@ public class InterpolatingSampleBuffer
} }
else else
{ {
int offset = (int)Math.floor(interpolation); int offset = (int)FastMath.floor(interpolation);
return mInterpolator.filter(mDelayLineQuadrature, mDelayLinePointer + offset, interpolation - offset); return mInterpolator.filter(mDelayLineQuadrature, mDelayLinePointer + offset, interpolation - offset);
} }
} }

View File

@@ -23,6 +23,7 @@ package io.github.dsheirer.dsp.psk;
import io.github.dsheirer.sample.complex.Complex; import io.github.dsheirer.sample.complex.Complex;
import io.github.dsheirer.sample.complex.ComplexSampleListener; import io.github.dsheirer.sample.complex.ComplexSampleListener;
import org.apache.commons.math3.util.FastMath;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -36,7 +37,7 @@ public class InterpolatingSampleBufferInstrumented extends InterpolatingSampleBu
public InterpolatingSampleBufferInstrumented(float samplesPerSymbol, float symbolTimingGain) public InterpolatingSampleBufferInstrumented(float samplesPerSymbol, float symbolTimingGain)
{ {
super(samplesPerSymbol, symbolTimingGain); super(samplesPerSymbol, symbolTimingGain);
mBufferLength = (int)Math.ceil(samplesPerSymbol); mBufferLength = (int) FastMath.ceil(samplesPerSymbol);
mSymbolDecisionData = new SymbolDecisionData(mBufferLength); mSymbolDecisionData = new SymbolDecisionData(mBufferLength);
} }

View File

@@ -19,6 +19,7 @@ import io.github.dsheirer.dsp.symbol.Dibit;
import io.github.dsheirer.sample.Broadcaster; import io.github.dsheirer.sample.Broadcaster;
import io.github.dsheirer.sample.Listener; import io.github.dsheirer.sample.Listener;
import io.github.dsheirer.sample.complex.Complex; import io.github.dsheirer.sample.complex.Complex;
import org.apache.commons.math3.util.FastMath;
public class QPSKSymbolDecoder implements Listener<Complex>, IQPSKSymbolDecoder public class QPSKSymbolDecoder implements Listener<Complex>, IQPSKSymbolDecoder
{ {
@@ -63,7 +64,7 @@ public class QPSKSymbolDecoder implements Listener<Complex>, IQPSKSymbolDecoder
public Dibit decode(Complex complex ) public Dibit decode(Complex complex )
{ {
if( Math.abs( complex.inphase() ) > Math.abs( complex.quadrature() ) ) if( FastMath.abs( complex.inphase() ) > FastMath.abs( complex.quadrature() ) )
{ {
if( complex.inphase() > 0 ) if( complex.inphase() > 0 )
{ {

View File

@@ -16,6 +16,7 @@
package io.github.dsheirer.dsp.psk; package io.github.dsheirer.dsp.psk;
import io.github.dsheirer.sample.complex.Complex; import io.github.dsheirer.sample.complex.Complex;
import org.apache.commons.math3.util.FastMath;
/** /**
* Calculates the phase error for a QPSK polar-orientation constellation * Calculates the phase error for a QPSK polar-orientation constellation
@@ -29,7 +30,7 @@ public class QPSKSymbolPhaseErrorCalculator implements ISymbolPhaseErrorCalculat
{ {
mPhaseError = 0.0f; mPhaseError = 0.0f;
if(Math.abs(symbol.inphase()) > Math.abs(symbol.quadrature())) if(FastMath.abs(symbol.inphase()) > FastMath.abs(symbol.quadrature()))
{ {
if(symbol.inphase() > 0) if(symbol.inphase() > 0)
{ {

View File

@@ -23,11 +23,12 @@ package io.github.dsheirer.dsp.psk;
import io.github.dsheirer.buffer.ComplexCircularBuffer; import io.github.dsheirer.buffer.ComplexCircularBuffer;
import io.github.dsheirer.sample.complex.Complex; import io.github.dsheirer.sample.complex.Complex;
import org.apache.commons.math3.util.FastMath;
public class SymbolDecisionData public class SymbolDecisionData
{ {
//45 degrees rotation to orient the symbol to a polar axis to make error calculation easy/efficient //45 degrees rotation to orient the symbol to a polar axis to make error calculation easy/efficient
public static final Complex DIFFERENTIAL_OFFSET = Complex.fromAngle(Math.PI / 4.0d); public static final Complex DIFFERENTIAL_OFFSET = Complex.fromAngle(FastMath.PI / 4.0d);
private ComplexCircularBuffer mBuffer; private ComplexCircularBuffer mBuffer;
private float mSamplingPoint; private float mSamplingPoint;

View File

@@ -15,11 +15,13 @@
******************************************************************************/ ******************************************************************************/
package io.github.dsheirer.dsp.psk; package io.github.dsheirer.dsp.psk;
import org.apache.commons.math3.util.FastMath;
public enum SymbolInversion public enum SymbolInversion
{ {
DEGREES_90_PLUS(Math.PI / 2.0), DEGREES_90_PLUS(FastMath.PI / 2.0),
DEGREES_90_MINUS(Math.PI / -2.0), DEGREES_90_MINUS(FastMath.PI / -2.0),
DEGREES_180(Math.PI); DEGREES_180(FastMath.PI);
private double mAngleRadians; private double mAngleRadians;

View File

@@ -22,6 +22,7 @@
package io.github.dsheirer.dsp.psk.pll; package io.github.dsheirer.dsp.psk.pll;
import io.github.dsheirer.sample.complex.Complex; import io.github.dsheirer.sample.complex.Complex;
import org.apache.commons.math3.util.FastMath;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -38,13 +39,13 @@ public class CostasLoop implements IPhaseLockedLoop
{ {
private final static Logger mLog = LoggerFactory.getLogger(CostasLoop.class); private final static Logger mLog = LoggerFactory.getLogger(CostasLoop.class);
public static final double TWO_PI = 2.0 * Math.PI; public static final double TWO_PI = 2.0 * FastMath.PI;
private Complex mCurrentVector = new Complex(0, 0); private Complex mCurrentVector = new Complex(0, 0);
private double mLoopPhase = 0.0; private double mLoopPhase = 0.0;
private double mLoopFrequency = 0.0; private double mLoopFrequency = 0.0;
private double mMaximumLoopFrequency; private double mMaximumLoopFrequency;
private double mDamping = Math.sqrt(2.0) / 2.0; private double mDamping = FastMath.sqrt(2.0) / 2.0;
private double mAlphaGain; private double mAlphaGain;
private double mBetaGain; private double mBetaGain;
private PLLBandwidth mPLLBandwidth = PLLBandwidth.BW_400; private PLLBandwidth mPLLBandwidth = PLLBandwidth.BW_400;

View File

@@ -86,9 +86,9 @@ public enum PLLBandwidth
*/ */
public static PLLBandwidth fromSyncCount(int syncCount) public static PLLBandwidth fromSyncCount(int syncCount)
{ {
if(LOOKUP_MAP.containsKey(syncCount)) PLLBandwidth mapValue = LOOKUP_MAP.get(syncCount);
{ if (mapValue != null) {
return LOOKUP_MAP.get(syncCount); return mapValue;
} }
return BW_200; return BW_200;

View File

@@ -70,9 +70,9 @@ public class QPSKPhaseInversionCalculator
} }
System.out.println("NORMAL: " + sync); System.out.println("NORMAL: " + sync);
System.out.println(" +90: " + sbP90.toString()); System.out.println(" +90: " + sbP90);
System.out.println(" -90: " + sbM90.toString()); System.out.println(" -90: " + sbM90);
System.out.println(" 180: " + sb180.toString()); System.out.println(" 180: " + sb180);
} }
} }

View File

@@ -22,6 +22,7 @@
package io.github.dsheirer.edac; package io.github.dsheirer.edac;
import org.apache.commons.math3.util.FastMath;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -304,14 +305,7 @@ public class BerlekempMassey_63
/* have now found q such that d[u]!=0 and u_lu[q] is maximum */ /* have now found q such that d[u]!=0 and u_lu[q] is maximum */
/* store degree of new elp polynomial */ /* store degree of new elp polynomial */
if( l[ u ] > l[ q ] + u - q ) l[u + 1] = FastMath.max(l[u], l[q] + u - q);
{
l[ u + 1 ] = l[ u ];
}
else
{
l[ u + 1 ] = l[ q ] + u - q;
}
/* form new elp(x) */ /* form new elp(x) */
for( int i = 0; i < NN - KK; i++ ) for( int i = 0; i < NN - KK; i++ )
@@ -373,10 +367,7 @@ public class BerlekempMassey_63
} }
/* find roots of the error location polynomial */ /* find roots of the error location polynomial */
for( int i = 1; i <= l[u]; i++ ) if (l[u] >= 0) System.arraycopy(elp[u], 1, reg, 1, l[u]);
{
reg[ i ] = elp[ u ][ i ];
}
count = 0; count = 0;

View File

@@ -63,16 +63,10 @@ public enum CRC
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for(int x = 0; x < checks.length; x++) for (CRC check : checks) {
{ if (check != null) {
CRC check = checks[x];
if(check != null)
{
sb.append(check.getAbbreviation()); sb.append(check.getAbbreviation());
} } else {
else
{
sb.append(CRC.UNKNOWN.getAbbreviation()); sb.append(CRC.UNKNOWN.getAbbreviation());
} }
} }

View File

@@ -18,6 +18,8 @@
******************************************************************************/ ******************************************************************************/
package io.github.dsheirer.edac.trellis; package io.github.dsheirer.edac.trellis;
import org.apache.commons.math3.util.FastMath;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
@@ -41,8 +43,8 @@ public abstract class ViterbiDecoder
mInputBitLength = inputBitLength; mInputBitLength = inputBitLength;
mOutputBitLength = outputBitLength; mOutputBitLength = outputBitLength;
mInputValueCount = (int)Math.pow(2.0, mInputBitLength); mInputValueCount = (int) FastMath.pow(2.0, mInputBitLength);
mOutputValueCount = (int)Math.pow(2.0, mOutputBitLength); mOutputValueCount = (int)FastMath.pow(2.0, mOutputBitLength);
} }
/** /**

View File

@@ -75,14 +75,7 @@ public class FilterEditorPanel<T> extends JPanel
List<IFilter<T>> filters = filterSet.getFilters(); List<IFilter<T>> filters = filterSet.getFilters();
/* sort the filters in alphabetical order by name */ /* sort the filters in alphabetical order by name */
Collections.sort(filters, new Comparator<IFilter<?>>() filters.sort((Comparator<IFilter<?>>) (first, second) -> first.getName().compareTo(second.getName()));
{
@Override
public int compare(IFilter<?> first, IFilter<?> second)
{
return first.getName().compareTo(second.getName());
}
});
for(IFilter<T> filter : filters) for(IFilter<T> filter : filters)
{ {
@@ -105,14 +98,7 @@ public class FilterEditorPanel<T> extends JPanel
{ {
List<FilterElement<?>> elements = filter.getFilterElements(); List<FilterElement<?>> elements = filter.getFilterElements();
Collections.sort(elements, new Comparator<FilterElement<?>>() elements.sort(Comparator.comparing(FilterElement::toString));
{
@Override
public int compare(FilterElement<?> o1, FilterElement<?> o2)
{
return o1.toString().compareTo(o2.toString());
}
});
for(FilterElement<?> element : elements) for(FilterElement<?> element : elements)
{ {

View File

@@ -25,18 +25,18 @@ public class ChannelMemoryLogger implements Runnable, ChannelEventListener
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append( "CHAN TOT:" + mChannelCount ); sb.append("CHAN TOT:").append(mChannelCount);
sb.append( " TRFC:" + mTrafficChannelCount ); sb.append(" TRFC:").append(mTrafficChannelCount);
sb.append( " PROC:" + mChannelProcessingCount ); sb.append(" PROC:").append(mChannelProcessingCount);
long maxMemory = runtime.maxMemory(); long maxMemory = runtime.maxMemory();
long allocatedMemory = runtime.totalMemory(); long allocatedMemory = runtime.totalMemory();
long freeMemory = runtime.freeMemory(); long freeMemory = runtime.freeMemory();
sb.append(" MEM FREE: " + format.format(freeMemory / 1024) ); sb.append(" MEM FREE: ").append(format.format(freeMemory / 1024));
sb.append(" ALLOC: " + format.format(allocatedMemory / 1024) ); sb.append(" ALLOC: ").append(format.format(allocatedMemory / 1024));
sb.append(" MAX: " + format.format(maxMemory / 1024) ); sb.append(" MAX: ").append(format.format(maxMemory / 1024));
sb.append(" TOTAL: " + format.format((freeMemory + (maxMemory - allocatedMemory)) / 1024) ); sb.append(" TOTAL: ").append(format.format((freeMemory + (maxMemory - allocatedMemory)) / 1024));
mLog.debug( sb.toString() ); mLog.debug( sb.toString() );
} }

View File

@@ -3,6 +3,7 @@ package io.github.dsheirer.gui.control;
import io.github.dsheirer.buffer.CircularBuffer; import io.github.dsheirer.buffer.CircularBuffer;
import io.github.dsheirer.sample.Listener; import io.github.dsheirer.sample.Listener;
import io.github.dsheirer.sample.complex.Complex; import io.github.dsheirer.sample.complex.Complex;
import org.apache.commons.math3.util.FastMath;
import javax.swing.*; import javax.swing.*;
import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeEvent;
@@ -135,7 +136,7 @@ public class ConstellationViewer extends JPanel implements Listener<Complex>
* serves as the instantaneous amplitude of the demodulated signal * serves as the instantaneous amplitude of the demodulated signal
*/ */
double denominator = 1.0d / i; double denominator = 1.0d / i;
angle = Math.atan( (double)q * denominator ); angle = FastMath.atan( (double)q * denominator );
} }
Ellipse2D.Double ellipse = Ellipse2D.Double ellipse =

View File

@@ -22,6 +22,7 @@ import io.github.dsheirer.source.InvalidFrequencyException;
import io.github.dsheirer.source.SourceEvent; import io.github.dsheirer.source.SourceEvent;
import io.github.dsheirer.source.SourceException; import io.github.dsheirer.source.SourceException;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import org.apache.commons.math3.util.FastMath;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -287,17 +288,17 @@ public class JFrequencyControl extends JPanel implements ISourceEventProcessor
public void setFrequency(long frequency, boolean fireChangeEvent) public void setFrequency(long frequency, boolean fireChangeEvent)
{ {
//Strip the digits higher than this one //Strip the digits higher than this one
long lower = frequency % (long)(Math.pow(10, mPower + 1)); long lower = frequency % (long)(FastMath.pow(10, mPower + 1));
//Set the value to int value of dividing by 10 to this power //Set the value to int value of dividing by 10 to this power
long value = (long)(lower / (long)(Math.pow(10, mPower))); long value = (long)(lower / (long)(FastMath.pow(10, mPower)));
set(value, fireChangeEvent); set(value, fireChangeEvent);
} }
public long getFrequency() public long getFrequency()
{ {
return mValue * (long)Math.pow(10, mPower); return mValue * (long)FastMath.pow(10, mPower);
} }
public void increment() public void increment()

View File

@@ -337,8 +337,7 @@ public class MultipleFrequencyEditor extends JPanel
*/ */
public List<Long> getFrequencies() public List<Long> getFrequencies()
{ {
List<Long> frequencies = new ArrayList<>(); List<Long> frequencies = new ArrayList<>(mFrequencies);
frequencies.addAll(mFrequencies);
return frequencies; return frequencies;
} }
} }

View File

@@ -28,6 +28,7 @@ import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.scene.chart.LineChart; import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis; import javafx.scene.chart.NumberAxis;
import org.apache.commons.math3.util.FastMath;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -35,7 +36,7 @@ public class ComplexPhaseLineChart extends LineChart implements Listener<Reusabl
{ {
private final static Logger mLog = LoggerFactory.getLogger(ComplexPhaseLineChart.class); private final static Logger mLog = LoggerFactory.getLogger(ComplexPhaseLineChart.class);
private static final Complex ANGLE_OFFSET_45_DEGREES = Complex.fromAngle(Math.PI / 4.0); private static final Complex ANGLE_OFFSET_45_DEGREES = Complex.fromAngle(FastMath.PI / 4.0);
private ComplexCircularBuffer mComplexCircularBuffer; private ComplexCircularBuffer mComplexCircularBuffer;
private ComplexGain mComplexGain = new ComplexGain(600.0f); private ComplexGain mComplexGain = new ComplexGain(600.0f);
private ObservableList<Data<Integer,Float>> mPhaseValues = FXCollections.observableArrayList(); private ObservableList<Data<Integer,Float>> mPhaseValues = FXCollections.observableArrayList();
@@ -44,7 +45,7 @@ public class ComplexPhaseLineChart extends LineChart implements Listener<Reusabl
public ComplexPhaseLineChart(int length) public ComplexPhaseLineChart(int length)
{ {
super(new NumberAxis("Time", 1, length - 10, 2), super(new NumberAxis("Time", 1, length - 10, 2),
new NumberAxis("Phase", -Math.PI, Math.PI, Math.PI / 2.0)); new NumberAxis("Phase", -FastMath.PI, FastMath.PI, FastMath.PI / 2.0));
Series<Integer,Float> phaseSeries = new Series<>("Phase", mPhaseValues); Series<Integer,Float> phaseSeries = new Series<>("Phase", mPhaseValues);
ObservableList<Series<Integer,Float>> observableList = FXCollections.observableArrayList(phaseSeries); ObservableList<Series<Integer,Float>> observableList = FXCollections.observableArrayList(phaseSeries);

View File

@@ -28,6 +28,7 @@ import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.scene.chart.LineChart; import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis; import javafx.scene.chart.NumberAxis;
import org.apache.commons.math3.util.FastMath;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -97,7 +98,7 @@ public class EyeDiagramChart extends LineChart implements Listener<SymbolDecisio
{ {
corrected[x] = samples[x].angle(); corrected[x] = samples[x].angle();
if(x > 0 && (Math.abs(corrected[x] - corrected[x - 1]) > Math.PI)) if(x > 0 && (FastMath.abs(corrected[x] - corrected[x - 1]) > FastMath.PI))
{ {
phaseRolloverIndex = x; phaseRolloverIndex = x;
} }
@@ -109,11 +110,11 @@ public class EyeDiagramChart extends LineChart implements Listener<SymbolDecisio
{ {
if(corrected[x] > 0) if(corrected[x] > 0)
{ {
corrected[x] -= 2 * Math.PI; corrected[x] -= 2 * FastMath.PI;
} }
else else
{ {
corrected[x] += 2 * Math.PI; corrected[x] += 2 * FastMath.PI;
} }
} }
} }

View File

@@ -85,9 +85,7 @@ public class SampleXYChart extends PolarChart<XYChartItem> implements Listener<R
series.getItems().clear(); series.getItems().clear();
for(int x = 0; x < complexSamples.length; x++) for (Complex sample : complexSamples) {
{
Complex sample = complexSamples[x];
series.getItems().add(new XYChartItem(sample.polarAngleDegrees(), sample.magnitude(), Color.BLUE)); series.getItems().add(new XYChartItem(sample.polarAngleDegrees(), sample.magnitude(), Color.BLUE));
} }

View File

@@ -20,6 +20,7 @@
package io.github.dsheirer.gui.preference; package io.github.dsheirer.gui.preference;
import io.github.dsheirer.preference.UserPreferences; import io.github.dsheirer.preference.UserPreferences;
import io.github.dsheirer.protocol.Protocol;
import javafx.application.Application; import javafx.application.Application;
import javafx.beans.value.ChangeListener; import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
@@ -41,6 +42,7 @@ import javafx.stage.Window;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.EnumMap;
import java.util.HashMap; import java.util.HashMap;
import java.util.ListIterator; import java.util.ListIterator;
import java.util.Map; import java.util.Map;
@@ -52,7 +54,7 @@ public class PreferencesEditor extends Application
{ {
private final static Logger mLog = LoggerFactory.getLogger(PreferencesEditor.class); private final static Logger mLog = LoggerFactory.getLogger(PreferencesEditor.class);
private Map<PreferenceEditorType,Node> mEditors = new HashMap<>(); private Map<PreferenceEditorType,Node> mEditors = new EnumMap<>(PreferenceEditorType.class);
private UserPreferences mUserPreferences; private UserPreferences mUserPreferences;
private HBox mParentBox; private HBox mParentBox;
private TreeView mEditorSelectionTreeView; private TreeView mEditorSelectionTreeView;
@@ -118,22 +120,14 @@ public class PreferencesEditor extends Application
private TreeItem recursivelyFindEditorType(TreeItem parent, PreferenceEditorType type) private TreeItem recursivelyFindEditorType(TreeItem parent, PreferenceEditorType type)
{ {
ListIterator<TreeItem> li = parent.getChildren().listIterator();
while(li.hasNext()) for (TreeItem treeItem : (Iterable<TreeItem>) parent.getChildren()) {
{ if (treeItem.getValue() instanceof PreferenceEditorType && (treeItem.getValue()).equals(type)) {
TreeItem treeItem = li.next();
if(treeItem.getValue() instanceof PreferenceEditorType && (treeItem.getValue()).equals(type))
{
return treeItem; return treeItem;
} } else {
else
{
TreeItem item = recursivelyFindEditorType(treeItem, type); TreeItem item = recursivelyFindEditorType(treeItem, type);
if(item != null) if (item != null) {
{
return item; return item;
} }
} }

View File

@@ -151,9 +151,9 @@ public class IconManager
String scaledIconName = name + height; String scaledIconName = name + height;
if(mResizedIcons.containsKey(scaledIconName)) ImageIcon mapValue = mResizedIcons.get(scaledIconName);
{ if (mapValue != null) {
return mResizedIcons.get(scaledIconName); return mapValue;
} }
Icon icon = getModel().getIcon(name); Icon icon = getModel().getIcon(name);

View File

@@ -168,7 +168,7 @@ public class IconTableModel extends AbstractTableModel
Collections.sort(icons); Collections.sort(icons);
return icons.toArray(new Icon[icons.size()]); return icons.toArray(new Icon[0]);
} }
/** /**

View File

@@ -198,7 +198,7 @@ public class IdentifierCollection
sb.append("Identifier: ").append(i).append(" Class:").append(i.getClass()).append("\n"); sb.append("Identifier: ").append(i).append(" Class:").append(i.getClass()).append("\n");
} }
} }
mLog.warn("An identifier in a collection is somehow null ...\n" + sb.toString()); mLog.warn("An identifier in a collection is somehow null ...\n" + sb);
} }
} }

View File

@@ -157,13 +157,9 @@ public class PatchGroupManager
PatchGroupIdentifier patchGroupIdentifier = (PatchGroupIdentifier)identifier; PatchGroupIdentifier patchGroupIdentifier = (PatchGroupIdentifier)identifier;
int patchGroupId = patchGroupIdentifier.getValue().getPatchGroup().getValue(); int patchGroupId = patchGroupIdentifier.getValue().getPatchGroup().getValue();
if(mPatchGroupMap.containsKey(patchGroupId)) Identifier mapValue = mPatchGroupMap.get(patchGroupId);
{ if (mapValue != null) {
return mPatchGroupMap.get(patchGroupId); return mapValue;
}
else
{
addPatchGroup(patchGroupIdentifier);
} }
} }
break; break;

View File

@@ -17,6 +17,7 @@
******************************************************************************/ ******************************************************************************/
package io.github.dsheirer.map; package io.github.dsheirer.map;
import org.apache.commons.math3.util.FastMath;
import org.jdesktop.swingx.JXMapViewer; import org.jdesktop.swingx.JXMapViewer;
import java.awt.*; import java.awt.*;
@@ -89,10 +90,10 @@ public class SelectionAdapter extends MouseAdapter
{ {
if (dragging) if (dragging)
{ {
int x1 = (int) Math.min(startPos.getX(), endPos.getX()); int x1 = (int) FastMath.min(startPos.getX(), endPos.getX());
int y1 = (int) Math.min(startPos.getY(), endPos.getY()); int y1 = (int) FastMath.min(startPos.getY(), endPos.getY());
int x2 = (int) Math.max(startPos.getX(), endPos.getX()); int x2 = (int) FastMath.max(startPos.getX(), endPos.getX());
int y2 = (int) Math.max(startPos.getY(), endPos.getY()); int y2 = (int) FastMath.max(startPos.getY(), endPos.getY());
return new Rectangle(x1, y1, x2-x1, y2-y1); return new Rectangle(x1, y1, x2-x1, y2-y1);
} }

View File

@@ -143,146 +143,28 @@ public class DecoderFactory
switch(decodeConfig.getDecoderType()) switch(decodeConfig.getDecoderType())
{ {
case AM: case AM:
modules.add(new AMDecoder(decodeConfig)); processAM(channel, modules, aliasList, decodeConfig);
modules.add(new AlwaysUnsquelchedDecoderState(DecoderType.AM, channel.getName()));
AudioModule audioModuleAM = new AudioModule(aliasList);
modules.add(audioModuleAM);
//Check if the user wants all audio recorded ..
if(((DecodeConfigAM)decodeConfig).getRecordAudio())
{
audioModuleAM.setRecordAudio(true);
}
if(channel.getSourceConfiguration().getSourceType() == SourceType.TUNER)
{
modules.add(new AMDemodulatorModule(AM_CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE));
}
break; break;
case NBFM: case NBFM:
modules.add(new NBFMDecoder(decodeConfig)); processNBFM(channel, modules, aliasList, decodeConfig);
modules.add(new AlwaysUnsquelchedDecoderState(DecoderType.NBFM, channel.getName()));
AudioModule audioModuleFM = new AudioModule(aliasList);
//Check if the user wants all audio recorded ..
if(((DecodeConfigNBFM)decodeConfig).getRecordAudio())
{
audioModuleFM.setRecordAudio(true);
}
modules.add(audioModuleFM);
if(channel.getSourceConfiguration().getSourceType() == SourceType.TUNER)
{
modules.add(new FMDemodulatorModule(FM_CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE));
}
break; break;
case LTR_STANDARD: case LTR_STANDARD:
MessageDirection direction = ((DecodeConfigLTRStandard)decodeConfig).getMessageDirection(); processLTRStandard(channel, modules, aliasList, (DecodeConfigLTRStandard) decodeConfig);
modules.add(new LTRStandardDecoder(null, direction));
modules.add(new LTRStandardDecoderState());
modules.add(new AudioModule(aliasList));
if(channel.getSourceConfiguration().getSourceType() == SourceType.TUNER)
{
modules.add(new FMDemodulatorModule(FM_CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE));
}
break; break;
case LTR_NET: case LTR_NET:
modules.add(new LTRNetDecoder((DecodeConfigLTRNet)decodeConfig)); processLTRNet(channel, modules, aliasList, (DecodeConfigLTRNet) decodeConfig);
modules.add(new LTRNetDecoderState());
modules.add(new AudioModule(aliasList));
if(channel.getSourceConfiguration().getSourceType() == SourceType.TUNER)
{
modules.add(new FMDemodulatorModule(FM_CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE));
}
break; break;
case MPT1327: case MPT1327:
DecodeConfigMPT1327 mptConfig = (DecodeConfigMPT1327)decodeConfig; processMPT1327(channelMapModel, channel, userPreferences, modules, aliasList, channelType, (DecodeConfigMPT1327) decodeConfig);
ChannelMap channelMap = channelMapModel.getChannelMap(mptConfig.getChannelMapName());
Sync sync = mptConfig.getSync();
modules.add(new MPT1327Decoder(sync));
modules.add(new AudioModule(aliasList));
SourceType sourceType = channel.getSourceConfiguration().getSourceType();
if(sourceType == SourceType.TUNER || sourceType == SourceType.TUNER_MULTIPLE_FREQUENCIES)
{
modules.add(new FMDemodulatorModule(FM_CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE));
}
long timeout = mptConfig.getCallTimeout() * 1000;
if(channelType == ChannelType.STANDARD)
{
MPT1327TrafficChannelManager trafficChannelManager = new MPT1327TrafficChannelManager(channel, channelMap);
modules.add(trafficChannelManager);
modules.add(new MPT1327DecoderState(trafficChannelManager, channelType, timeout));
}
else
{
modules.add(new MPT1327DecoderState(channelType, timeout));
}
//Add a channel rotation monitor when we have multiple control channel frequencies specified
if(channel.getSourceConfiguration() instanceof SourceConfigTunerMultipleFrequency &&
((SourceConfigTunerMultipleFrequency)channel.getSourceConfiguration()).hasMultipleFrequencies())
{
List<State> activeStates = new ArrayList<>();
activeStates.add(State.CONTROL);
modules.add(new ChannelRotationMonitor(activeStates, userPreferences));
}
break; break;
case PASSPORT: case PASSPORT:
modules.add(new PassportDecoder(decodeConfig)); processPassport(channel, modules, aliasList, decodeConfig);
modules.add(new PassportDecoderState());
modules.add(new AudioModule(aliasList));
if(channel.getSourceConfiguration().getSourceType() == SourceType.TUNER)
{
modules.add(new FMDemodulatorModule(FM_CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE));
}
break; break;
case P25_PHASE1: case P25_PHASE1:
DecodeConfigP25Phase1 p25Config = (DecodeConfigP25Phase1)decodeConfig; processP25Phase1(channel, userPreferences, modules, aliasList, channelType, (DecodeConfigP25Phase1) decodeConfig);
switch(p25Config.getModulation())
{
case C4FM:
modules.add(new P25P1DecoderC4FM());
break;
case CQPSK:
modules.add(new P25P1DecoderLSM());
break;
default:
throw new IllegalArgumentException("Unrecognized P25 Phase 1 Modulation [" +
p25Config.getModulation() + "]");
}
if(channelType == ChannelType.STANDARD)
{
P25TrafficChannelManager trafficChannelManager = new P25TrafficChannelManager(channel);
modules.add(trafficChannelManager);
modules.add(new P25P1DecoderState(channel, trafficChannelManager));
}
else
{
modules.add(new P25P1DecoderState(channel));
}
modules.add(new P25P1AudioModule(userPreferences, aliasList));
//Add a channel rotation monitor when we have multiple control channel frequencies specified
if(channel.getSourceConfiguration() instanceof SourceConfigTunerMultipleFrequency &&
((SourceConfigTunerMultipleFrequency)channel.getSourceConfiguration()).hasMultipleFrequencies())
{
List<State> activeStates = new ArrayList<>();
activeStates.add(State.CONTROL);
modules.add(new ChannelRotationMonitor(activeStates, userPreferences));
}
break; break;
case P25_PHASE2: case P25_PHASE2:
modules.add(new P25P2DecoderHDQPSK((DecodeConfigP25Phase2)channel.getDecodeConfiguration())); processP25Phase2(channel, userPreferences, modules, aliasList);
modules.add(new P25P2DecoderState(channel, 0));
modules.add(new P25P2DecoderState(channel, 1));
modules.add(new P25P2AudioModule(userPreferences, 0, aliasList));
modules.add(new P25P2AudioModule(userPreferences, 1, aliasList));
break; break;
default: default:
throw new IllegalArgumentException("Unknown decoder type [" + decodeConfig.getDecoderType().toString() + "]"); throw new IllegalArgumentException("Unknown decoder type [" + decodeConfig.getDecoderType().toString() + "]");
@@ -291,6 +173,156 @@ public class DecoderFactory
return modules; return modules;
} }
private static void processP25Phase2(Channel channel, UserPreferences userPreferences, List<Module> modules, AliasList aliasList) {
modules.add(new P25P2DecoderHDQPSK((DecodeConfigP25Phase2)channel.getDecodeConfiguration()));
modules.add(new P25P2DecoderState(channel, 0));
modules.add(new P25P2DecoderState(channel, 1));
modules.add(new P25P2AudioModule(userPreferences, 0, aliasList));
modules.add(new P25P2AudioModule(userPreferences, 1, aliasList));
}
private static void processP25Phase1(Channel channel, UserPreferences userPreferences, List<Module> modules, AliasList aliasList, ChannelType channelType, DecodeConfigP25Phase1 decodeConfig) {
DecodeConfigP25Phase1 p25Config = decodeConfig;
switch(p25Config.getModulation())
{
case C4FM:
modules.add(new P25P1DecoderC4FM());
break;
case CQPSK:
modules.add(new P25P1DecoderLSM());
break;
default:
throw new IllegalArgumentException("Unrecognized P25 Phase 1 Modulation [" +
p25Config.getModulation() + "]");
}
if(channelType == ChannelType.STANDARD)
{
P25TrafficChannelManager trafficChannelManager = new P25TrafficChannelManager(channel);
modules.add(trafficChannelManager);
modules.add(new P25P1DecoderState(channel, trafficChannelManager));
}
else
{
modules.add(new P25P1DecoderState(channel));
}
modules.add(new P25P1AudioModule(userPreferences, aliasList));
//Add a channel rotation monitor when we have multiple control channel frequencies specified
if(channel.getSourceConfiguration() instanceof SourceConfigTunerMultipleFrequency &&
((SourceConfigTunerMultipleFrequency)channel.getSourceConfiguration()).hasMultipleFrequencies())
{
List<State> activeStates = new ArrayList<>();
activeStates.add(State.CONTROL);
modules.add(new ChannelRotationMonitor(activeStates, userPreferences));
}
}
private static void processPassport(Channel channel, List<Module> modules, AliasList aliasList, DecodeConfiguration decodeConfig) {
modules.add(new PassportDecoder(decodeConfig));
modules.add(new PassportDecoderState());
modules.add(new AudioModule(aliasList));
if(channel.getSourceConfiguration().getSourceType() == SourceType.TUNER)
{
modules.add(new FMDemodulatorModule(FM_CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE));
}
}
private static void processMPT1327(ChannelMapModel channelMapModel, Channel channel, UserPreferences userPreferences, List<Module> modules, AliasList aliasList, ChannelType channelType, DecodeConfigMPT1327 decodeConfig) {
DecodeConfigMPT1327 mptConfig = decodeConfig;
ChannelMap channelMap = channelMapModel.getChannelMap(mptConfig.getChannelMapName());
Sync sync = mptConfig.getSync();
modules.add(new MPT1327Decoder(sync));
modules.add(new AudioModule(aliasList));
SourceType sourceType = channel.getSourceConfiguration().getSourceType();
if(sourceType == SourceType.TUNER || sourceType == SourceType.TUNER_MULTIPLE_FREQUENCIES)
{
modules.add(new FMDemodulatorModule(FM_CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE));
}
long timeout = mptConfig.getCallTimeout() * 1000;
if(channelType == ChannelType.STANDARD)
{
MPT1327TrafficChannelManager trafficChannelManager = new MPT1327TrafficChannelManager(channel, channelMap);
modules.add(trafficChannelManager);
modules.add(new MPT1327DecoderState(trafficChannelManager, channelType, timeout));
}
else
{
modules.add(new MPT1327DecoderState(channelType, timeout));
}
//Add a channel rotation monitor when we have multiple control channel frequencies specified
if(channel.getSourceConfiguration() instanceof SourceConfigTunerMultipleFrequency &&
((SourceConfigTunerMultipleFrequency)channel.getSourceConfiguration()).hasMultipleFrequencies())
{
List<State> activeStates = new ArrayList<>();
activeStates.add(State.CONTROL);
modules.add(new ChannelRotationMonitor(activeStates, userPreferences));
}
}
private static void processLTRNet(Channel channel, List<Module> modules, AliasList aliasList, DecodeConfigLTRNet decodeConfig) {
modules.add(new LTRNetDecoder(decodeConfig));
modules.add(new LTRNetDecoderState());
modules.add(new AudioModule(aliasList));
if(channel.getSourceConfiguration().getSourceType() == SourceType.TUNER)
{
modules.add(new FMDemodulatorModule(FM_CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE));
}
}
private static void processLTRStandard(Channel channel, List<Module> modules, AliasList aliasList, DecodeConfigLTRStandard decodeConfig) {
MessageDirection direction = decodeConfig.getMessageDirection();
modules.add(new LTRStandardDecoder(null, direction));
modules.add(new LTRStandardDecoderState());
modules.add(new AudioModule(aliasList));
if(channel.getSourceConfiguration().getSourceType() == SourceType.TUNER)
{
modules.add(new FMDemodulatorModule(FM_CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE));
}
}
private static void processNBFM(Channel channel, List<Module> modules, AliasList aliasList, DecodeConfiguration decodeConfig) {
modules.add(new NBFMDecoder(decodeConfig));
modules.add(new AlwaysUnsquelchedDecoderState(DecoderType.NBFM, channel.getName()));
AudioModule audioModuleFM = new AudioModule(aliasList);
//Check if the user wants all audio recorded ..
if(((DecodeConfigNBFM)decodeConfig).getRecordAudio())
{
audioModuleFM.setRecordAudio(true);
}
modules.add(audioModuleFM);
if(channel.getSourceConfiguration().getSourceType() == SourceType.TUNER)
{
modules.add(new FMDemodulatorModule(FM_CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE));
}
}
private static void processAM(Channel channel, List<Module> modules, AliasList aliasList, DecodeConfiguration decodeConfig) {
modules.add(new AMDecoder(decodeConfig));
modules.add(new AlwaysUnsquelchedDecoderState(DecoderType.AM, channel.getName()));
AudioModule audioModuleAM = new AudioModule(aliasList);
modules.add(audioModuleAM);
//Check if the user wants all audio recorded ..
if(((DecodeConfigAM)decodeConfig).getRecordAudio())
{
audioModuleAM.setRecordAudio(true);
}
if(channel.getSourceConfiguration().getSourceType() == SourceType.TUNER)
{
modules.add(new AMDemodulatorModule(AM_CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE));
}
}
/** /**
* Constructs a list of auxiliary decoders, as specified in the configuration * Constructs a list of auxiliary decoders, as specified in the configuration
* *

View File

@@ -167,11 +167,9 @@ public class Fleetsync2DecoderState extends DecoderState
} }
else else
{ {
Iterator<FleetsyncIdentifier> it = mIdents.iterator();
while(it.hasNext()) for (FleetsyncIdentifier mIdent : mIdents) {
{ sb.append(" ").append(mIdent.formatted()).append("\n");
sb.append(" ").append(it.next().formatted()).append("\n");
} }
} }

View File

@@ -24,15 +24,13 @@ import io.github.dsheirer.filter.Filter;
import io.github.dsheirer.filter.FilterElement; import io.github.dsheirer.filter.FilterElement;
import io.github.dsheirer.message.IMessage; import io.github.dsheirer.message.IMessage;
import io.github.dsheirer.module.decode.fleetsync2.message.Fleetsync2Message; import io.github.dsheirer.module.decode.fleetsync2.message.Fleetsync2Message;
import io.github.dsheirer.module.decode.ltrnet.LtrNetMessageType;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.List;
public class FleetsyncMessageFilter extends Filter<IMessage> public class FleetsyncMessageFilter extends Filter<IMessage>
{ {
private HashMap<FleetsyncMessageType,FilterElement<FleetsyncMessageType>> mElements = private Map<FleetsyncMessageType,FilterElement<FleetsyncMessageType>> mElements = new EnumMap<>(FleetsyncMessageType.class);
new HashMap<FleetsyncMessageType,FilterElement<FleetsyncMessageType>>();
public FleetsyncMessageFilter() public FleetsyncMessageFilter()
{ {

View File

@@ -25,6 +25,7 @@ import io.github.dsheirer.identifier.Role;
import io.github.dsheirer.identifier.esn.ESNIdentifier; import io.github.dsheirer.identifier.esn.ESNIdentifier;
import io.github.dsheirer.message.Message; import io.github.dsheirer.message.Message;
import io.github.dsheirer.protocol.Protocol; import io.github.dsheirer.protocol.Protocol;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -183,9 +184,9 @@ public class LJ1200Message extends Message
sb.append("] ADDRESS ["); sb.append("] ADDRESS [");
sb.append(getAddress()); sb.append(getAddress());
sb.append("] VRC [" + getVRC()); sb.append("] VRC [").append(getVRC());
sb.append("] LRC [" + getLRC()); sb.append("] LRC [").append(getLRC());
sb.append("] CRC [" + getCRC()); sb.append("] CRC [").append(getCRC());
sb.append("]"); sb.append("]");
return sb.toString(); return sb.toString();
@@ -196,16 +197,7 @@ public class LJ1200Message extends Message
*/ */
public String pad(String value, int places, String padCharacter) public String pad(String value, int places, String padCharacter)
{ {
StringBuilder sb = new StringBuilder(); return StringUtils.rightPad(value, places, padCharacter);
sb.append(value);
while(sb.length() < places)
{
sb.append(padCharacter);
}
return sb.toString();
} }
/** /**
@@ -213,18 +205,7 @@ public class LJ1200Message extends Message
*/ */
public String format(int number, int decimalPlaces) public String format(int number, int decimalPlaces)
{ {
StringBuilder sb = new StringBuilder(); return StringUtils.leftPad(Integer.valueOf(number).toString(), decimalPlaces, '0');
int paddingRequired = decimalPlaces - (String.valueOf(number).length());
for(int x = 0; x < paddingRequired; x++)
{
sb.append("0");
}
sb.append(number);
return sb.toString();
} }
@Override @Override

View File

@@ -22,6 +22,7 @@ import io.github.dsheirer.edac.CRC;
import io.github.dsheirer.identifier.Identifier; import io.github.dsheirer.identifier.Identifier;
import io.github.dsheirer.message.Message; import io.github.dsheirer.message.Message;
import io.github.dsheirer.protocol.Protocol; import io.github.dsheirer.protocol.Protocol;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -100,16 +101,7 @@ public class LJ1200TransponderMessage extends Message
*/ */
public String pad(String value, int places, String padCharacter) public String pad(String value, int places, String padCharacter)
{ {
StringBuilder sb = new StringBuilder(); return StringUtils.rightPad(value, places, padCharacter);
sb.append(value);
while(sb.length() < places)
{
sb.append(padCharacter);
}
return sb.toString();
} }
/** /**
@@ -117,18 +109,7 @@ public class LJ1200TransponderMessage extends Message
*/ */
public String format(int number, int decimalPlaces) public String format(int number, int decimalPlaces)
{ {
StringBuilder sb = new StringBuilder(); return StringUtils.leftPad(Integer.valueOf(number).toString(), decimalPlaces, '0');
int paddingRequired = decimalPlaces - (String.valueOf(number).length());
for(int x = 0; x < paddingRequired; x++)
{
sb.append("0");
}
sb.append(number);
return sb.toString();
} }
@Override @Override

View File

@@ -573,7 +573,7 @@ public class LTRNetDecoderState extends DecoderState
else else
{ {
List<LTRTalkgroup> talkgroups = new ArrayList<>(mTalkgroups); List<LTRTalkgroup> talkgroups = new ArrayList<>(mTalkgroups);
Collections.sort(talkgroups, Comparator.comparingInt(Identifier::getValue)); talkgroups.sort(Comparator.comparingInt(Identifier::getValue));
for(LTRTalkgroup talkgroup: talkgroups) for(LTRTalkgroup talkgroup: talkgroups)
{ {
@@ -590,7 +590,7 @@ public class LTRNetDecoderState extends DecoderState
else else
{ {
List<LtrNetRadioIdentifier> ltrNetRadioIdentifiers = new ArrayList<>(mLtrNetRadioIdentifiers); List<LtrNetRadioIdentifier> ltrNetRadioIdentifiers = new ArrayList<>(mLtrNetRadioIdentifiers);
Collections.sort(ltrNetRadioIdentifiers, Comparator.comparingInt(Identifier::getValue)); ltrNetRadioIdentifiers.sort(Comparator.comparingInt(Identifier::getValue));
for(LtrNetRadioIdentifier ltrNetRadioIdentifier : ltrNetRadioIdentifiers) for(LtrNetRadioIdentifier ltrNetRadioIdentifier : ltrNetRadioIdentifiers)
{ {

View File

@@ -4,15 +4,13 @@ import io.github.dsheirer.filter.Filter;
import io.github.dsheirer.filter.FilterElement; import io.github.dsheirer.filter.FilterElement;
import io.github.dsheirer.message.IMessage; import io.github.dsheirer.message.IMessage;
import io.github.dsheirer.module.decode.ltrnet.message.LtrNetMessage; import io.github.dsheirer.module.decode.ltrnet.message.LtrNetMessage;
import io.github.dsheirer.module.decode.ltrstandard.LtrStandardMessageType;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class LTRNetMessageFilter extends Filter<IMessage> public class LTRNetMessageFilter extends Filter<IMessage>
{ {
private Map<LtrNetMessageType, FilterElement<LtrNetMessageType>> mElements = new HashMap<>(); private Map<LtrNetMessageType, FilterElement<LtrNetMessageType>> mElements = new EnumMap<>(LtrNetMessageType.class);
public LTRNetMessageFilter() public LTRNetMessageFilter()
{ {

View File

@@ -24,15 +24,13 @@ import io.github.dsheirer.filter.Filter;
import io.github.dsheirer.filter.FilterElement; import io.github.dsheirer.filter.FilterElement;
import io.github.dsheirer.message.IMessage; import io.github.dsheirer.message.IMessage;
import io.github.dsheirer.module.decode.ltrstandard.message.LTRStandardMessage; import io.github.dsheirer.module.decode.ltrstandard.message.LTRStandardMessage;
import io.github.dsheirer.module.decode.mdc1200.MDCMessageType;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class LTRStandardMessageFilter extends Filter<IMessage> public class LTRStandardMessageFilter extends Filter<IMessage>
{ {
private Map<LtrStandardMessageType,FilterElement<LtrStandardMessageType>> mElements = new HashMap<>(); private Map<LtrStandardMessageType,FilterElement<LtrStandardMessageType>> mElements = new EnumMap<>(LtrStandardMessageType.class);
public LTRStandardMessageFilter() public LTRStandardMessageFilter()
{ {

View File

@@ -152,11 +152,9 @@ public class MDCDecoderState extends DecoderState
} }
else else
{ {
Iterator<MDC1200Identifier> it = mIdents.iterator();
while(it.hasNext()) for (MDC1200Identifier mIdent : mIdents) {
{ sb.append(" ").append(mIdent).append("\n");
sb.append(" ").append(it.next()).append("\n");
} }
} }
@@ -172,11 +170,9 @@ public class MDCDecoderState extends DecoderState
while(it.hasNext()) while(it.hasNext())
{ {
Iterator<MDC1200Identifier> it2 = mIdents.iterator();
while(it2.hasNext()) for (MDC1200Identifier mIdent : mIdents) {
{ sb.append(" ").append(mIdent).append("\n");
sb.append(" ").append(it2.next()).append("\n");
} }
} }
} }

View File

@@ -24,6 +24,7 @@ import io.github.dsheirer.identifier.Identifier;
import io.github.dsheirer.message.Message; import io.github.dsheirer.message.Message;
import io.github.dsheirer.module.decode.mdc1200.identifier.MDC1200Identifier; import io.github.dsheirer.module.decode.mdc1200.identifier.MDC1200Identifier;
import io.github.dsheirer.protocol.Protocol; import io.github.dsheirer.protocol.Protocol;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -177,16 +178,7 @@ public class MDCMessage extends Message
*/ */
public String pad(String value, int places, String padCharacter) public String pad(String value, int places, String padCharacter)
{ {
StringBuilder sb = new StringBuilder(); return StringUtils.rightPad(value, places, padCharacter);
sb.append(value);
while(sb.length() < places)
{
sb.append(padCharacter);
}
return sb.toString();
} }
/** /**
@@ -194,18 +186,7 @@ public class MDCMessage extends Message
*/ */
public String format(int number, int decimalPlaces) public String format(int number, int decimalPlaces)
{ {
StringBuilder sb = new StringBuilder(); return StringUtils.leftPad(Integer.valueOf(number).toString(), decimalPlaces, '0');
int paddingRequired = decimalPlaces - (String.valueOf(number).length());
for(int x = 0; x < paddingRequired; x++)
{
sb.append("0");
}
sb.append(number);
return sb.toString();
} }
@Override @Override
@@ -219,7 +200,7 @@ public class MDCMessage extends Message
{ {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("MDC1200 UNIT:" + getFromIdentifier()); sb.append("MDC1200 UNIT:").append(getFromIdentifier());
if(isEmergency()) if(isEmergency())
{ {
sb.append(" **EMERGENCY**"); sb.append(" **EMERGENCY**");
@@ -235,11 +216,11 @@ public class MDCMessage extends Message
sb.append(" EOT"); sb.append(" EOT");
} }
sb.append(" OPCODE:" + format(getOpcode(), 2)); sb.append(" OPCODE:").append(format(getOpcode(), 2));
sb.append(" ARG:" + format(getArgument(), 3)); sb.append(" ARG:").append(format(getArgument(), 3));
sb.append(" TYPE:" + getPacketType().toString()); sb.append(" TYPE:").append(getPacketType().toString());
sb.append(" ACK:" + getResponse().toString()); sb.append(" ACK:").append(getResponse().toString());
sb.append(" DIR:" + pad(getDirection().toString(), 3, " ")); sb.append(" DIR:").append(pad(getDirection().toString(), 3, " "));
return sb.toString(); return sb.toString();
} }

Some files were not shown because too many files have changed in this diff Show More