Performance improvements (#746)

* Misc minor performance improvements

* Use more concise loop syntax

* Use more concise Collection sort syntax

* Use StringUtils pad methods

* Optimize some loops and double-map-lookups

* Optimize array instantiation

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

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

* Cleanup string concatenation

* Use EnumMap where possible

* Use FastMath instead of Math

* Initialize complex things only once

* Reduce method size to aloow more JIT inlining

* remove map of short->float

* Move field to local variable

* Cleanup Map lookup

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

View File

@@ -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;

View File

@@ -19,6 +19,7 @@ import io.github.dsheirer.buffer.FloatAveragingBuffer;
import io.github.dsheirer.dsp.mixer.IOscillator;
import io.github.dsheirer.dsp.mixer.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"));

View File

@@ -18,6 +18,7 @@ package io.github.dsheirer.dsp.am;
import io.github.dsheirer.sample.buffer.ReusableBufferQueue;
import io.github.dsheirer.sample.buffer.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;
}
/**

View File

@@ -26,6 +26,7 @@ import io.github.dsheirer.dsp.filter.design.FilterDesignException;
import io.github.dsheirer.dsp.filter.fir.FIRFilterSpecification;
import io.github.dsheirer.dsp.filter.fir.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)

View File

@@ -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" );
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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
}

View File

@@ -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));
}
/**

View File

@@ -38,6 +38,7 @@ import io.github.dsheirer.source.tuner.TunerController;
import io.github.dsheirer.source.tuner.channel.ChannelSpecification;
import io.github.dsheirer.source.tuner.channel.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)
{

View File

@@ -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()

View File

@@ -17,6 +17,7 @@ package io.github.dsheirer.dsp.filter.channelizer;
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.sample.buffer.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

View File

@@ -29,6 +29,7 @@ import io.github.dsheirer.sample.buffer.ReusableComplexBufferAssembler;
import io.github.dsheirer.sample.complex.ComplexSampleListener;
import io.github.dsheirer.sample.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()

View File

@@ -28,6 +28,7 @@ import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
import io.github.dsheirer.sample.decimator.RealDecimator;
import io.github.dsheirer.sample.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.
*/

View File

@@ -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);

View File

@@ -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])));
}

View File

@@ -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);
}
/**

View File

@@ -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;

View File

@@ -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

View File

@@ -2,6 +2,7 @@ package io.github.dsheirer.dsp.filter.fir.remez;
import io.github.dsheirer.dsp.filter.design.FilterDesignException;
import io.github.dsheirer.dsp.filter.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:

View File

@@ -20,6 +20,7 @@ package io.github.dsheirer.dsp.filter.fir.remez;
import io.github.dsheirer.dsp.filter.design.FilterDesignException;
import io.github.dsheirer.dsp.filter.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:

View File

@@ -21,6 +21,7 @@ package io.github.dsheirer.dsp.filter.fir.remez;
import io.github.dsheirer.dsp.filter.design.FilterDesignException;
import io.github.dsheirer.dsp.filter.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:

View File

@@ -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
{

View File

@@ -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 )

View File

@@ -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));

View File

@@ -21,6 +21,7 @@ import io.github.dsheirer.sample.buffer.ReusableBufferQueue;
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.sample.buffer.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;

View File

@@ -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];
}

View File

@@ -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;
}

View File

@@ -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));
}
}

View File

@@ -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 ) );
}

View File

@@ -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);
}
/**

View File

@@ -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);
}
}

View File

@@ -26,6 +26,7 @@ import io.github.dsheirer.dsp.psk.pll.IPhaseLockedLoop;
import io.github.dsheirer.sample.Listener;
import io.github.dsheirer.sample.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);
}

View File

@@ -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;

View File

@@ -26,6 +26,7 @@ import io.github.dsheirer.dsp.psk.pll.IPhaseLockedLoop;
import io.github.dsheirer.sample.Listener;
import io.github.dsheirer.sample.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);
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);
}
}

View File

@@ -23,6 +23,7 @@ package io.github.dsheirer.dsp.psk;
import io.github.dsheirer.sample.complex.Complex;
import io.github.dsheirer.sample.complex.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);
}

View File

@@ -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 )
{

View File

@@ -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)
{

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);
}
}