mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-09 15:17:24 -05:00
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:
@@ -45,13 +45,7 @@ import io.github.dsheirer.sample.Listener;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 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>
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(AliasList.class);
|
||||
private Map<Protocol,TalkgroupAliasList> mTalkgroupProtocolMap = new HashMap<>();
|
||||
private Map<Protocol,RadioAliasList> mRadioProtocolMap = new HashMap<>();
|
||||
private Map<Protocol,TalkgroupAliasList> mTalkgroupProtocolMap = new EnumMap<>(Protocol.class);
|
||||
private Map<Protocol,RadioAliasList> mRadioProtocolMap = new EnumMap<>(Protocol.class);
|
||||
private Map<String,Alias> mESNMap = new HashMap<>();
|
||||
private Map<Integer,Alias> mStatusMap = new HashMap<>();
|
||||
private boolean mHasAliasActions = false;
|
||||
@@ -487,15 +481,7 @@ public class AliasList implements Listener<AliasEvent>
|
||||
*/
|
||||
public static void remove(Alias alias, Map map)
|
||||
{
|
||||
Iterator<Map.Entry> it = map.entrySet().iterator();
|
||||
|
||||
while(it.hasNext())
|
||||
{
|
||||
if(it.next().getValue().equals(alias))
|
||||
{
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
map.entrySet().removeIf(entry -> alias.equals(((Map.Entry)entry).getValue()));
|
||||
}
|
||||
|
||||
|
||||
@@ -515,16 +501,17 @@ public class AliasList implements Listener<AliasEvent>
|
||||
{
|
||||
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();
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -117,9 +117,9 @@ public class AliasModel extends AbstractTableModel
|
||||
return new AliasList(name);
|
||||
}
|
||||
|
||||
if(mAliasListMap.containsKey(name))
|
||||
{
|
||||
return mAliasListMap.get(name);
|
||||
AliasList mapValue = mAliasListMap.get(name);
|
||||
if (mapValue != null) {
|
||||
return mapValue;
|
||||
}
|
||||
|
||||
AliasList aliasList = new AliasList(name);
|
||||
|
||||
@@ -115,7 +115,7 @@ public class AliasNameEditor extends Editor<Alias>
|
||||
else
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
mGroupCombo.setModel(new DefaultComboBoxModel<String>(
|
||||
groupNames.toArray(new String[groupNames.size()])));
|
||||
groupNames.toArray(new String[0])));
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
@@ -266,15 +266,15 @@ public class MultipleAliasEditor extends Editor<List<Alias>>
|
||||
List<String> listNames = mAliasModel.getListNames();
|
||||
listNames.add(0, "");
|
||||
mListCombo.setModel(new DefaultComboBoxModel<String>(
|
||||
listNames.toArray(new String[listNames.size()])));
|
||||
listNames.toArray(new String[0])));
|
||||
|
||||
List<String> groupNames = mAliasModel.getGroupNames();
|
||||
groupNames.add(0, "");
|
||||
mGroupCombo.setModel(new DefaultComboBoxModel<String>(
|
||||
groupNames.toArray(new String[groupNames.size()])));
|
||||
groupNames.toArray(new String[0])));
|
||||
|
||||
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()));
|
||||
|
||||
@@ -300,12 +300,12 @@ public class MultipleAliasEditor extends Editor<List<Alias>>
|
||||
List<String> listNames = mAliasModel.getListNames();
|
||||
listNames.add(0, "");
|
||||
mListCombo.setModel(new DefaultComboBoxModel<String>(
|
||||
listNames.toArray(new String[listNames.size()])));
|
||||
listNames.toArray(new String[0])));
|
||||
|
||||
List<String> groupNames = mAliasModel.getGroupNames();
|
||||
groupNames.add(0, "");
|
||||
mGroupCombo.setModel(new DefaultComboBoxModel<String>(
|
||||
groupNames.toArray(new String[groupNames.size()])));
|
||||
groupNames.toArray(new String[0])));
|
||||
|
||||
mButtonColor.setForeground(getForeground());
|
||||
mButtonColor.setBackground(getBackground());
|
||||
|
||||
@@ -188,14 +188,7 @@ public class AliasActionEditor extends Editor<Alias>
|
||||
|
||||
List<AliasAction> actions = alias.getAction();
|
||||
|
||||
Collections.sort( actions, new Comparator<AliasAction>()
|
||||
{
|
||||
@Override
|
||||
public int compare( AliasAction o1, AliasAction o2 )
|
||||
{
|
||||
return o1.toString().compareTo( o2.toString() );
|
||||
}
|
||||
} );
|
||||
actions.sort(Comparator.comparing(Object::toString));
|
||||
|
||||
for( AliasAction action: actions )
|
||||
{
|
||||
|
||||
@@ -227,14 +227,7 @@ public class AliasIdentifierEditor extends Editor<Alias>
|
||||
|
||||
List<AliasID> ids = alias.getId();
|
||||
|
||||
Collections.sort(ids, new Comparator<AliasID>()
|
||||
{
|
||||
@Override
|
||||
public int compare(AliasID o1, AliasID o2)
|
||||
{
|
||||
return o1.toString().compareTo(o2.toString());
|
||||
}
|
||||
});
|
||||
ids.sort(Comparator.comparing(Object::toString));
|
||||
|
||||
for(AliasID id : ids)
|
||||
{
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
package io.github.dsheirer.alias.id;
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -95,12 +96,12 @@ public class WildcardID implements Comparable<WildcardID>
|
||||
{
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
||||
weight += (int)(Math.pow(2, characterCount)) * 1000; //Character count weight
|
||||
weight += (int)(FastMath.pow(2, characterCount)) * 1000; //Character count weight
|
||||
|
||||
return weight;
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ public class BroadcastChannelEditor extends DocumentListenerEditor<AliasID>
|
||||
|
||||
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()
|
||||
{
|
||||
@Override
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -38,7 +39,7 @@ import java.util.Map;
|
||||
public class RadioFormatter
|
||||
{
|
||||
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
|
||||
{
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -41,7 +42,7 @@ import java.util.Map;
|
||||
public class TalkgroupFormatter
|
||||
{
|
||||
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
|
||||
{
|
||||
|
||||
@@ -384,10 +384,7 @@ public class AudioSegment implements Listener<IdentifierUpdateNotification>
|
||||
}
|
||||
|
||||
//Add all broadcast channels for the alias ... let the set handle duplication.
|
||||
for(BroadcastChannel broadcastChannel: alias.getBroadcastChannels())
|
||||
{
|
||||
mBroadcastChannels.add(broadcastChannel);
|
||||
}
|
||||
mBroadcastChannels.addAll(alias.getBroadcastChannels());
|
||||
|
||||
//Only assign a playback priority if it is lower priority than the current setting.
|
||||
int playbackPriority = alias.getPlaybackPriority();
|
||||
|
||||
@@ -25,6 +25,7 @@ import io.github.dsheirer.audio.convert.ISilenceGenerator;
|
||||
import io.github.dsheirer.identifier.IdentifierCollection;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.util.ThreadPool;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -360,7 +361,7 @@ public abstract class AudioBroadcaster implements Listener<AudioRecording>
|
||||
//Trim length to whole-frame intervals (144 byte frame)
|
||||
bytesToStream -= (bytesToStream % 144);
|
||||
|
||||
int length = Math.min(bytesToStream, mInputStream.available());
|
||||
int length = FastMath.min(bytesToStream, mInputStream.available());
|
||||
|
||||
byte[] audio = new byte[length];
|
||||
|
||||
|
||||
@@ -174,7 +174,7 @@ public class UserFeedSelectionDialog extends JDialog implements DocumentListener
|
||||
mLog.info("RR User:" + userInfo.getUserName() + " Expiration Date:" + userInfo.getExpirationDate());
|
||||
List<UserFeedBroadcast> feeds = service.getUserFeeds();
|
||||
|
||||
mUserFeedBroadcastList.setListData(feeds.toArray(new UserFeedBroadcast[feeds.size()]));
|
||||
mUserFeedBroadcastList.setListData(feeds.toArray(new UserFeedBroadcast[0]));
|
||||
}
|
||||
catch(RadioReferenceException rre)
|
||||
{
|
||||
|
||||
@@ -50,6 +50,7 @@ import io.github.dsheirer.identifier.IdentifierCollection;
|
||||
import io.github.dsheirer.identifier.Role;
|
||||
import io.github.dsheirer.properties.SystemProperties;
|
||||
import io.github.dsheirer.util.ThreadPool;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.apache.mina.core.RuntimeIoException;
|
||||
import org.apache.mina.core.future.ConnectFuture;
|
||||
import org.apache.mina.core.service.IoHandlerAdapter;
|
||||
@@ -363,7 +364,7 @@ public class ShoutcastV2AudioBroadcaster extends AudioBroadcaster implements IBr
|
||||
|
||||
int pointer = 0;
|
||||
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)
|
||||
{
|
||||
@@ -375,7 +376,7 @@ public class ShoutcastV2AudioBroadcaster extends AudioBroadcaster implements IBr
|
||||
|
||||
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];
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import io.github.dsheirer.audio.AudioUtils;
|
||||
import net.sourceforge.lame.lowlevel.LameEncoder;
|
||||
import net.sourceforge.lame.mp3.Lame;
|
||||
import net.sourceforge.lame.mp3.MPEGMode;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -59,7 +60,7 @@ public class MP3AudioConverter implements IAudioConverter
|
||||
|
||||
byte[] pcmBytes = AudioUtils.convertTo16BitSamples(audioPackets);
|
||||
|
||||
int pcmBufferSize = Math.min(mMP3Buffer.length, pcmBytes.length);
|
||||
int pcmBufferSize = FastMath.min(mMP3Buffer.length, pcmBytes.length);
|
||||
|
||||
int mp3BufferSize = 0;
|
||||
|
||||
@@ -70,7 +71,7 @@ public class MP3AudioConverter implements IAudioConverter
|
||||
while (0 < (mp3BufferSize = mEncoder.encodeBuffer(pcmBytes, pcmBytesPosition, pcmBufferSize, mMP3Buffer)))
|
||||
{
|
||||
pcmBytesPosition += pcmBufferSize;
|
||||
pcmBufferSize = Math.min(mMP3Buffer.length, pcmBytes.length - pcmBytesPosition);
|
||||
pcmBufferSize = FastMath.min(mMP3Buffer.length, pcmBytes.length - pcmBytesPosition);
|
||||
mMP3Stream.write(mMP3Buffer, 0, mp3BufferSize);
|
||||
}
|
||||
|
||||
@@ -89,7 +90,7 @@ public class MP3AudioConverter implements IAudioConverter
|
||||
|
||||
byte[] pcmBytes = AudioUtils.convert(audioBuffers);
|
||||
|
||||
int pcmBufferSize = Math.min(mMP3Buffer.length, pcmBytes.length);
|
||||
int pcmBufferSize = FastMath.min(mMP3Buffer.length, pcmBytes.length);
|
||||
|
||||
int mp3BufferSize = 0;
|
||||
|
||||
@@ -100,7 +101,7 @@ public class MP3AudioConverter implements IAudioConverter
|
||||
while (0 < (mp3BufferSize = mEncoder.encodeBuffer(pcmBytes, pcmBytesPosition, pcmBufferSize, mMP3Buffer)))
|
||||
{
|
||||
pcmBytesPosition += pcmBufferSize;
|
||||
pcmBufferSize = Math.min(mMP3Buffer.length, pcmBytes.length - pcmBytesPosition);
|
||||
pcmBufferSize = FastMath.min(mMP3Buffer.length, pcmBytes.length - pcmBytesPosition);
|
||||
mMP3Stream.write(mMP3Buffer, 0, mp3BufferSize);
|
||||
}
|
||||
|
||||
|
||||
@@ -195,7 +195,7 @@ public class AudioPlaybackManager implements Listener<AudioSegment>, IAudioContr
|
||||
//Sort audio segments by playback priority and assign to empty audio outputs
|
||||
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
|
||||
for(AudioOutput audioOutput: mAudioOutputs)
|
||||
@@ -347,14 +347,7 @@ public class AudioPlaybackManager implements Listener<AudioSegment>, IAudioContr
|
||||
{
|
||||
List<AudioOutput> outputs = new ArrayList<>(mAudioOutputs);
|
||||
|
||||
Collections.sort(outputs, new Comparator<AudioOutput>()
|
||||
{
|
||||
@Override
|
||||
public int compare(AudioOutput first, AudioOutput second)
|
||||
{
|
||||
return first.getChannelName().compareTo(second.getChannelName());
|
||||
}
|
||||
});
|
||||
outputs.sort(Comparator.comparing(AudioOutput::getChannelName));
|
||||
|
||||
return outputs;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ package io.github.dsheirer.bits;
|
||||
|
||||
import io.github.dsheirer.edac.CRC;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
|
||||
import java.util.BitSet;
|
||||
|
||||
@@ -593,7 +594,7 @@ public class BinaryMessage extends BitSet
|
||||
*/
|
||||
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++)
|
||||
{
|
||||
@@ -795,7 +796,7 @@ public class BinaryMessage extends BitSet
|
||||
*/
|
||||
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 "
|
||||
+ "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)
|
||||
{
|
||||
if(Math.abs(end - start) > 64)
|
||||
if(FastMath.abs(end - start) > 64)
|
||||
{
|
||||
throw new IllegalArgumentException("Overflow - must be 64 bits "
|
||||
+ "or less to fit into a primitive long value");
|
||||
|
||||
@@ -171,9 +171,8 @@ public class MessageFramer implements IBinarySymbolProcessor, Listener<Boolean>,
|
||||
this(messageLength);
|
||||
|
||||
/* Pre-load the message with the sync pattern */
|
||||
for(int x = 0; x < initialFill.length; x++)
|
||||
{
|
||||
receive(initialFill[x]);
|
||||
for (boolean b : initialFill) {
|
||||
receive(b);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ package io.github.dsheirer.bits;
|
||||
|
||||
import io.github.dsheirer.dsp.symbol.ISyncDetectListener;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -57,7 +58,7 @@ public class MultiSyncPatternMatcher
|
||||
Validate.isTrue(syncSize < 64);
|
||||
|
||||
//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()
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
package io.github.dsheirer.bits;
|
||||
|
||||
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
|
||||
/**
|
||||
* Sync pattern matcher.
|
||||
*
|
||||
@@ -37,7 +39,7 @@ public class SyncPatternMatcher
|
||||
public SyncPatternMatcher(boolean[] syncPattern)
|
||||
{
|
||||
//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
|
||||
for(int x = 0; x < syncPattern.length; x++)
|
||||
|
||||
@@ -76,10 +76,8 @@ public class BooleanAveragingBuffer
|
||||
|
||||
mTrueCount = 0;
|
||||
|
||||
for(int x = 0; x < mBuffer.length; x++)
|
||||
{
|
||||
if(mBuffer[x])
|
||||
{
|
||||
for (boolean b : mBuffer) {
|
||||
if (b) {
|
||||
mTrueCount++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ import java.awt.Component;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -68,8 +69,8 @@ public class ChannelMetadataPanel extends JPanel implements ListSelectionListene
|
||||
private UserPreferences mUserPreferences;
|
||||
private JTable mTable;
|
||||
private Broadcaster<ProcessingChain> mSelectedProcessingChainBroadcaster = new Broadcaster<>();
|
||||
private Map<State,Color> mBackgroundColors = new HashMap<>();
|
||||
private Map<State,Color> mForegroundColors = new HashMap<>();
|
||||
private Map<State,Color> mBackgroundColors = new EnumMap<>(State.class);
|
||||
private Map<State,Color> mForegroundColors = new EnumMap<>(State.class);
|
||||
private JTableColumnWidthMonitor mTableColumnMonitor;
|
||||
|
||||
/**
|
||||
|
||||
@@ -128,11 +128,11 @@ public class DecoderStateEvent
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append("Decoder State Event - source[" + mSource.getClass() +
|
||||
"] event[" + mEvent.toString() +
|
||||
"] state[" + mState.toString() +
|
||||
"] timeslot[" + mTimeslot +
|
||||
"] frequency [" + mFrequency + "]");
|
||||
sb.append("Decoder State Event - source[").append(mSource.getClass())
|
||||
.append("] event[").append(mEvent)
|
||||
.append("] state[").append(mState)
|
||||
.append("] timeslot[").append(mTimeslot)
|
||||
.append("] frequency [").append(mFrequency).append("]");
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@@ -251,26 +251,16 @@ public class ChannelModel extends AbstractTableModel implements Listener<Channel
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(autoStartChannels, new Comparator<Channel>()
|
||||
{
|
||||
@Override
|
||||
public int compare(Channel channel1, Channel channel2)
|
||||
{
|
||||
if(channel1.hasAutoStartOrder() && channel2.hasAutoStartOrder())
|
||||
{
|
||||
return Integer.compare(channel1.getAutoStartOrder(), channel2.getAutoStartOrder());
|
||||
}
|
||||
else if(channel1.hasAutoStartOrder())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if(channel2.hasAutoStartOrder())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
autoStartChannels.sort((channel1, channel2) -> {
|
||||
if (channel1.hasAutoStartOrder() && channel2.hasAutoStartOrder()) {
|
||||
return Integer.compare(channel1.getAutoStartOrder(), channel2.getAutoStartOrder());
|
||||
} else if (channel1.hasAutoStartOrder()) {
|
||||
return -1;
|
||||
} else if (channel2.hasAutoStartOrder()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
||||
return autoStartChannels;
|
||||
|
||||
@@ -110,7 +110,7 @@ public class NameConfigurationEditor extends Editor<Channel> implements Document
|
||||
else
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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();
|
||||
Collections.sort(lists);
|
||||
mAliasListCombo.setModel(new DefaultComboBoxModel<String>(
|
||||
lists.toArray(new String[lists.size()])));
|
||||
lists.toArray(new String[0])));
|
||||
|
||||
if(channel.getAliasListName() != null)
|
||||
{
|
||||
|
||||
@@ -60,13 +60,13 @@ public class ChannelRange
|
||||
if(isValid())
|
||||
{
|
||||
sb.append("First: ");
|
||||
sb.append(mFirst + "=");
|
||||
sb.append(mFirst).append("=");
|
||||
|
||||
long frequency = getFrequency(mFirst);
|
||||
|
||||
sb.append(FREQUENCY_FORMATTER.format((double)frequency / 1E6D));
|
||||
sb.append(" Last: ");
|
||||
sb.append(mLast + "=");
|
||||
sb.append(mLast).append("=");
|
||||
|
||||
frequency = getFrequency(mLast);
|
||||
sb.append(FREQUENCY_FORMATTER.format((double)frequency / 1E6D));
|
||||
|
||||
@@ -26,6 +26,7 @@ import io.github.dsheirer.dsp.mixer.IOscillator;
|
||||
import io.github.dsheirer.dsp.mixer.Oscillator;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
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
|
||||
//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
|
||||
mCorrelationValues[x] = mAveragingBuffer.get(Math.abs(mCorrelationAccumulator));
|
||||
mCorrelationValues[x] = mAveragingBuffer.get(FastMath.abs(mCorrelationAccumulator));
|
||||
}
|
||||
|
||||
return mCorrelationValues;
|
||||
|
||||
@@ -19,6 +19,7 @@ import io.github.dsheirer.buffer.FloatAveragingBuffer;
|
||||
import io.github.dsheirer.dsp.mixer.IOscillator;
|
||||
import io.github.dsheirer.dsp.mixer.Oscillator;
|
||||
import io.github.dsheirer.sample.complex.Complex;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -110,8 +111,8 @@ public class AFSKTest
|
||||
correlation1800 += reference1800[x] * samples[x + offset];
|
||||
}
|
||||
|
||||
correlation1200 = avg1200.get(Math.abs(correlation1200));
|
||||
correlation1800 = avg1800.get(Math.abs(correlation1800));
|
||||
correlation1200 = avg1200.get(FastMath.abs(correlation1200));
|
||||
correlation1800 = avg1800.get(FastMath.abs(correlation1800));
|
||||
|
||||
mLog.debug(offset + " 1200:" + format(correlation1200) + " 1800:" + format(correlation1800) +
|
||||
" Decision: " + (correlation1200 > correlation1800 ? "0" : "1"));
|
||||
|
||||
@@ -18,6 +18,7 @@ package io.github.dsheirer.dsp.am;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBufferQueue;
|
||||
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
|
||||
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.
|
||||
@@ -55,7 +56,7 @@ public class AMDemodulator
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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.remez.RemezFIRFilterDesigner;
|
||||
import io.github.dsheirer.dsp.filter.fir.remez.RemezFIRFilterDesignerWithLagrange;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.jtransforms.fft.FloatFFT_1D;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -109,9 +110,8 @@ public class FilterFactory
|
||||
{
|
||||
float accumulator = 0;
|
||||
|
||||
for(int x = 0; x < coefficients.length; x++)
|
||||
{
|
||||
accumulator += Math.abs(coefficients[x]);
|
||||
for (float coefficient : coefficients) {
|
||||
accumulator += FastMath.abs(coefficient);
|
||||
}
|
||||
|
||||
for(int x = 0; x < coefficients.length; x++)
|
||||
@@ -133,9 +133,8 @@ public class FilterFactory
|
||||
{
|
||||
float accumulator = 0;
|
||||
|
||||
for(int x = 0; x < coefficients.length; x++)
|
||||
{
|
||||
accumulator += Math.abs(coefficients[x]);
|
||||
for (float coefficient : coefficients) {
|
||||
accumulator += FastMath.abs(coefficient);
|
||||
}
|
||||
|
||||
accumulator /= objective;
|
||||
@@ -171,7 +170,7 @@ public class FilterFactory
|
||||
|
||||
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++)
|
||||
{
|
||||
@@ -181,7 +180,7 @@ public class FilterFactory
|
||||
}
|
||||
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;
|
||||
|
||||
@@ -316,7 +315,7 @@ public class FilterFactory
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for(int x = 0; x < array.length; x++)
|
||||
{
|
||||
sb.append(x + ": " + array[x]);
|
||||
sb.append(x).append(": ").append(array[x]);
|
||||
|
||||
if(breaks)
|
||||
{
|
||||
@@ -354,7 +353,7 @@ public class FilterFactory
|
||||
{
|
||||
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)
|
||||
{
|
||||
int testDelta = Math.abs(desiredFactor - factor);
|
||||
int testDelta = FastMath.abs(desiredFactor - factor);
|
||||
|
||||
if(testDelta < bestDelta)
|
||||
{
|
||||
@@ -484,7 +483,7 @@ public class FilterFactory
|
||||
{
|
||||
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));
|
||||
|
||||
@@ -559,18 +558,18 @@ public class FilterFactory
|
||||
{
|
||||
float[] cicArray = new float[length * 2];
|
||||
|
||||
int binCount = (int)((Math.round(
|
||||
int binCount = (int)((FastMath.round(
|
||||
(double)frequency / (double)sampleRate * 2.0d * (double)length)));
|
||||
|
||||
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));
|
||||
|
||||
for(int x = 1; x <= binCount; x++)
|
||||
{
|
||||
/* 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[length - x] = compensated;
|
||||
@@ -612,25 +611,25 @@ public class FilterFactory
|
||||
{
|
||||
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 x3 = x2 * x2 - 1.0f;
|
||||
|
||||
float numerator, denominator;
|
||||
|
||||
if(Math.abs(x3) >= 0.000001)
|
||||
if(FastMath.abs(x3) >= 0.000001)
|
||||
{
|
||||
if(x != taps / 2)
|
||||
{
|
||||
numerator = (float)Math.cos((1.0 + alpha) * x1) +
|
||||
(float)Math.sin((1.0f - alpha) * x1) / (4.0f * alpha * index / (float)samplesPerSymbol);
|
||||
numerator = (float)FastMath.cos((1.0 + alpha) * x1) +
|
||||
(float)FastMath.sin((1.0f - alpha) * x1) / (4.0f * alpha * index / (float)samplesPerSymbol);
|
||||
}
|
||||
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
|
||||
{
|
||||
@@ -643,11 +642,11 @@ public class FilterFactory
|
||||
x3 = (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 *
|
||||
(double)samplesPerSymbol) / (4.0 * alpha * index) + Math.sin(x3) * (double)samplesPerSymbol *
|
||||
numerator = (float)(FastMath.sin(x2) * (1.0f + alpha) * FastMath.PI - FastMath.cos(x3) * ((1.0 - alpha) * FastMath.PI *
|
||||
(double)samplesPerSymbol) / (4.0 * alpha * index) + FastMath.sin(x3) * (double)samplesPerSymbol *
|
||||
(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;
|
||||
@@ -699,8 +698,8 @@ public class FilterFactory
|
||||
|
||||
for(int x = 0; x < filter.length; x++)
|
||||
{
|
||||
real += filter[x] * Math.cos(Math.PI * frequency * (double)x);
|
||||
imag += filter[x] * Math.sin(Math.PI * frequency * (double)x);
|
||||
real += filter[x] * FastMath.cos(FastMath.PI * frequency * (double)x);
|
||||
imag += filter[x] * FastMath.sin(FastMath.PI * frequency * (double)x);
|
||||
}
|
||||
|
||||
return decibel(real, imag);
|
||||
@@ -715,7 +714,7 @@ public class FilterFactory
|
||||
*/
|
||||
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 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);
|
||||
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);
|
||||
|
||||
return taps;
|
||||
@@ -946,14 +945,14 @@ public class FilterFactory
|
||||
double[] window = Window.getWindow(windowType, length);
|
||||
|
||||
double scalor = 2.0 * cutoff;
|
||||
double piScalor = Math.PI * scalor;
|
||||
double piScalor = FastMath.PI * scalor;
|
||||
|
||||
coefficients[half] = (float)(1.0 * scalor * window[half]);
|
||||
|
||||
for(int x = 1; x <= half; x++)
|
||||
{
|
||||
double a = piScalor * x;
|
||||
double coefficient = scalor * Math.sin(a) / a;
|
||||
double coefficient = scalor * FastMath.sin(a) / a;
|
||||
|
||||
coefficient *= window[half + x];
|
||||
coefficients[half + x] = (float)coefficient;
|
||||
@@ -985,14 +984,14 @@ public class FilterFactory
|
||||
double[] window = Window.getKaiser(length, attenuation);
|
||||
|
||||
double scalor = 2.0 * cutoff;
|
||||
double piScalor = Math.PI * scalor;
|
||||
double piScalor = FastMath.PI * scalor;
|
||||
|
||||
coefficients[half] = (float)(1.0 * scalor * window[half]);
|
||||
|
||||
for(int x = 1; x <= half; x++)
|
||||
{
|
||||
double a = piScalor * x;
|
||||
double coefficient = scalor * Math.sin(a) / a;
|
||||
double coefficient = scalor * FastMath.sin(a) / a;
|
||||
|
||||
coefficient *= window[half + x];
|
||||
coefficients[half + x] = (float)coefficient;
|
||||
@@ -1011,7 +1010,7 @@ public class FilterFactory
|
||||
*/
|
||||
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)
|
||||
|
||||
@@ -126,7 +126,7 @@ public class FloatFIRFilter implements RealSampleListener
|
||||
{
|
||||
for( int y = 0; y < mCoefficients.length; y++ )
|
||||
{
|
||||
sb.append( mIndexMap[ x ][ y ] + " " );
|
||||
sb.append(mIndexMap[x][y]).append(" ");
|
||||
}
|
||||
sb.append( "\n" );
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
package io.github.dsheirer.dsp.filter;
|
||||
|
||||
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()
|
||||
{
|
||||
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_prev = 0.0D;
|
||||
double s_prev2 = 0.0D;
|
||||
|
||||
for ( int x = 0; x < samples.length; x++ )
|
||||
{
|
||||
s = samples[x] + ( mCoefficient * s_prev ) - s_prev2;
|
||||
s_prev2 = s_prev;
|
||||
s_prev = s;
|
||||
}
|
||||
|
||||
for (float sample : samples) {
|
||||
s = sample + (mCoefficient * s_prev) - s_prev2;
|
||||
s_prev2 = s_prev;
|
||||
s_prev = s;
|
||||
}
|
||||
|
||||
//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);
|
||||
int binZero = getBinZeroPower( samples );
|
||||
|
||||
int power = (int) (20 * Math.log10( magnitude / binZero ) );
|
||||
int power = (int) (20 * FastMath.log10( magnitude / binZero ) );
|
||||
|
||||
return power;
|
||||
}
|
||||
@@ -125,10 +125,9 @@ public class GoertzelFilter
|
||||
private int getBinZeroPower( float[] samples )
|
||||
{
|
||||
int retVal = 0;
|
||||
|
||||
for( int x = 0; x < samples.length; x++ )
|
||||
{
|
||||
retVal += samples[ x ];
|
||||
|
||||
for (float sample : samples) {
|
||||
retVal += sample;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
******************************************************************************/
|
||||
package io.github.dsheirer.dsp.filter;
|
||||
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2011 by Paul Lutus *
|
||||
* lutusp@arachnoid.com *
|
||||
@@ -93,12 +95,12 @@ final public class IIRBiQuadraticFilter {
|
||||
public void reconfigure(double cf) {
|
||||
center_freq = cf;
|
||||
// only used for peaking and shelving filters
|
||||
gain_abs = Math.pow(10, gainDB / 40);
|
||||
double omega = 2 * Math.PI * cf / sample_rate;
|
||||
double sn = Math.sin(omega);
|
||||
double cs = Math.cos(omega);
|
||||
gain_abs = FastMath.pow(10, gainDB / 40);
|
||||
double omega = 2 * FastMath.PI * cf / sample_rate;
|
||||
double sn = FastMath.sin(omega);
|
||||
double cs = FastMath.cos(omega);
|
||||
double alpha = sn / (2 * Q);
|
||||
double beta = Math.sqrt(gain_abs + gain_abs);
|
||||
double beta = FastMath.sqrt(gain_abs + gain_abs);
|
||||
switch (type) {
|
||||
case BANDPASS:
|
||||
b0 = alpha;
|
||||
@@ -167,8 +169,8 @@ final public class IIRBiQuadraticFilter {
|
||||
|
||||
// provide a static amplitude result for testing
|
||||
public double result(double f) {
|
||||
double phi = Math.pow((Math.sin(2.0 * Math.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);
|
||||
double phi = FastMath.pow((FastMath.sin(2.0 * FastMath.PI * f / (2.0 * sample_rate))), 2.0);
|
||||
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
|
||||
@@ -176,7 +178,7 @@ final public class IIRBiQuadraticFilter {
|
||||
{
|
||||
double r;
|
||||
try {
|
||||
r = 10 * Math.log10(result(f));
|
||||
r = 10 * FastMath.log10(result(f));
|
||||
} catch (Exception e) {
|
||||
r = -100;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
*/
|
||||
package io.github.dsheirer.dsp.filter;
|
||||
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -48,10 +49,10 @@ public class Window
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(Window.class);
|
||||
|
||||
private static final double TWO_PI = Math.PI * 2.0d;
|
||||
private static final double FOUR_PI = Math.PI * 4.0d;
|
||||
private static final double SIX_PI = Math.PI * 6.0d;
|
||||
private static final double EIGHT_PI = Math.PI * 8.0d;
|
||||
private static final double TWO_PI = FastMath.PI * 2.0d;
|
||||
private static final double FOUR_PI = FastMath.PI * 4.0d;
|
||||
private static final double SIX_PI = FastMath.PI * 6.0d;
|
||||
private static final double EIGHT_PI = FastMath.PI * 8.0d;
|
||||
|
||||
/**
|
||||
* 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++)
|
||||
{
|
||||
coefficients[x + half] = Math.cos(
|
||||
((double)x * Math.PI) / ((double)length + 1.0d));
|
||||
coefficients[x + half] = FastMath.cos(
|
||||
((double)x * FastMath.PI) / ((double)length + 1.0d));
|
||||
}
|
||||
}
|
||||
else //Odd length
|
||||
@@ -131,8 +132,8 @@ public class Window
|
||||
|
||||
for(int x = -half; x < half + 1; x++)
|
||||
{
|
||||
coefficients[x + half] = Math.cos(
|
||||
((double)x * Math.PI) / ((double)length + 1.0d));
|
||||
coefficients[x + half] = FastMath.cos(
|
||||
((double)x * FastMath.PI) / ((double)length + 1.0d));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,8 +159,8 @@ public class Window
|
||||
for(int x = 0; x < length; x++)
|
||||
{
|
||||
coefficients[x] = a0 -
|
||||
(a1 * Math.cos((TWO_PI * (double)x) / denominator)) +
|
||||
(a2 * Math.cos((FOUR_PI * (double)x) / denominator));
|
||||
(a1 * FastMath.cos((TWO_PI * (double)x) / denominator)) +
|
||||
(a2 * FastMath.cos((FOUR_PI * (double)x) / denominator));
|
||||
}
|
||||
|
||||
return coefficients;
|
||||
@@ -184,9 +185,9 @@ public class Window
|
||||
for(int x = 0; x < length; x++)
|
||||
{
|
||||
coefficients[x] = a0 -
|
||||
(a1 * Math.cos(TWO_PI * (double)x / denominator)) +
|
||||
(a2 * Math.cos(FOUR_PI * (double)x / denominator)) -
|
||||
(a3 * Math.cos(SIX_PI * (double)x / denominator));
|
||||
(a1 * FastMath.cos(TWO_PI * (double)x / denominator)) +
|
||||
(a2 * FastMath.cos(FOUR_PI * (double)x / denominator)) -
|
||||
(a3 * FastMath.cos(SIX_PI * (double)x / denominator));
|
||||
}
|
||||
|
||||
return coefficients;
|
||||
@@ -211,9 +212,9 @@ public class Window
|
||||
for(int x = 0; x < length; x++)
|
||||
{
|
||||
coefficients[x] = a0 -
|
||||
(a1 * Math.cos(TWO_PI * (double)x / denominator)) +
|
||||
(a2 * Math.cos(FOUR_PI * (double)x / denominator)) -
|
||||
(a3 * Math.cos(SIX_PI * (double)x / denominator));
|
||||
(a1 * FastMath.cos(TWO_PI * (double)x / denominator)) +
|
||||
(a2 * FastMath.cos(FOUR_PI * (double)x / denominator)) -
|
||||
(a3 * FastMath.cos(SIX_PI * (double)x / denominator));
|
||||
}
|
||||
|
||||
return coefficients;
|
||||
@@ -238,9 +239,9 @@ public class Window
|
||||
for(int x = 0; x < length; x++)
|
||||
{
|
||||
coefficients[x] = a0 -
|
||||
(a1 * Math.cos(TWO_PI * (double)x / denominator)) +
|
||||
(a2 * Math.cos(FOUR_PI * (double)x / denominator)) -
|
||||
(a3 * Math.cos(SIX_PI * (double)x / denominator));
|
||||
(a1 * FastMath.cos(TWO_PI * (double)x / denominator)) +
|
||||
(a2 * FastMath.cos(FOUR_PI * (double)x / denominator)) -
|
||||
(a3 * FastMath.cos(SIX_PI * (double)x / denominator));
|
||||
}
|
||||
|
||||
return coefficients;
|
||||
@@ -272,12 +273,12 @@ public class Window
|
||||
double w = TWO_PI * (double)x / denominator;
|
||||
|
||||
coefficients[x] = a0 -
|
||||
(a1 * Math.cos(w)) +
|
||||
(a2 * Math.cos(2.0 * w)) -
|
||||
(a3 * Math.cos(3.0 * w)) +
|
||||
(a4 * Math.cos(4.0 * w)) -
|
||||
(a5 * Math.cos(5.0 * w)) +
|
||||
(a6 * Math.cos(6.0 * w));
|
||||
(a1 * FastMath.cos(w)) +
|
||||
(a2 * FastMath.cos(2.0 * w)) -
|
||||
(a3 * FastMath.cos(3.0 * w)) +
|
||||
(a4 * FastMath.cos(4.0 * w)) -
|
||||
(a5 * FastMath.cos(5.0 * w)) +
|
||||
(a6 * FastMath.cos(6.0 * w));
|
||||
}
|
||||
|
||||
return coefficients;
|
||||
@@ -299,7 +300,7 @@ public class Window
|
||||
|
||||
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;
|
||||
@@ -321,7 +322,7 @@ public class Window
|
||||
|
||||
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;
|
||||
@@ -348,10 +349,10 @@ public class Window
|
||||
for(int x = 0; x < length; x++)
|
||||
{
|
||||
coefficients[x] = a0 -
|
||||
(a1 * Math.cos(TWO_PI * (double)x / denominator)) +
|
||||
(a2 * Math.cos(FOUR_PI * (double)x / denominator)) -
|
||||
(a3 * Math.cos(SIX_PI * (double)x / denominator)) +
|
||||
(a4 * Math.cos(EIGHT_PI * (double)x / denominator));
|
||||
(a1 * FastMath.cos(TWO_PI * (double)x / denominator)) +
|
||||
(a2 * FastMath.cos(FOUR_PI * (double)x / denominator)) -
|
||||
(a3 * FastMath.cos(SIX_PI * (double)x / denominator)) +
|
||||
(a4 * FastMath.cos(EIGHT_PI * (double)x / denominator));
|
||||
}
|
||||
|
||||
return coefficients;
|
||||
@@ -371,7 +372,7 @@ public class Window
|
||||
}
|
||||
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
|
||||
{
|
||||
@@ -398,7 +399,7 @@ public class Window
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package io.github.dsheirer.dsp.filter.channelizer;
|
||||
|
||||
import io.github.dsheirer.source.tuner.channel.TunerChannel;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -293,7 +294,7 @@ public class ChannelCalculator
|
||||
{
|
||||
double offset = frequency - getCenterFrequency();
|
||||
|
||||
if(Math.abs(offset) < getHalfChannelBandwidth())
|
||||
if(FastMath.abs(offset) < getHalfChannelBandwidth())
|
||||
{
|
||||
return 0; //Center index
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import io.github.dsheirer.sample.IOverflowListener;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableChannelResultsBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.jtransforms.fft.FloatFFT_1D;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -71,8 +72,6 @@ public class ComplexPolyphaseChannelizerM2 extends AbstractComplexPolyphaseChann
|
||||
private FloatFFT_1D mFFT;
|
||||
private float[] mInlineSamples;
|
||||
private float[] mInlineFilter;
|
||||
private float[] mInlineInterimOutput;
|
||||
private float[] mFilterAccumulator;
|
||||
private boolean mTopBlockIndicator = true;
|
||||
private int[] mTopBlockMap;
|
||||
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)");
|
||||
}
|
||||
|
||||
mTapsPerChannel = (int)Math.ceil((double)taps.length / (double)channelCount);
|
||||
mTapsPerChannel = (int) FastMath.ceil((double)taps.length / (double)channelCount);
|
||||
|
||||
init(taps);
|
||||
}
|
||||
@@ -204,9 +203,10 @@ public class ComplexPolyphaseChannelizerM2 extends AbstractComplexPolyphaseChann
|
||||
{
|
||||
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);
|
||||
@@ -336,13 +336,16 @@ public class ComplexPolyphaseChannelizerM2 extends AbstractComplexPolyphaseChann
|
||||
*/
|
||||
private void process(ReusableChannelResultsBuffer channelResultsBuffer)
|
||||
{
|
||||
int bufferLength = getSubChannelCount() * mTapsPerChannel;
|
||||
float[] inlineInterimOutput = new float[bufferLength];
|
||||
|
||||
//Multiply each of the samples by the corresponding filter tap
|
||||
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;
|
||||
|
||||
@@ -353,7 +356,7 @@ public class ComplexPolyphaseChannelizerM2 extends AbstractComplexPolyphaseChann
|
||||
|
||||
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++)
|
||||
{
|
||||
processed[x] = mFilterAccumulator[mTopBlockMap[x]];
|
||||
processed[x] = filterAccumulator[mTopBlockMap[x]];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
mInlineFilter = getAlignedFilter(coefficients, channelCount, mTapsPerChannel);
|
||||
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
|
||||
//channel results array contained in each results buffer and then dispatch the buffer
|
||||
//so that it can be distributed to each channel listener.
|
||||
setListener(new Listener<List<ReusableChannelResultsBuffer>>()
|
||||
{
|
||||
@Override
|
||||
public void receive(List<ReusableChannelResultsBuffer> buffers)
|
||||
setListener(buffers -> {
|
||||
for(ReusableChannelResultsBuffer buffer: 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);
|
||||
}
|
||||
|
||||
dispatch(buffer);
|
||||
//Rotate each of the channels to the correct phase using the IFFT
|
||||
mFFT.complexInverse(channelResults, true);
|
||||
}
|
||||
|
||||
dispatch(buffer);
|
||||
}
|
||||
});
|
||||
|
||||
setOverflowListener(new IOverflowListener()
|
||||
{
|
||||
@Override
|
||||
public void sourceOverflow(boolean overflow)
|
||||
{
|
||||
mLog.debug("IFFTProcessor overflow changed - overflow:" + overflow);
|
||||
}
|
||||
});
|
||||
setOverflowListener(overflow -> mLog.debug("IFFTProcessor overflow changed - overflow:" + overflow));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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.TunerChannel;
|
||||
import io.github.dsheirer.source.tuner.channel.TunerChannelSource;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -339,7 +340,7 @@ public class PolyphaseChannelManager implements ISourceEventProcessor
|
||||
double tunerSampleRate = mChannelCalculator.getSampleRate();
|
||||
|
||||
//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)
|
||||
{
|
||||
|
||||
@@ -286,9 +286,10 @@ public class PolyphaseChannelSource extends TunerChannelSource
|
||||
private float[] getLowPassFilter(double sampleRate, double passFrequency, double stopFrequency) throws FilterDesignException
|
||||
{
|
||||
//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()
|
||||
|
||||
@@ -17,6 +17,7 @@ package io.github.dsheirer.dsp.filter.channelizer;
|
||||
|
||||
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableComplexBufferQueue;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.jtransforms.fft.FloatFFT_1D;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -49,7 +50,6 @@ public class TwoChannelSynthesizerM2
|
||||
private float[] mSerpentineDataBuffer;
|
||||
private float[] mIQInterleavedFilter;
|
||||
private float[] mFilterVectorProduct;
|
||||
private float[] mIFFTBuffer = new float[4];
|
||||
private float mIAccumulator;
|
||||
private float mQAccumulator;
|
||||
private FloatFFT_1D mFFT = new FloatFFT_1D(2);
|
||||
@@ -72,7 +72,7 @@ public class TwoChannelSynthesizerM2
|
||||
*/
|
||||
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);
|
||||
mSerpentineDataBuffer = new float[mIQInterleavedFilter.length];
|
||||
@@ -100,17 +100,18 @@ public class TwoChannelSynthesizerM2
|
||||
ReusableComplexBuffer synthesizedComplexBuffer = mReusableComplexBufferQueue.getBuffer(channel1.length);
|
||||
|
||||
float[] output = synthesizedComplexBuffer.getSamples();
|
||||
float[] IFFTBuffer = new float[4];
|
||||
|
||||
for(int x = 0; x < channel1.length; x += 2)
|
||||
{
|
||||
//Load samples from each channel into buffer for IFFT
|
||||
mIFFTBuffer[0] = channel1[x]; //i
|
||||
mIFFTBuffer[1] = channel1[x + 1]; //q
|
||||
mIFFTBuffer[2] = channel2[x]; //i
|
||||
mIFFTBuffer[3] = channel2[x + 1]; //q
|
||||
IFFTBuffer[0] = channel1[x]; //i
|
||||
IFFTBuffer[1] = channel1[x + 1]; //q
|
||||
IFFTBuffer[2] = channel2[x]; //i
|
||||
IFFTBuffer[3] = channel2[x + 1]; //q
|
||||
|
||||
//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
|
||||
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
|
||||
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
|
||||
else
|
||||
{
|
||||
System.arraycopy(mIFFTBuffer, 0, mSerpentineDataBuffer, 2, 2);
|
||||
System.arraycopy(mIFFTBuffer, 2, mSerpentineDataBuffer, 0, 2);
|
||||
System.arraycopy(IFFTBuffer, 0, mSerpentineDataBuffer, 2, 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
|
||||
|
||||
@@ -29,6 +29,7 @@ import io.github.dsheirer.sample.buffer.ReusableComplexBufferAssembler;
|
||||
import io.github.dsheirer.sample.complex.ComplexSampleListener;
|
||||
import io.github.dsheirer.sample.decimator.ComplexDecimator;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.commons.math3.primes.Primes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -49,38 +50,6 @@ public class ComplexPrimeCICDecimate implements Listener<ReusableComplexBuffer>
|
||||
{
|
||||
// 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,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)
|
||||
throws FilterDesignException
|
||||
{
|
||||
Validate.isTrue(decimation <= PRIMES[PRIMES.length - 1]);
|
||||
|
||||
List<Integer> stageSizes = getPrimeFactors(decimation);
|
||||
|
||||
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)
|
||||
{
|
||||
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] +
|
||||
"] are not supported. Update the PRIMES array to add support for higher decimation rates");
|
||||
return primeFactors;
|
||||
}
|
||||
|
||||
if(sPrimeFactors.containsKey(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++;
|
||||
}
|
||||
}
|
||||
primeFactors = Primes.primeFactors(decimation);
|
||||
|
||||
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
|
||||
{
|
||||
//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()
|
||||
|
||||
@@ -28,6 +28,7 @@ import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import io.github.dsheirer.sample.decimator.RealDecimator;
|
||||
import io.github.dsheirer.sample.real.RealSampleListener;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.commons.math3.primes.Primes;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -38,14 +39,6 @@ public class RealPrimeCICDecimate
|
||||
{
|
||||
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 DecimatingStage mFirstDecimatingStage;
|
||||
private Output mOutput;
|
||||
@@ -79,7 +72,7 @@ public class RealPrimeCICDecimate
|
||||
|
||||
mOutputBufferSize = outputBufferSize;
|
||||
|
||||
List<Integer> stageSizes = getPrimeFactors(decimation);
|
||||
List<Integer> stageSizes = Primes.primeFactors(decimation);
|
||||
|
||||
for(int x = 0; x < stageSizes.size(); x++)
|
||||
{
|
||||
@@ -137,39 +130,6 @@ public class RealPrimeCICDecimate
|
||||
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.
|
||||
*/
|
||||
|
||||
@@ -43,9 +43,8 @@ public class BufferDCFilter
|
||||
{
|
||||
mAccumulator = 0.0;
|
||||
|
||||
for(int x = 0; x < samples.length; x++)
|
||||
{
|
||||
mAccumulator += samples[x];
|
||||
for (float sample : samples) {
|
||||
mAccumulator += sample;
|
||||
}
|
||||
|
||||
return (float)(mAccumulator / (double)samples.length);
|
||||
|
||||
@@ -23,6 +23,7 @@ import javafx.scene.chart.XYChart.Series;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.jtransforms.fft.FloatFFT_1D;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -140,7 +141,7 @@ public class FilterView extends BorderPane
|
||||
mImpulseXAxis.setUpperBound(taps.length - 1);
|
||||
mImpulseXAxis.setTickUnit(1.0);
|
||||
|
||||
double padding = Math.abs(largest - smallest) * .1;
|
||||
double padding = FastMath.abs(largest - smallest) * .1;
|
||||
|
||||
mImpulseYAxis.setLowerBound(smallest - padding);
|
||||
mImpulseYAxis.setUpperBound(largest + padding);
|
||||
@@ -180,7 +181,7 @@ public class FilterView extends BorderPane
|
||||
{
|
||||
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])));
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package io.github.dsheirer.dsp.filter.fir;
|
||||
|
||||
import io.github.dsheirer.dsp.filter.fir.remez.FIRLinearPhaseFilterType;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -887,7 +888,7 @@ public class FIRFilterSpecification
|
||||
*/
|
||||
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,
|
||||
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 dds = Math.log10(stopBandRipple <= passBandRipple ? stopBandRipple : passBandRipple);
|
||||
double ddp = FastMath.log10(FastMath.max(stopBandRipple, passBandRipple));
|
||||
double dds = FastMath.log10(FastMath.min(stopBandRipple, passBandRipple));
|
||||
|
||||
double a1 = 5.309e-3;
|
||||
double a2 = 7.114e-2;
|
||||
@@ -932,7 +933,7 @@ public class FIRFilterSpecification
|
||||
double ff = b1 + b2 * (ddp - dds);
|
||||
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,
|
||||
double passBandRippleDb, double stopBandRippleDb)
|
||||
{
|
||||
double df = (double)Math.abs(passBandEnd - passBandStart) / sampleRate;
|
||||
double ddp = Math.log10(passBandRippleDb);
|
||||
double dds = Math.log10(stopBandRippleDb);
|
||||
double df = (double)FastMath.abs(passBandEnd - passBandStart) / sampleRate;
|
||||
double ddp = FastMath.log10(passBandRippleDb);
|
||||
double dds = FastMath.log10(stopBandRippleDb);
|
||||
|
||||
double a1 = 0.01201;
|
||||
double a2 = 0.09664;
|
||||
@@ -963,10 +964,10 @@ public class FIRFilterSpecification
|
||||
double t4 = a5 * ddp;
|
||||
|
||||
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;
|
||||
|
||||
return (int)Math.ceil(n);
|
||||
return (int)FastMath.ceil(n);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1040,7 +1041,7 @@ public class FIRFilterSpecification
|
||||
|
||||
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()
|
||||
@@ -1104,8 +1105,8 @@ public class FIRFilterSpecification
|
||||
*/
|
||||
public double getRippleAmplitude()
|
||||
{
|
||||
return (Math.pow(10.0, (mRippleDB / 20)) - 1)
|
||||
/ (Math.pow(10.0, (mRippleDB / 20)) + 1);
|
||||
return (FastMath.pow(10.0, (mRippleDB / 20)) - 1)
|
||||
/ (FastMath.pow(10.0, (mRippleDB / 20)) + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package io.github.dsheirer.dsp.filter.fir.remez;
|
||||
|
||||
import io.github.dsheirer.dsp.filter.fir.FIRFilterSpecification;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
|
||||
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[] mCosineOfFrequencyGrid;
|
||||
@@ -59,7 +60,7 @@ public class Grid
|
||||
//gridFrequencyInterval increments
|
||||
mFrequencyGrid[ j ] = lowFrequency;
|
||||
|
||||
mCosineOfFrequencyGrid[ j ] = Math.cos( TWO_PI * mFrequencyGrid[ j ] );
|
||||
mCosineOfFrequencyGrid[ j ] = FastMath.cos( TWO_PI * mFrequencyGrid[ j ] );
|
||||
|
||||
lowFrequency += gridFrequencyInterval;
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
package io.github.dsheirer.dsp.filter.fir.remez;
|
||||
|
||||
import io.github.dsheirer.dsp.filter.fir.FIRFilterSpecification;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -26,7 +27,7 @@ public class PolyphaseChannelizerFilterFactory
|
||||
{
|
||||
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)
|
||||
{
|
||||
@@ -77,7 +78,7 @@ public class PolyphaseChannelizerFilterFactory
|
||||
specification.addFrequencyBand(transitionBand);
|
||||
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;
|
||||
|
||||
try
|
||||
|
||||
@@ -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.fir.FIRFilterSpecification;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -16,7 +17,7 @@ public class RemezFIRFilterDesigner
|
||||
|
||||
private static final double CONVERGENCE_THRESHOLD = 0.0001;
|
||||
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" );
|
||||
|
||||
@@ -164,7 +165,7 @@ public class RemezFIRFilterDesigner
|
||||
|
||||
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;
|
||||
@@ -181,7 +182,7 @@ public class RemezFIRFilterDesigner
|
||||
|
||||
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;
|
||||
@@ -214,7 +215,7 @@ public class RemezFIRFilterDesigner
|
||||
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( Math.abs( cosineDelta ) < 1.0e-7 )
|
||||
if( FastMath.abs( cosineDelta ) < 1.0e-7 )
|
||||
{
|
||||
return mIdealFrequencyResponse[ k ];
|
||||
}
|
||||
@@ -319,7 +320,7 @@ public class RemezFIRFilterDesigner
|
||||
|
||||
double denominator = xk - xi;
|
||||
|
||||
if( Math.abs( denominator ) < 0.00001 )
|
||||
if( FastMath.abs( 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
|
||||
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
|
||||
it.remove();
|
||||
@@ -530,8 +531,8 @@ public class RemezFIRFilterDesigner
|
||||
{
|
||||
int lastIndex = mExtremalIndices.size() - 1;
|
||||
|
||||
if( Math.abs( mGridErrors[ mExtremalIndices.get( 0 )] ) >
|
||||
Math.abs( mGridErrors[ mExtremalIndices.get( lastIndex )] ) )
|
||||
if( FastMath.abs( mGridErrors[ mExtremalIndices.get( 0 )] ) >
|
||||
FastMath.abs( mGridErrors[ mExtremalIndices.get( lastIndex )] ) )
|
||||
{
|
||||
mExtremalIndices.remove( lastIndex );
|
||||
}
|
||||
@@ -560,7 +561,7 @@ public class RemezFIRFilterDesigner
|
||||
*/
|
||||
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()
|
||||
{
|
||||
double maximum = Math.abs( mGridErrors[ mExtremalIndices.get( 0 ) ] );
|
||||
double maximum = FastMath.abs( mGridErrors[ mExtremalIndices.get( 0 ) ] );
|
||||
|
||||
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 )
|
||||
{
|
||||
@@ -582,7 +583,7 @@ public class RemezFIRFilterDesigner
|
||||
}
|
||||
}
|
||||
|
||||
double convergence = maximum - Math.abs( mDelta );
|
||||
double convergence = maximum - FastMath.abs( mDelta );
|
||||
|
||||
mConverged = convergence < CONVERGENCE_THRESHOLD;
|
||||
}
|
||||
@@ -619,11 +620,11 @@ public class RemezFIRFilterDesigner
|
||||
|
||||
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++ )
|
||||
{
|
||||
resampled[ x ] = getFrequencyResponse( Math.cos( Math.PI * (double)x / half ) );
|
||||
resampled[ x ] = getFrequencyResponse( FastMath.cos( FastMath.PI * (double)x / half ) );
|
||||
}
|
||||
|
||||
return resampled;
|
||||
@@ -651,15 +652,15 @@ public class RemezFIRFilterDesigner
|
||||
case TYPE_3_ODD_LENGTH_EVEN_ORDER_ANTI_SYMMETRICAL:
|
||||
for( int x = 0; x < frequencyResponse.length; x++ )
|
||||
{
|
||||
double frequencyRadians = Math.PI * ( ( (double)x ) / filterLength );
|
||||
frequencyResponse[ x ] *= Math.sin( TWO_PI * frequencyRadians );
|
||||
double frequencyRadians = FastMath.PI * ( ( (double)x ) / filterLength );
|
||||
frequencyResponse[ x ] *= FastMath.sin( TWO_PI * frequencyRadians );
|
||||
}
|
||||
break;
|
||||
case TYPE_4_EVEN_LENGTH_ODD_ORDER_ANTI_SYMMETRICAL:
|
||||
for( int x = 0; x < frequencyResponse.length; x++ )
|
||||
{
|
||||
double frequencyRadians = Math.PI * ( ( (double)x ) / filterLength );
|
||||
frequencyResponse[ x ] *= Math.sin( Math.PI * frequencyRadians );
|
||||
double frequencyRadians = FastMath.PI * ( ( (double)x ) / filterLength );
|
||||
frequencyResponse[ x ] *= FastMath.sin( FastMath.PI * frequencyRadians );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -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.fir.FIRFilterSpecification;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -35,7 +36,7 @@ public class RemezFIRFilterDesigner2
|
||||
|
||||
private static final double CONVERGENCE_THRESHOLD = 0.0001;
|
||||
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;
|
||||
|
||||
private FIRFilterSpecification mSpecification;
|
||||
@@ -189,7 +190,7 @@ public class RemezFIRFilterDesigner2
|
||||
|
||||
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;
|
||||
@@ -206,7 +207,7 @@ public class RemezFIRFilterDesigner2
|
||||
|
||||
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;
|
||||
@@ -238,7 +239,7 @@ public class RemezFIRFilterDesigner2
|
||||
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(Math.abs(cosineDelta) < FREQUENCY_PROXIMITY_THRESHOLD)
|
||||
if(FastMath.abs(cosineDelta) < FREQUENCY_PROXIMITY_THRESHOLD)
|
||||
{
|
||||
return mIdealFrequencyResponse[k];
|
||||
}
|
||||
@@ -360,7 +361,7 @@ public class RemezFIRFilterDesigner2
|
||||
|
||||
double denominator = xk - xi;
|
||||
|
||||
if(Math.abs(denominator) < 0.00001)
|
||||
if(FastMath.abs(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
|
||||
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
|
||||
it.remove();
|
||||
@@ -571,8 +572,8 @@ public class RemezFIRFilterDesigner2
|
||||
{
|
||||
int lastIndex = mExtremalIndices.size() - 1;
|
||||
|
||||
if(Math.abs(mGridErrors[mExtremalIndices.get(0)]) >
|
||||
Math.abs(mGridErrors[mExtremalIndices.get(lastIndex)]))
|
||||
if(FastMath.abs(mGridErrors[mExtremalIndices.get(0)]) >
|
||||
FastMath.abs(mGridErrors[mExtremalIndices.get(lastIndex)]))
|
||||
{
|
||||
mExtremalIndices.remove(lastIndex);
|
||||
}
|
||||
@@ -600,7 +601,7 @@ public class RemezFIRFilterDesigner2
|
||||
*/
|
||||
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()
|
||||
{
|
||||
double maximum = Math.abs(mGridErrors[mExtremalIndices.get(0)]);
|
||||
double maximum = FastMath.abs(mGridErrors[mExtremalIndices.get(0)]);
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -622,7 +623,7 @@ public class RemezFIRFilterDesigner2
|
||||
}
|
||||
}
|
||||
|
||||
double convergence = maximum - Math.abs(mDelta);
|
||||
double convergence = maximum - FastMath.abs(mDelta);
|
||||
|
||||
mConverged = convergence < CONVERGENCE_THRESHOLD;
|
||||
}
|
||||
@@ -659,11 +660,11 @@ public class RemezFIRFilterDesigner2
|
||||
|
||||
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++)
|
||||
{
|
||||
resampled[x] = getFrequencyResponse(Math.cos(Math.PI * (double)x / half));
|
||||
resampled[x] = getFrequencyResponse(FastMath.cos(FastMath.PI * (double)x / half));
|
||||
}
|
||||
|
||||
return resampled;
|
||||
@@ -690,15 +691,15 @@ public class RemezFIRFilterDesigner2
|
||||
case TYPE_3_ODD_LENGTH_EVEN_ORDER_ANTI_SYMMETRICAL:
|
||||
for(int x = 0; x < frequencyResponse.length; x++)
|
||||
{
|
||||
double frequencyRadians = Math.PI * (((double)x) / filterLength);
|
||||
frequencyResponse[x] *= Math.sin(TWO_PI * frequencyRadians);
|
||||
double frequencyRadians = FastMath.PI * (((double)x) / filterLength);
|
||||
frequencyResponse[x] *= FastMath.sin(TWO_PI * frequencyRadians);
|
||||
}
|
||||
break;
|
||||
case TYPE_4_EVEN_LENGTH_ODD_ORDER_ANTI_SYMMETRICAL:
|
||||
for(int x = 0; x < frequencyResponse.length; x++)
|
||||
{
|
||||
double frequencyRadians = Math.PI * (((double)x) / filterLength);
|
||||
frequencyResponse[x] *= Math.sin(Math.PI * frequencyRadians);
|
||||
double frequencyRadians = FastMath.PI * (((double)x) / filterLength);
|
||||
frequencyResponse[x] *= FastMath.sin(FastMath.PI * frequencyRadians);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -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.fir.FIRFilterSpecification;
|
||||
import org.apache.commons.math3.analysis.polynomials.PolynomialFunctionLagrangeForm;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -36,7 +37,7 @@ public class RemezFIRFilterDesignerWithLagrange
|
||||
|
||||
private static final double CONVERGENCE_THRESHOLD = 0.0001;
|
||||
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");
|
||||
|
||||
@@ -178,7 +179,7 @@ public class RemezFIRFilterDesignerWithLagrange
|
||||
|
||||
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;
|
||||
@@ -195,7 +196,7 @@ public class RemezFIRFilterDesignerWithLagrange
|
||||
|
||||
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;
|
||||
@@ -351,7 +352,7 @@ public class RemezFIRFilterDesignerWithLagrange
|
||||
|
||||
double denominator = xk - xi;
|
||||
|
||||
if(Math.abs(denominator) < 0.00001)
|
||||
if(FastMath.abs(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
|
||||
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
|
||||
it.remove();
|
||||
@@ -545,8 +546,8 @@ public class RemezFIRFilterDesignerWithLagrange
|
||||
{
|
||||
int lastIndex = mExtremalIndices.size() - 1;
|
||||
|
||||
if(Math.abs(mGridErrors[mExtremalIndices.get(0)]) >
|
||||
Math.abs(mGridErrors[mExtremalIndices.get(lastIndex)]))
|
||||
if(FastMath.abs(mGridErrors[mExtremalIndices.get(0)]) >
|
||||
FastMath.abs(mGridErrors[mExtremalIndices.get(lastIndex)]))
|
||||
{
|
||||
mExtremalIndices.remove(lastIndex);
|
||||
}
|
||||
@@ -574,7 +575,7 @@ public class RemezFIRFilterDesignerWithLagrange
|
||||
*/
|
||||
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()
|
||||
{
|
||||
double maximum = Math.abs(mGridErrors[mExtremalIndices.get(0)]);
|
||||
double maximum = FastMath.abs(mGridErrors[mExtremalIndices.get(0)]);
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -596,7 +597,7 @@ public class RemezFIRFilterDesignerWithLagrange
|
||||
}
|
||||
}
|
||||
|
||||
double convergence = maximum - Math.abs(mDelta);
|
||||
double convergence = maximum - FastMath.abs(mDelta);
|
||||
|
||||
mLog.debug("Convergence: " + convergence);
|
||||
|
||||
@@ -635,11 +636,11 @@ public class RemezFIRFilterDesignerWithLagrange
|
||||
|
||||
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++)
|
||||
{
|
||||
resampled[x] = getFrequencyResponse(Math.cos(Math.PI * (double)x / half));
|
||||
resampled[x] = getFrequencyResponse(FastMath.cos(FastMath.PI * (double)x / half));
|
||||
}
|
||||
|
||||
return resampled;
|
||||
@@ -666,15 +667,15 @@ public class RemezFIRFilterDesignerWithLagrange
|
||||
case TYPE_3_ODD_LENGTH_EVEN_ORDER_ANTI_SYMMETRICAL:
|
||||
for(int x = 0; x < frequencyResponse.length; x++)
|
||||
{
|
||||
double frequencyRadians = Math.PI * (((double)x) / filterLength);
|
||||
frequencyResponse[x] *= Math.sin(TWO_PI * frequencyRadians);
|
||||
double frequencyRadians = FastMath.PI * (((double)x) / filterLength);
|
||||
frequencyResponse[x] *= FastMath.sin(TWO_PI * frequencyRadians);
|
||||
}
|
||||
break;
|
||||
case TYPE_4_EVEN_LENGTH_ODD_ORDER_ANTI_SYMMETRICAL:
|
||||
for(int x = 0; x < frequencyResponse.length; x++)
|
||||
{
|
||||
double frequencyRadians = Math.PI * (((double)x) / filterLength);
|
||||
frequencyResponse[x] *= Math.sin(Math.PI * frequencyRadians);
|
||||
double frequencyRadians = FastMath.PI * (((double)x) / filterLength);
|
||||
frequencyResponse[x] *= FastMath.sin(FastMath.PI * frequencyRadians);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package io.github.dsheirer.dsp.filter.hilbert;
|
||||
|
||||
import io.github.dsheirer.dsp.filter.Filters;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -230,11 +231,11 @@ public class HilbertTransform
|
||||
{
|
||||
if(x < middle)
|
||||
{
|
||||
mHilbertFilter[x] = 2.0f * -Math.abs(coefficients[x]);
|
||||
mHilbertFilter[x] = 2.0f * -FastMath.abs(coefficients[x]);
|
||||
}
|
||||
else if(x > middle)
|
||||
{
|
||||
mHilbertFilter[x] = 2.0f * Math.abs(coefficients[x]);
|
||||
mHilbertFilter[x] = 2.0f * FastMath.abs(coefficients[x]);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
******************************************************************************/
|
||||
package io.github.dsheirer.dsp.filter.iir;
|
||||
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
|
||||
public class DeemphasisFilter
|
||||
{
|
||||
private static final float MAX_SAMPLE_VALUE = 0.95f;
|
||||
@@ -24,7 +26,7 @@ public class DeemphasisFilter
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -41,12 +43,7 @@ public class DeemphasisFilter
|
||||
{
|
||||
return MAX_SAMPLE_VALUE;
|
||||
}
|
||||
else if( value < -MAX_SAMPLE_VALUE )
|
||||
{
|
||||
return -MAX_SAMPLE_VALUE;
|
||||
}
|
||||
|
||||
else return value;
|
||||
else return FastMath.max(value, -MAX_SAMPLE_VALUE);
|
||||
}
|
||||
|
||||
public float[] filter( float[] samples )
|
||||
|
||||
@@ -2,6 +2,7 @@ package io.github.dsheirer.dsp.filter.interpolator;
|
||||
|
||||
import io.github.dsheirer.sample.complex.Complex;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -70,13 +71,13 @@ public class RealInterpolator extends Interpolator
|
||||
RealInterpolator interpolator = new RealInterpolator(1.0f);
|
||||
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];
|
||||
|
||||
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));
|
||||
|
||||
@@ -21,6 +21,7 @@ import io.github.dsheirer.sample.buffer.ReusableBufferQueue;
|
||||
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
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.
|
||||
@@ -81,7 +82,7 @@ public class FMDemodulator
|
||||
* serves as the instantaneous amplitude of the demodulated signal
|
||||
*/
|
||||
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
|
||||
*/
|
||||
double denominator = 1.0d / inphase;
|
||||
angle = Math.atan((double)quadrature * denominator);
|
||||
angle = FastMath.atan((double)quadrature * denominator);
|
||||
}
|
||||
|
||||
return angle;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
******************************************************************************/
|
||||
package io.github.dsheirer.dsp.fsk;
|
||||
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -47,7 +48,7 @@ public class SampleBuffer
|
||||
mIntegerSamplesPerSymbol = (int)(samplesPerSymbol + 0.5f);
|
||||
mHalfIntegerSamplesPerSymbol = (int)(samplesPerSymbol / 2.0f + 0.5f);
|
||||
mMidSymbolSamplingPoint = samplesPerSymbol + mHalfIntegerSamplesPerSymbol;
|
||||
mTwiceSamplesPerSymbol = (int)Math.floor(2.0 * samplesPerSymbol);
|
||||
mTwiceSamplesPerSymbol = (int) FastMath.floor(2.0 * samplesPerSymbol);
|
||||
mDelayLine = new boolean[2 * mTwiceSamplesPerSymbol];
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
******************************************************************************/
|
||||
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
|
||||
* 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)
|
||||
{
|
||||
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 = (samplesPerSymbol / 2.0f);
|
||||
}
|
||||
@@ -108,7 +110,7 @@ public class ZeroCrossingErrorDetector
|
||||
float errorDistanceOne = mZeroCrossingIdeal - mZeroCrossingOne;
|
||||
float errorDistanceTwo = mZeroCrossingCount - mZeroCrossingTwo;
|
||||
|
||||
if(Math.abs(errorDistanceOne) < Math.abs(errorDistanceTwo))
|
||||
if(FastMath.abs(errorDistanceOne) < FastMath.abs(errorDistanceTwo))
|
||||
{
|
||||
mDetectedZeroCrossing = mZeroCrossingOne;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import io.github.dsheirer.buffer.DoubleCircularBuffer;
|
||||
import io.github.dsheirer.buffer.RealCircularBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBufferQueue;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
@@ -74,10 +75,10 @@ public class AutomaticGainControl
|
||||
private static final double ATTACK_FALL_TIME_CONSTANT = 0.005;
|
||||
|
||||
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 -
|
||||
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) */
|
||||
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_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 -
|
||||
Math.exp(-1.0 / (SAMPLE_RATE * DECAY * .001));
|
||||
FastMath.exp(-1.0 / (SAMPLE_RATE * DECAY * .001));
|
||||
|
||||
/* Hang timer release decay time constant in seconds */
|
||||
@SuppressWarnings("unused")
|
||||
@@ -110,7 +111,7 @@ public class AutomaticGainControl
|
||||
private static final double MANUAL_GAIN = 0.0;
|
||||
|
||||
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) */
|
||||
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 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 */
|
||||
private static final double MIN_CONSTANT = 3.2767E-4;
|
||||
@@ -178,7 +179,7 @@ public class AutomaticGainControl
|
||||
|
||||
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);
|
||||
|
||||
@@ -212,7 +213,7 @@ public class AutomaticGainControl
|
||||
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)
|
||||
{
|
||||
@@ -220,7 +221,7 @@ public class AutomaticGainControl
|
||||
}
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import io.github.dsheirer.buffer.DoubleCircularBuffer;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.Provider;
|
||||
import io.github.dsheirer.sample.complex.Complex;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
|
||||
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_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 -
|
||||
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) */
|
||||
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_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 -
|
||||
Math.exp( -1.0 / ( SAMPLE_RATE * DECAY * .001 ) );
|
||||
FastMath.exp( -1.0 / ( SAMPLE_RATE * DECAY * .001 ) );
|
||||
|
||||
/* Hang timer release decay time constant in seconds */
|
||||
@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_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) */
|
||||
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 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 */
|
||||
private static final double MIN_CONSTANT = 3.2767E-4;
|
||||
@@ -156,8 +157,8 @@ public class ComplexAutomaticGainControl implements Listener<Complex>,
|
||||
{
|
||||
float max = currentSample.maximumAbsolute();
|
||||
|
||||
double currentMagnitude = Math.log10( max + MIN_CONSTANT ) -
|
||||
Math.log10( MAX_AMPLITUDE );
|
||||
double currentMagnitude = FastMath.log10( max + MIN_CONSTANT ) -
|
||||
FastMath.log10( MAX_AMPLITUDE );
|
||||
|
||||
double delayedMagnitude = mMagnitudeBuffer.get( currentMagnitude );
|
||||
|
||||
@@ -195,8 +196,7 @@ public class ComplexAutomaticGainControl implements Listener<Complex>,
|
||||
( DECAY_RISE_ALPHA * mPeakMagnitude );
|
||||
}
|
||||
|
||||
double magnitude = ( mAttackAverage > mDecayAverage ) ?
|
||||
mAttackAverage : mDecayAverage;
|
||||
double magnitude = FastMath.max(mAttackAverage, mDecayAverage);
|
||||
|
||||
if( magnitude < KNEE )
|
||||
{
|
||||
@@ -204,7 +204,7 @@ public class ComplexAutomaticGainControl implements Listener<Complex>,
|
||||
}
|
||||
else
|
||||
{
|
||||
gain = AGC_OUT_SCALE * Math.pow( 10.0,
|
||||
gain = AGC_OUT_SCALE * FastMath.pow( 10.0,
|
||||
magnitude * ( GAIN_SLOPE - 1.0 ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
******************************************************************************/
|
||||
package io.github.dsheirer.dsp.mixer;
|
||||
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -26,7 +27,7 @@ public class LowPhaseNoiseOscillator extends AbstractOscillator
|
||||
{
|
||||
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 double mInphase = 1.0;
|
||||
private double mQuadrature = 0.0;
|
||||
@@ -68,8 +69,8 @@ public class LowPhaseNoiseOscillator extends AbstractOscillator
|
||||
{
|
||||
double anglePerSample = TWO_PI * getFrequency() / getSampleRate();
|
||||
|
||||
mCosineAngle = Math.cos(anglePerSample);
|
||||
mSineAngle = Math.sin(anglePerSample);
|
||||
mCosineAngle = FastMath.cos(anglePerSample);
|
||||
mSineAngle = FastMath.sin(anglePerSample);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package io.github.dsheirer.dsp.mixer;
|
||||
|
||||
import io.github.dsheirer.sample.complex.Complex;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
|
||||
public class Oscillator extends AbstractOscillator
|
||||
{
|
||||
@@ -62,7 +63,7 @@ public class Oscillator extends AbstractOscillator
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import io.github.dsheirer.dsp.psk.pll.IPhaseLockedLoop;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
|
||||
import io.github.dsheirer.sample.complex.Complex;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
|
||||
public class DQPSKDecisionDirectedDemodulatorInstrumented extends DQPSKDecisionDirectedDemodulator
|
||||
{
|
||||
@@ -102,7 +103,7 @@ public class DQPSKDecisionDirectedDemodulatorInstrumented extends DQPSKDecisionD
|
||||
{
|
||||
double loopFrequency = ((CostasLoop)getPLL()).getLoopFrequency();
|
||||
|
||||
loopFrequency *= mSampleRate / (2.0 * Math.PI);
|
||||
loopFrequency *= mSampleRate / (2.0 * FastMath.PI);
|
||||
|
||||
mPLLFrequencyListener.receive(loopFrequency);
|
||||
}
|
||||
|
||||
@@ -17,13 +17,14 @@ package io.github.dsheirer.dsp.psk;
|
||||
|
||||
import io.github.dsheirer.dsp.symbol.Dibit;
|
||||
import io.github.dsheirer.sample.complex.Complex;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
|
||||
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_45 = Complex.fromAngle(-1.0 * Math.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_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 * FastMath.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 * FastMath.PI / 4.0);
|
||||
|
||||
private Complex mEvaluationSymbol = new Complex(0, 0);
|
||||
private float mPhaseError = 0.0f;
|
||||
|
||||
@@ -26,6 +26,7 @@ import io.github.dsheirer.dsp.psk.pll.IPhaseLockedLoop;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
|
||||
import io.github.dsheirer.sample.complex.Complex;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
|
||||
public class DQPSKGardnerDemodulatorInstrumented extends DQPSKGardnerDemodulator
|
||||
{
|
||||
@@ -99,7 +100,7 @@ public class DQPSKGardnerDemodulatorInstrumented extends DQPSKGardnerDemodulator
|
||||
{
|
||||
double loopFrequency = ((CostasLoop)getPLL()).getLoopFrequency();
|
||||
|
||||
loopFrequency *= mSampleRate / (2.0 * Math.PI);
|
||||
loopFrequency *= mSampleRate / (2.0 * FastMath.PI);
|
||||
|
||||
mPLLFrequencyListener.receive(loopFrequency);
|
||||
}
|
||||
|
||||
@@ -17,13 +17,14 @@ package io.github.dsheirer.dsp.psk;
|
||||
|
||||
import io.github.dsheirer.dsp.symbol.Dibit;
|
||||
import io.github.dsheirer.sample.complex.Complex;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
|
||||
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_45 = Complex.fromAngle(-1.0 * Math.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_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 * FastMath.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 * FastMath.PI / 4.0);
|
||||
|
||||
private float mPhaseError = 0.0f;
|
||||
private float mTimingError = 0.0f;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package io.github.dsheirer.dsp.psk;
|
||||
|
||||
import io.github.dsheirer.sample.complex.Complex;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
|
||||
public class GardnerDetector
|
||||
{
|
||||
@@ -41,8 +42,8 @@ public class GardnerDetector
|
||||
*/
|
||||
public float getError(Complex previous, Complex middle, Complex current)
|
||||
{
|
||||
mErrorInphase = (Math.abs(previous.inphase()) - Math.abs(current.inphase())) * Math.abs(middle.inphase());
|
||||
mErrorQuadrature = (Math.abs(previous.quadrature()) - Math.abs(current.quadrature())) * Math.abs(middle.quadrature());
|
||||
mErrorInphase = (FastMath.abs(previous.inphase()) - FastMath.abs(current.inphase())) * FastMath.abs(middle.inphase());
|
||||
mErrorQuadrature = (FastMath.abs(previous.quadrature()) - FastMath.abs(current.quadrature())) * FastMath.abs(middle.quadrature());
|
||||
mError = normalize(mErrorInphase + mErrorQuadrature, 1.0f);
|
||||
|
||||
return mError;
|
||||
|
||||
@@ -23,6 +23,7 @@ package io.github.dsheirer.dsp.psk;
|
||||
|
||||
import io.github.dsheirer.dsp.filter.interpolator.RealInterpolator;
|
||||
import io.github.dsheirer.sample.complex.Complex;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -60,7 +61,7 @@ public class InterpolatingSampleBuffer
|
||||
mDetectedSamplesPerSymbol = samplesPerSymbol;
|
||||
mMaximumSamplesPerSymbol = 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];
|
||||
mDelayLineQuadrature = new float[2 * mTwiceSamplesPerSymbol];
|
||||
|
||||
@@ -190,7 +191,7 @@ public class InterpolatingSampleBuffer
|
||||
}
|
||||
else
|
||||
{
|
||||
int offset = (int)Math.floor(interpolation);
|
||||
int offset = (int)FastMath.floor(interpolation);
|
||||
return mInterpolator.filter(mDelayLineInphase, mDelayLinePointer + offset, interpolation - offset);
|
||||
}
|
||||
}
|
||||
@@ -208,7 +209,7 @@ public class InterpolatingSampleBuffer
|
||||
}
|
||||
else
|
||||
{
|
||||
int offset = (int)Math.floor(interpolation);
|
||||
int offset = (int)FastMath.floor(interpolation);
|
||||
return mInterpolator.filter(mDelayLineQuadrature, mDelayLinePointer + offset, interpolation - offset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ package io.github.dsheirer.dsp.psk;
|
||||
|
||||
import io.github.dsheirer.sample.complex.Complex;
|
||||
import io.github.dsheirer.sample.complex.ComplexSampleListener;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -36,7 +37,7 @@ public class InterpolatingSampleBufferInstrumented extends InterpolatingSampleBu
|
||||
public InterpolatingSampleBufferInstrumented(float samplesPerSymbol, float symbolTimingGain)
|
||||
{
|
||||
super(samplesPerSymbol, symbolTimingGain);
|
||||
mBufferLength = (int)Math.ceil(samplesPerSymbol);
|
||||
mBufferLength = (int) FastMath.ceil(samplesPerSymbol);
|
||||
mSymbolDecisionData = new SymbolDecisionData(mBufferLength);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import io.github.dsheirer.dsp.symbol.Dibit;
|
||||
import io.github.dsheirer.sample.Broadcaster;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.complex.Complex;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
|
||||
public class QPSKSymbolDecoder implements Listener<Complex>, IQPSKSymbolDecoder
|
||||
{
|
||||
@@ -63,7 +64,7 @@ public class QPSKSymbolDecoder implements Listener<Complex>, IQPSKSymbolDecoder
|
||||
|
||||
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 )
|
||||
{
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package io.github.dsheirer.dsp.psk;
|
||||
|
||||
import io.github.dsheirer.sample.complex.Complex;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
|
||||
/**
|
||||
* Calculates the phase error for a QPSK polar-orientation constellation
|
||||
@@ -29,7 +30,7 @@ public class QPSKSymbolPhaseErrorCalculator implements ISymbolPhaseErrorCalculat
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -23,11 +23,12 @@ package io.github.dsheirer.dsp.psk;
|
||||
|
||||
import io.github.dsheirer.buffer.ComplexCircularBuffer;
|
||||
import io.github.dsheirer.sample.complex.Complex;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
|
||||
public class SymbolDecisionData
|
||||
{
|
||||
//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 float mSamplingPoint;
|
||||
|
||||
@@ -15,11 +15,13 @@
|
||||
******************************************************************************/
|
||||
package io.github.dsheirer.dsp.psk;
|
||||
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
|
||||
public enum SymbolInversion
|
||||
{
|
||||
DEGREES_90_PLUS(Math.PI / 2.0),
|
||||
DEGREES_90_MINUS(Math.PI / -2.0),
|
||||
DEGREES_180(Math.PI);
|
||||
DEGREES_90_PLUS(FastMath.PI / 2.0),
|
||||
DEGREES_90_MINUS(FastMath.PI / -2.0),
|
||||
DEGREES_180(FastMath.PI);
|
||||
|
||||
private double mAngleRadians;
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
package io.github.dsheirer.dsp.psk.pll;
|
||||
|
||||
import io.github.dsheirer.sample.complex.Complex;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -38,13 +39,13 @@ public class CostasLoop implements IPhaseLockedLoop
|
||||
{
|
||||
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 double mLoopPhase = 0.0;
|
||||
private double mLoopFrequency = 0.0;
|
||||
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 mBetaGain;
|
||||
private PLLBandwidth mPLLBandwidth = PLLBandwidth.BW_400;
|
||||
|
||||
@@ -86,9 +86,9 @@ public enum PLLBandwidth
|
||||
*/
|
||||
public static PLLBandwidth fromSyncCount(int syncCount)
|
||||
{
|
||||
if(LOOKUP_MAP.containsKey(syncCount))
|
||||
{
|
||||
return LOOKUP_MAP.get(syncCount);
|
||||
PLLBandwidth mapValue = LOOKUP_MAP.get(syncCount);
|
||||
if (mapValue != null) {
|
||||
return mapValue;
|
||||
}
|
||||
|
||||
return BW_200;
|
||||
|
||||
@@ -70,9 +70,9 @@ public class QPSKPhaseInversionCalculator
|
||||
}
|
||||
|
||||
System.out.println("NORMAL: " + sync);
|
||||
System.out.println(" +90: " + sbP90.toString());
|
||||
System.out.println(" -90: " + sbM90.toString());
|
||||
System.out.println(" 180: " + sb180.toString());
|
||||
System.out.println(" +90: " + sbP90);
|
||||
System.out.println(" -90: " + sbM90);
|
||||
System.out.println(" 180: " + sb180);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
package io.github.dsheirer.edac;
|
||||
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
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 */
|
||||
/* store degree of new elp polynomial */
|
||||
if( l[ u ] > l[ q ] + u - q )
|
||||
{
|
||||
l[ u + 1 ] = l[ u ];
|
||||
}
|
||||
else
|
||||
{
|
||||
l[ u + 1 ] = l[ q ] + u - q;
|
||||
}
|
||||
l[u + 1] = FastMath.max(l[u], l[q] + u - q);
|
||||
|
||||
/* form new elp(x) */
|
||||
for( int i = 0; i < NN - KK; i++ )
|
||||
@@ -373,10 +367,7 @@ public class BerlekempMassey_63
|
||||
}
|
||||
|
||||
/* find roots of the error location polynomial */
|
||||
for( int i = 1; i <= l[u]; i++ )
|
||||
{
|
||||
reg[ i ] = elp[ u ][ i ];
|
||||
}
|
||||
if (l[u] >= 0) System.arraycopy(elp[u], 1, reg, 1, l[u]);
|
||||
|
||||
count = 0;
|
||||
|
||||
|
||||
@@ -63,16 +63,10 @@ public enum CRC
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for(int x = 0; x < checks.length; x++)
|
||||
{
|
||||
CRC check = checks[x];
|
||||
|
||||
if(check != null)
|
||||
{
|
||||
for (CRC check : checks) {
|
||||
if (check != null) {
|
||||
sb.append(check.getAbbreviation());
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
sb.append(CRC.UNKNOWN.getAbbreviation());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
******************************************************************************/
|
||||
package io.github.dsheirer.edac.trellis;
|
||||
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
@@ -41,8 +43,8 @@ public abstract class ViterbiDecoder
|
||||
mInputBitLength = inputBitLength;
|
||||
mOutputBitLength = outputBitLength;
|
||||
|
||||
mInputValueCount = (int)Math.pow(2.0, mInputBitLength);
|
||||
mOutputValueCount = (int)Math.pow(2.0, mOutputBitLength);
|
||||
mInputValueCount = (int) FastMath.pow(2.0, mInputBitLength);
|
||||
mOutputValueCount = (int)FastMath.pow(2.0, mOutputBitLength);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -75,14 +75,7 @@ public class FilterEditorPanel<T> extends JPanel
|
||||
List<IFilter<T>> filters = filterSet.getFilters();
|
||||
|
||||
/* sort the filters in alphabetical order by name */
|
||||
Collections.sort(filters, new Comparator<IFilter<?>>()
|
||||
{
|
||||
@Override
|
||||
public int compare(IFilter<?> first, IFilter<?> second)
|
||||
{
|
||||
return first.getName().compareTo(second.getName());
|
||||
}
|
||||
});
|
||||
filters.sort((Comparator<IFilter<?>>) (first, second) -> first.getName().compareTo(second.getName()));
|
||||
|
||||
for(IFilter<T> filter : filters)
|
||||
{
|
||||
@@ -105,14 +98,7 @@ public class FilterEditorPanel<T> extends JPanel
|
||||
{
|
||||
List<FilterElement<?>> elements = filter.getFilterElements();
|
||||
|
||||
Collections.sort(elements, new Comparator<FilterElement<?>>()
|
||||
{
|
||||
@Override
|
||||
public int compare(FilterElement<?> o1, FilterElement<?> o2)
|
||||
{
|
||||
return o1.toString().compareTo(o2.toString());
|
||||
}
|
||||
});
|
||||
elements.sort(Comparator.comparing(FilterElement::toString));
|
||||
|
||||
for(FilterElement<?> element : elements)
|
||||
{
|
||||
|
||||
@@ -25,18 +25,18 @@ public class ChannelMemoryLogger implements Runnable, ChannelEventListener
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append( "CHAN TOT:" + mChannelCount );
|
||||
sb.append( " TRFC:" + mTrafficChannelCount );
|
||||
sb.append( " PROC:" + mChannelProcessingCount );
|
||||
sb.append("CHAN TOT:").append(mChannelCount);
|
||||
sb.append(" TRFC:").append(mTrafficChannelCount);
|
||||
sb.append(" PROC:").append(mChannelProcessingCount);
|
||||
|
||||
long maxMemory = runtime.maxMemory();
|
||||
long allocatedMemory = runtime.totalMemory();
|
||||
long freeMemory = runtime.freeMemory();
|
||||
|
||||
sb.append(" MEM FREE: " + format.format(freeMemory / 1024) );
|
||||
sb.append(" ALLOC: " + format.format(allocatedMemory / 1024) );
|
||||
sb.append(" MAX: " + format.format(maxMemory / 1024) );
|
||||
sb.append(" TOTAL: " + format.format((freeMemory + (maxMemory - allocatedMemory)) / 1024) );
|
||||
sb.append(" MEM FREE: ").append(format.format(freeMemory / 1024));
|
||||
sb.append(" ALLOC: ").append(format.format(allocatedMemory / 1024));
|
||||
sb.append(" MAX: ").append(format.format(maxMemory / 1024));
|
||||
sb.append(" TOTAL: ").append(format.format((freeMemory + (maxMemory - allocatedMemory)) / 1024));
|
||||
|
||||
mLog.debug( sb.toString() );
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package io.github.dsheirer.gui.control;
|
||||
import io.github.dsheirer.buffer.CircularBuffer;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.complex.Complex;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
|
||||
import javax.swing.*;
|
||||
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
|
||||
*/
|
||||
double denominator = 1.0d / i;
|
||||
angle = Math.atan( (double)q * denominator );
|
||||
angle = FastMath.atan( (double)q * denominator );
|
||||
}
|
||||
|
||||
Ellipse2D.Double ellipse =
|
||||
|
||||
@@ -22,6 +22,7 @@ import io.github.dsheirer.source.InvalidFrequencyException;
|
||||
import io.github.dsheirer.source.SourceEvent;
|
||||
import io.github.dsheirer.source.SourceException;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -287,17 +288,17 @@ public class JFrequencyControl extends JPanel implements ISourceEventProcessor
|
||||
public void setFrequency(long frequency, boolean fireChangeEvent)
|
||||
{
|
||||
//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
|
||||
long value = (long)(lower / (long)(Math.pow(10, mPower)));
|
||||
long value = (long)(lower / (long)(FastMath.pow(10, mPower)));
|
||||
|
||||
set(value, fireChangeEvent);
|
||||
}
|
||||
|
||||
public long getFrequency()
|
||||
{
|
||||
return mValue * (long)Math.pow(10, mPower);
|
||||
return mValue * (long)FastMath.pow(10, mPower);
|
||||
}
|
||||
|
||||
public void increment()
|
||||
|
||||
@@ -337,8 +337,7 @@ public class MultipleFrequencyEditor extends JPanel
|
||||
*/
|
||||
public List<Long> getFrequencies()
|
||||
{
|
||||
List<Long> frequencies = new ArrayList<>();
|
||||
frequencies.addAll(mFrequencies);
|
||||
List<Long> frequencies = new ArrayList<>(mFrequencies);
|
||||
return frequencies;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.chart.LineChart;
|
||||
import javafx.scene.chart.NumberAxis;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
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 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 ComplexGain mComplexGain = new ComplexGain(600.0f);
|
||||
private ObservableList<Data<Integer,Float>> mPhaseValues = FXCollections.observableArrayList();
|
||||
@@ -44,7 +45,7 @@ public class ComplexPhaseLineChart extends LineChart implements Listener<Reusabl
|
||||
public ComplexPhaseLineChart(int length)
|
||||
{
|
||||
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);
|
||||
ObservableList<Series<Integer,Float>> observableList = FXCollections.observableArrayList(phaseSeries);
|
||||
|
||||
@@ -28,6 +28,7 @@ import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.chart.LineChart;
|
||||
import javafx.scene.chart.NumberAxis;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -97,7 +98,7 @@ public class EyeDiagramChart extends LineChart implements Listener<SymbolDecisio
|
||||
{
|
||||
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;
|
||||
}
|
||||
@@ -109,11 +110,11 @@ public class EyeDiagramChart extends LineChart implements Listener<SymbolDecisio
|
||||
{
|
||||
if(corrected[x] > 0)
|
||||
{
|
||||
corrected[x] -= 2 * Math.PI;
|
||||
corrected[x] -= 2 * FastMath.PI;
|
||||
}
|
||||
else
|
||||
{
|
||||
corrected[x] += 2 * Math.PI;
|
||||
corrected[x] += 2 * FastMath.PI;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,9 +85,7 @@ public class SampleXYChart extends PolarChart<XYChartItem> implements Listener<R
|
||||
|
||||
series.getItems().clear();
|
||||
|
||||
for(int x = 0; x < complexSamples.length; x++)
|
||||
{
|
||||
Complex sample = complexSamples[x];
|
||||
for (Complex sample : complexSamples) {
|
||||
series.getItems().add(new XYChartItem(sample.polarAngleDegrees(), sample.magnitude(), Color.BLUE));
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
package io.github.dsheirer.gui.preference;
|
||||
|
||||
import io.github.dsheirer.preference.UserPreferences;
|
||||
import io.github.dsheirer.protocol.Protocol;
|
||||
import javafx.application.Application;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
@@ -41,6 +42,7 @@ import javafx.stage.Window;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
@@ -52,7 +54,7 @@ public class PreferencesEditor extends Application
|
||||
{
|
||||
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 HBox mParentBox;
|
||||
private TreeView mEditorSelectionTreeView;
|
||||
@@ -118,22 +120,14 @@ public class PreferencesEditor extends Application
|
||||
|
||||
private TreeItem recursivelyFindEditorType(TreeItem parent, PreferenceEditorType type)
|
||||
{
|
||||
ListIterator<TreeItem> li = parent.getChildren().listIterator();
|
||||
|
||||
while(li.hasNext())
|
||||
{
|
||||
TreeItem treeItem = li.next();
|
||||
|
||||
if(treeItem.getValue() instanceof PreferenceEditorType && (treeItem.getValue()).equals(type))
|
||||
{
|
||||
for (TreeItem treeItem : (Iterable<TreeItem>) parent.getChildren()) {
|
||||
if (treeItem.getValue() instanceof PreferenceEditorType && (treeItem.getValue()).equals(type)) {
|
||||
return treeItem;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
TreeItem item = recursivelyFindEditorType(treeItem, type);
|
||||
|
||||
if(item != null)
|
||||
{
|
||||
if (item != null) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,9 +151,9 @@ public class IconManager
|
||||
|
||||
String scaledIconName = name + height;
|
||||
|
||||
if(mResizedIcons.containsKey(scaledIconName))
|
||||
{
|
||||
return mResizedIcons.get(scaledIconName);
|
||||
ImageIcon mapValue = mResizedIcons.get(scaledIconName);
|
||||
if (mapValue != null) {
|
||||
return mapValue;
|
||||
}
|
||||
|
||||
Icon icon = getModel().getIcon(name);
|
||||
|
||||
@@ -168,7 +168,7 @@ public class IconTableModel extends AbstractTableModel
|
||||
|
||||
Collections.sort(icons);
|
||||
|
||||
return icons.toArray(new Icon[icons.size()]);
|
||||
return icons.toArray(new Icon[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -198,7 +198,7 @@ public class IdentifierCollection
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -157,13 +157,9 @@ public class PatchGroupManager
|
||||
PatchGroupIdentifier patchGroupIdentifier = (PatchGroupIdentifier)identifier;
|
||||
int patchGroupId = patchGroupIdentifier.getValue().getPatchGroup().getValue();
|
||||
|
||||
if(mPatchGroupMap.containsKey(patchGroupId))
|
||||
{
|
||||
return mPatchGroupMap.get(patchGroupId);
|
||||
}
|
||||
else
|
||||
{
|
||||
addPatchGroup(patchGroupIdentifier);
|
||||
Identifier mapValue = mPatchGroupMap.get(patchGroupId);
|
||||
if (mapValue != null) {
|
||||
return mapValue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
******************************************************************************/
|
||||
package io.github.dsheirer.map;
|
||||
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.jdesktop.swingx.JXMapViewer;
|
||||
|
||||
import java.awt.*;
|
||||
@@ -89,10 +90,10 @@ public class SelectionAdapter extends MouseAdapter
|
||||
{
|
||||
if (dragging)
|
||||
{
|
||||
int x1 = (int) Math.min(startPos.getX(), endPos.getX());
|
||||
int y1 = (int) Math.min(startPos.getY(), endPos.getY());
|
||||
int x2 = (int) Math.max(startPos.getX(), endPos.getX());
|
||||
int y2 = (int) Math.max(startPos.getY(), endPos.getY());
|
||||
int x1 = (int) FastMath.min(startPos.getX(), endPos.getX());
|
||||
int y1 = (int) FastMath.min(startPos.getY(), endPos.getY());
|
||||
int x2 = (int) FastMath.max(startPos.getX(), endPos.getX());
|
||||
int y2 = (int) FastMath.max(startPos.getY(), endPos.getY());
|
||||
|
||||
return new Rectangle(x1, y1, x2-x1, y2-y1);
|
||||
}
|
||||
|
||||
@@ -143,146 +143,28 @@ public class DecoderFactory
|
||||
switch(decodeConfig.getDecoderType())
|
||||
{
|
||||
case AM:
|
||||
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));
|
||||
}
|
||||
processAM(channel, modules, aliasList, decodeConfig);
|
||||
break;
|
||||
case NBFM:
|
||||
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));
|
||||
}
|
||||
processNBFM(channel, modules, aliasList, decodeConfig);
|
||||
break;
|
||||
case LTR_STANDARD:
|
||||
MessageDirection direction = ((DecodeConfigLTRStandard)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));
|
||||
}
|
||||
processLTRStandard(channel, modules, aliasList, (DecodeConfigLTRStandard) decodeConfig);
|
||||
break;
|
||||
case LTR_NET:
|
||||
modules.add(new LTRNetDecoder((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));
|
||||
}
|
||||
processLTRNet(channel, modules, aliasList, (DecodeConfigLTRNet) decodeConfig);
|
||||
break;
|
||||
case MPT1327:
|
||||
DecodeConfigMPT1327 mptConfig = (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));
|
||||
}
|
||||
processMPT1327(channelMapModel, channel, userPreferences, modules, aliasList, channelType, (DecodeConfigMPT1327) decodeConfig);
|
||||
break;
|
||||
case PASSPORT:
|
||||
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));
|
||||
}
|
||||
processPassport(channel, modules, aliasList, decodeConfig);
|
||||
break;
|
||||
case P25_PHASE1:
|
||||
DecodeConfigP25Phase1 p25Config = (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));
|
||||
}
|
||||
processP25Phase1(channel, userPreferences, modules, aliasList, channelType, (DecodeConfigP25Phase1) decodeConfig);
|
||||
break;
|
||||
case P25_PHASE2:
|
||||
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));
|
||||
processP25Phase2(channel, userPreferences, modules, aliasList);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown decoder type [" + decodeConfig.getDecoderType().toString() + "]");
|
||||
@@ -291,6 +173,156 @@ public class DecoderFactory
|
||||
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
|
||||
*
|
||||
|
||||
@@ -167,11 +167,9 @@ public class Fleetsync2DecoderState extends DecoderState
|
||||
}
|
||||
else
|
||||
{
|
||||
Iterator<FleetsyncIdentifier> it = mIdents.iterator();
|
||||
|
||||
while(it.hasNext())
|
||||
{
|
||||
sb.append(" ").append(it.next().formatted()).append("\n");
|
||||
for (FleetsyncIdentifier mIdent : mIdents) {
|
||||
sb.append(" ").append(mIdent.formatted()).append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,15 +24,13 @@ import io.github.dsheirer.filter.Filter;
|
||||
import io.github.dsheirer.filter.FilterElement;
|
||||
import io.github.dsheirer.message.IMessage;
|
||||
import io.github.dsheirer.module.decode.fleetsync2.message.Fleetsync2Message;
|
||||
import io.github.dsheirer.module.decode.ltrnet.LtrNetMessageType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
public class FleetsyncMessageFilter extends Filter<IMessage>
|
||||
{
|
||||
private HashMap<FleetsyncMessageType,FilterElement<FleetsyncMessageType>> mElements =
|
||||
new HashMap<FleetsyncMessageType,FilterElement<FleetsyncMessageType>>();
|
||||
private Map<FleetsyncMessageType,FilterElement<FleetsyncMessageType>> mElements = new EnumMap<>(FleetsyncMessageType.class);
|
||||
|
||||
public FleetsyncMessageFilter()
|
||||
{
|
||||
|
||||
@@ -25,6 +25,7 @@ import io.github.dsheirer.identifier.Role;
|
||||
import io.github.dsheirer.identifier.esn.ESNIdentifier;
|
||||
import io.github.dsheirer.message.Message;
|
||||
import io.github.dsheirer.protocol.Protocol;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -183,9 +184,9 @@ public class LJ1200Message extends Message
|
||||
|
||||
sb.append("] ADDRESS [");
|
||||
sb.append(getAddress());
|
||||
sb.append("] VRC [" + getVRC());
|
||||
sb.append("] LRC [" + getLRC());
|
||||
sb.append("] CRC [" + getCRC());
|
||||
sb.append("] VRC [").append(getVRC());
|
||||
sb.append("] LRC [").append(getLRC());
|
||||
sb.append("] CRC [").append(getCRC());
|
||||
sb.append("]");
|
||||
|
||||
return sb.toString();
|
||||
@@ -196,16 +197,7 @@ public class LJ1200Message extends Message
|
||||
*/
|
||||
public String pad(String value, int places, String padCharacter)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append(value);
|
||||
|
||||
while(sb.length() < places)
|
||||
{
|
||||
sb.append(padCharacter);
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
return StringUtils.rightPad(value, places, padCharacter);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -213,18 +205,7 @@ public class LJ1200Message extends Message
|
||||
*/
|
||||
public String format(int number, int decimalPlaces)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
int paddingRequired = decimalPlaces - (String.valueOf(number).length());
|
||||
|
||||
for(int x = 0; x < paddingRequired; x++)
|
||||
{
|
||||
sb.append("0");
|
||||
}
|
||||
|
||||
sb.append(number);
|
||||
|
||||
return sb.toString();
|
||||
return StringUtils.leftPad(Integer.valueOf(number).toString(), decimalPlaces, '0');
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -22,6 +22,7 @@ import io.github.dsheirer.edac.CRC;
|
||||
import io.github.dsheirer.identifier.Identifier;
|
||||
import io.github.dsheirer.message.Message;
|
||||
import io.github.dsheirer.protocol.Protocol;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -100,16 +101,7 @@ public class LJ1200TransponderMessage extends Message
|
||||
*/
|
||||
public String pad(String value, int places, String padCharacter)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append(value);
|
||||
|
||||
while(sb.length() < places)
|
||||
{
|
||||
sb.append(padCharacter);
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
return StringUtils.rightPad(value, places, padCharacter);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -117,18 +109,7 @@ public class LJ1200TransponderMessage extends Message
|
||||
*/
|
||||
public String format(int number, int decimalPlaces)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
int paddingRequired = decimalPlaces - (String.valueOf(number).length());
|
||||
|
||||
for(int x = 0; x < paddingRequired; x++)
|
||||
{
|
||||
sb.append("0");
|
||||
}
|
||||
|
||||
sb.append(number);
|
||||
|
||||
return sb.toString();
|
||||
return StringUtils.leftPad(Integer.valueOf(number).toString(), decimalPlaces, '0');
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -573,7 +573,7 @@ public class LTRNetDecoderState extends DecoderState
|
||||
else
|
||||
{
|
||||
List<LTRTalkgroup> talkgroups = new ArrayList<>(mTalkgroups);
|
||||
Collections.sort(talkgroups, Comparator.comparingInt(Identifier::getValue));
|
||||
talkgroups.sort(Comparator.comparingInt(Identifier::getValue));
|
||||
|
||||
for(LTRTalkgroup talkgroup: talkgroups)
|
||||
{
|
||||
@@ -590,7 +590,7 @@ public class LTRNetDecoderState extends DecoderState
|
||||
else
|
||||
{
|
||||
List<LtrNetRadioIdentifier> ltrNetRadioIdentifiers = new ArrayList<>(mLtrNetRadioIdentifiers);
|
||||
Collections.sort(ltrNetRadioIdentifiers, Comparator.comparingInt(Identifier::getValue));
|
||||
ltrNetRadioIdentifiers.sort(Comparator.comparingInt(Identifier::getValue));
|
||||
|
||||
for(LtrNetRadioIdentifier ltrNetRadioIdentifier : ltrNetRadioIdentifiers)
|
||||
{
|
||||
|
||||
@@ -4,15 +4,13 @@ import io.github.dsheirer.filter.Filter;
|
||||
import io.github.dsheirer.filter.FilterElement;
|
||||
import io.github.dsheirer.message.IMessage;
|
||||
import io.github.dsheirer.module.decode.ltrnet.message.LtrNetMessage;
|
||||
import io.github.dsheirer.module.decode.ltrstandard.LtrStandardMessageType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
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()
|
||||
{
|
||||
|
||||
@@ -24,15 +24,13 @@ import io.github.dsheirer.filter.Filter;
|
||||
import io.github.dsheirer.filter.FilterElement;
|
||||
import io.github.dsheirer.message.IMessage;
|
||||
import io.github.dsheirer.module.decode.ltrstandard.message.LTRStandardMessage;
|
||||
import io.github.dsheirer.module.decode.mdc1200.MDCMessageType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
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()
|
||||
{
|
||||
|
||||
@@ -152,11 +152,9 @@ public class MDCDecoderState extends DecoderState
|
||||
}
|
||||
else
|
||||
{
|
||||
Iterator<MDC1200Identifier> it = mIdents.iterator();
|
||||
|
||||
while(it.hasNext())
|
||||
{
|
||||
sb.append(" ").append(it.next()).append("\n");
|
||||
for (MDC1200Identifier mIdent : mIdents) {
|
||||
sb.append(" ").append(mIdent).append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,11 +170,9 @@ public class MDCDecoderState extends DecoderState
|
||||
|
||||
while(it.hasNext())
|
||||
{
|
||||
Iterator<MDC1200Identifier> it2 = mIdents.iterator();
|
||||
|
||||
while(it2.hasNext())
|
||||
{
|
||||
sb.append(" ").append(it2.next()).append("\n");
|
||||
for (MDC1200Identifier mIdent : mIdents) {
|
||||
sb.append(" ").append(mIdent).append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import io.github.dsheirer.identifier.Identifier;
|
||||
import io.github.dsheirer.message.Message;
|
||||
import io.github.dsheirer.module.decode.mdc1200.identifier.MDC1200Identifier;
|
||||
import io.github.dsheirer.protocol.Protocol;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -177,16 +178,7 @@ public class MDCMessage extends Message
|
||||
*/
|
||||
public String pad(String value, int places, String padCharacter)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append(value);
|
||||
|
||||
while(sb.length() < places)
|
||||
{
|
||||
sb.append(padCharacter);
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
return StringUtils.rightPad(value, places, padCharacter);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -194,18 +186,7 @@ public class MDCMessage extends Message
|
||||
*/
|
||||
public String format(int number, int decimalPlaces)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
int paddingRequired = decimalPlaces - (String.valueOf(number).length());
|
||||
|
||||
for(int x = 0; x < paddingRequired; x++)
|
||||
{
|
||||
sb.append("0");
|
||||
}
|
||||
|
||||
sb.append(number);
|
||||
|
||||
return sb.toString();
|
||||
return StringUtils.leftPad(Integer.valueOf(number).toString(), decimalPlaces, '0');
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -219,7 +200,7 @@ public class MDCMessage extends Message
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append("MDC1200 UNIT:" + getFromIdentifier());
|
||||
sb.append("MDC1200 UNIT:").append(getFromIdentifier());
|
||||
if(isEmergency())
|
||||
{
|
||||
sb.append(" **EMERGENCY**");
|
||||
@@ -235,11 +216,11 @@ public class MDCMessage extends Message
|
||||
sb.append(" EOT");
|
||||
}
|
||||
|
||||
sb.append(" OPCODE:" + format(getOpcode(), 2));
|
||||
sb.append(" ARG:" + format(getArgument(), 3));
|
||||
sb.append(" TYPE:" + getPacketType().toString());
|
||||
sb.append(" ACK:" + getResponse().toString());
|
||||
sb.append(" DIR:" + pad(getDirection().toString(), 3, " "));
|
||||
sb.append(" OPCODE:").append(format(getOpcode(), 2));
|
||||
sb.append(" ARG:").append(format(getArgument(), 3));
|
||||
sb.append(" TYPE:").append(getPacketType().toString());
|
||||
sb.append(" ACK:").append(getResponse().toString());
|
||||
sb.append(" DIR:").append(pad(getDirection().toString(), 3, " "));
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user