mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-13 00:57:31 -05:00
wip: adds filter viewer JavaFX utility application for visualizing
filters designed through the filter factory.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014,2015 Dennis Sheirer
|
||||
* Copyright (C) 2014-2016,2015 Dennis Sheirer
|
||||
*
|
||||
* Root Raised Cosine filter designer:
|
||||
* Copyright 2002,2007,2008,2012,2013 Free Software Foundation, Inc.
|
||||
@@ -35,9 +35,46 @@ import dsp.filter.cic.ComplexPrimeCICDecimate;
|
||||
|
||||
public class FilterFactory
|
||||
{
|
||||
private final static Logger mLog =
|
||||
LoggerFactory.getLogger( FilterFactory.class );
|
||||
private final static Logger mLog = LoggerFactory.getLogger( FilterFactory.class );
|
||||
|
||||
public static final double TWO_PI = Math.pow( Math.PI, 2.0 );
|
||||
|
||||
public static float[] getNewLowPass( int sampleRate, long passFrequency, long stopFrequency,
|
||||
int attenuation, WindowType window )
|
||||
{
|
||||
assert( passFrequency <= sampleRate / 2 );
|
||||
|
||||
int length = getTapCount( sampleRate, passFrequency, stopFrequency, attenuation );
|
||||
|
||||
if( length % 2 == 0 )
|
||||
{
|
||||
length++;
|
||||
}
|
||||
|
||||
float[] coefficients = new float[ length ];
|
||||
|
||||
int half = length / 2;
|
||||
|
||||
int K = (int)( length * ( 2.0d * (double)passFrequency / (double) sampleRate ));
|
||||
|
||||
double scale = 1.0 / (double)length;
|
||||
|
||||
coefficients[ half ] = (float)( K / (double)length );
|
||||
|
||||
for( int k = 1; k <= half; k++ )
|
||||
{
|
||||
float coefficient = (float)( scale * ( Math.sin( Math.PI * k * K / length ) /
|
||||
Math.sin( Math.PI * k / length ) ) );
|
||||
|
||||
coefficients[ k + half ] = coefficient;
|
||||
coefficients[ half - k ] = coefficient;
|
||||
}
|
||||
|
||||
Window.apply( WindowType.HANNING, coefficients );
|
||||
|
||||
return coefficients;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates coefficients for a unity-gain, windowed low-pass filter
|
||||
* @param sampleRate - hertz
|
||||
@@ -78,6 +115,7 @@ public class FilterFactory
|
||||
}
|
||||
|
||||
//Apply the window against the coefficients
|
||||
|
||||
coefficients = Window.apply( window, coefficients );
|
||||
|
||||
//Normalize to unity (1) gain
|
||||
|
||||
@@ -32,7 +32,7 @@ public class GoertzelFilter
|
||||
private int mSampleRate;
|
||||
private long mTargetFrequency;
|
||||
private int mBlockSize;
|
||||
private double[] mWindowCoefficients;
|
||||
private float[] mWindowCoefficients;
|
||||
|
||||
private double mCoefficient;
|
||||
|
||||
|
||||
@@ -19,6 +19,9 @@ package dsp.filter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Window creator
|
||||
*
|
||||
@@ -33,7 +36,9 @@ import java.util.Arrays;
|
||||
*/
|
||||
public class Window
|
||||
{
|
||||
public static double[] getWindow( WindowType type, int length )
|
||||
private final static Logger mLog = LoggerFactory.getLogger( Window.class );
|
||||
|
||||
public static float[] getWindow( WindowType type, int length )
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
@@ -51,18 +56,18 @@ public class Window
|
||||
}
|
||||
}
|
||||
|
||||
public static double[] getRectangularWindow( int length )
|
||||
public static float[] getRectangularWindow( int length )
|
||||
{
|
||||
double[] coefficients = new double[ length ];
|
||||
float[] coefficients = new float[ length ];
|
||||
|
||||
Arrays.fill( coefficients, 1.0d );
|
||||
Arrays.fill( coefficients, 1.0f );
|
||||
|
||||
return coefficients;
|
||||
}
|
||||
|
||||
public static double[] getCosineWindow( int length )
|
||||
public static float[] getCosineWindow( int length )
|
||||
{
|
||||
double[] coefficients = new double[ length ];
|
||||
float[] coefficients = new float[ length ];
|
||||
|
||||
|
||||
if( length % 2 == 0 ) //Even length
|
||||
@@ -71,7 +76,7 @@ public class Window
|
||||
|
||||
for( int x = -half; x < length / 2 + 1; x++ )
|
||||
{
|
||||
coefficients[ x + half ] = Math.cos(
|
||||
coefficients[ x + half ] = (float)Math.cos(
|
||||
( (double)x * Math.PI ) / ( (double)length + 1.0d ) );
|
||||
}
|
||||
}
|
||||
@@ -81,7 +86,7 @@ public class Window
|
||||
|
||||
for( int x = -half; x < half + 1; x++ )
|
||||
{
|
||||
coefficients[ x + half ] = Math.cos(
|
||||
coefficients[ x + half ] = (float)Math.cos(
|
||||
( (double)x * Math.PI ) / ( (double)length + 1.0d ) );
|
||||
}
|
||||
}
|
||||
@@ -89,62 +94,62 @@ public class Window
|
||||
return coefficients;
|
||||
}
|
||||
|
||||
public static double[] getBlackmanWindow( int length )
|
||||
public static float[] getBlackmanWindow( int length )
|
||||
{
|
||||
double[] coefficients = new double[ length ];
|
||||
float[] coefficients = new float[ length ];
|
||||
|
||||
for( int x = 0; x < length; x++ )
|
||||
{
|
||||
coefficients[ x ] = .426591D -
|
||||
coefficients[ x ] = (float)( .426591D -
|
||||
( .496561D * Math.cos( ( Math.PI * 2.0D * (double)x ) / (double)( length - 1 ) ) +
|
||||
( .076848D * Math.cos( ( Math.PI * 4.0D * (double)x ) / (double)( length - 1 ) ) ) );
|
||||
( .076848D * Math.cos( ( Math.PI * 4.0D * (double)x ) / (double)( length - 1 ) ) ) ) );
|
||||
}
|
||||
|
||||
return coefficients;
|
||||
}
|
||||
|
||||
public static double[] getHammingWindow( int length )
|
||||
public static float[] getHammingWindow( int length )
|
||||
{
|
||||
double[] coefficients = new double[ length ];
|
||||
float[] coefficients = new float[ length ];
|
||||
|
||||
if( length % 2 == 0 ) //Even length
|
||||
{
|
||||
for( int x = 0; x < length; x++ )
|
||||
{
|
||||
coefficients[ x ] = .54D - ( .46D *
|
||||
Math.cos( ( Math.PI * ( 2.0D * (double)x + 1.0d ) ) / (double)( length - 1 ) ) );
|
||||
coefficients[ x ] = (float)( .54D - ( .46D *
|
||||
Math.cos( ( Math.PI * ( 2.0D * (double)x + 1.0d ) ) / (double)( length - 1 ) ) ) );
|
||||
}
|
||||
}
|
||||
else //Odd length
|
||||
{
|
||||
for( int x = 0; x < length; x++ )
|
||||
{
|
||||
coefficients[ x ] = .54D - ( .46D *
|
||||
Math.cos( ( 2.0D * Math.PI * (double)x ) / (double)( length - 1 ) ) );
|
||||
coefficients[ x ] = (float)( .54D - ( .46D *
|
||||
Math.cos( ( 2.0D * Math.PI * (double)x ) / (double)( length - 1 ) ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
return coefficients;
|
||||
}
|
||||
|
||||
public static double[] getHanningWindow( int length )
|
||||
public static float[] getHanningWindow( int length )
|
||||
{
|
||||
double[] coefficients = new double[ length ];
|
||||
float[] coefficients = new float[ length ];
|
||||
|
||||
if( length % 2 == 0 ) //Even length
|
||||
{
|
||||
for( int x = 0; x < length; x++ )
|
||||
{
|
||||
coefficients[ x ] = .5D - ( .5D *
|
||||
Math.cos( ( Math.PI * ( 2.0D * (double)x + 1 ) ) / (double)( length - 1 ) ) );
|
||||
coefficients[ x ] = (float)( .5D - ( .5D *
|
||||
Math.cos( ( Math.PI * ( 2.0D * (double)x + 1 ) ) / (double)( length - 1 ) ) ) );
|
||||
}
|
||||
}
|
||||
else //Odd length
|
||||
{
|
||||
for( int x = 0; x < length; x++ )
|
||||
{
|
||||
coefficients[ x ] = .5D - ( .5D *
|
||||
Math.cos( ( 2.0D * Math.PI * (double)x ) / (double)( length - 1 ) ) );
|
||||
coefficients[ x ] = (float)( .5D - ( .5D *
|
||||
Math.cos( ( 2.0D * Math.PI * (double)x ) / (double)( length - 1 ) ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,41 +160,21 @@ public class Window
|
||||
/**
|
||||
* Apply the window against an array of float-type samples
|
||||
*/
|
||||
public static float[] apply( double[] coefficients, float[] samples )
|
||||
public static float[] apply( float[] windowCoefficients, float[] samples )
|
||||
{
|
||||
for( int x = 0; x < coefficients.length; x++ )
|
||||
for( int x = 0; x < windowCoefficients.length; x++ )
|
||||
{
|
||||
samples[ x ] = (float)( samples[ x ] * coefficients[ x ] );
|
||||
samples[ x ] = samples[ x ] * windowCoefficients[ x ];
|
||||
}
|
||||
|
||||
return samples;
|
||||
}
|
||||
|
||||
|
||||
public static float[] apply( WindowType type, float[] samples )
|
||||
{
|
||||
double[] coefficients = getWindow( type, samples.length );
|
||||
float[] windowCoefficients = getWindow( type, samples.length );
|
||||
|
||||
return apply( coefficients, samples );
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the window against an array of float-type samples
|
||||
*/
|
||||
public static double[] apply( double[] coefficients, double[] samples )
|
||||
{
|
||||
for( int x = 0; x < coefficients.length; x++ )
|
||||
{
|
||||
samples[ x ] = samples[ x ] * coefficients[ x ];
|
||||
}
|
||||
|
||||
return samples;
|
||||
}
|
||||
|
||||
public static double[] apply( WindowType type, double[] samples )
|
||||
{
|
||||
double[] coefficients = getWindow( type, samples.length );
|
||||
|
||||
return apply( coefficients, samples );
|
||||
return apply( windowCoefficients, samples );
|
||||
}
|
||||
|
||||
|
||||
@@ -205,7 +190,7 @@ public class Window
|
||||
/**
|
||||
* Utility to log the double arrays
|
||||
*/
|
||||
public static String arrayToString( double[] array, boolean breaks )
|
||||
public static String arrayToString( float[] array, boolean breaks )
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for( int x = 0; x < array.length; x++ )
|
||||
|
||||
Reference in New Issue
Block a user