mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 16:47:31 -05:00
Adding real cic decimator for testing in LTR FSK demodulator
This commit is contained in:
414
src/dsp/filter/cic/RealPrimeCICDecimate.java
Normal file
414
src/dsp/filter/cic/RealPrimeCICDecimate.java
Normal file
@@ -0,0 +1,414 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2015 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
******************************************************************************/
|
||||
package dsp.filter.cic;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import dsp.filter.FilterFactory;
|
||||
import dsp.filter.Filters;
|
||||
import dsp.filter.Window.WindowType;
|
||||
import dsp.filter.fir.real.RealFIRFilter_RB_RB;
|
||||
import dsp.filter.halfband.real.HalfBandFilter_RB_RB;
|
||||
import sample.Listener;
|
||||
import sample.decimator.RealDecimator;
|
||||
import sample.real.RealBuffer;
|
||||
import sample.real.RealSampleListener;
|
||||
import sample.real.RealToRealBufferAssembler;
|
||||
|
||||
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 ArrayList<DecimatingStage> mDecimatingStages =
|
||||
new ArrayList<DecimatingStage>();
|
||||
|
||||
private DecimatingStage mFirstDecimatingStage;
|
||||
|
||||
private Output mOutput;
|
||||
|
||||
private int mOutputBufferSize = 2048;
|
||||
|
||||
/**
|
||||
* Non-Recursive Prime-Factor CIC Filter with float sample array inputs and
|
||||
* decimated float sample output.
|
||||
*
|
||||
* Implements the CIC filter described in Understanding Digital Signal
|
||||
* Processing, 3e, Lyons, on page 769. This filter is comprised of multiple
|
||||
* decimating stages each with a prime factor decimation rate. Multiple
|
||||
* stages are cascaded to achieve the overall decimation rate.
|
||||
*
|
||||
* This filter supports a maximum decimation rate of 700. This filter can
|
||||
* be adapted to higher decimation rates by adding additional prime factors
|
||||
* to the PRIMES array.
|
||||
*
|
||||
* @param decimation - overall decimation rate
|
||||
* @param order - filter order
|
||||
*/
|
||||
public RealPrimeCICDecimate( int decimation, int order, int passFrequency,
|
||||
int attenuation, WindowType windowType )
|
||||
{
|
||||
this( decimation, order, passFrequency, attenuation, windowType, 2048 );
|
||||
}
|
||||
|
||||
public RealPrimeCICDecimate( int decimation, int order, int passFrequency,
|
||||
int attenuation, WindowType windowType, int outputBufferSize )
|
||||
{
|
||||
assert( decimation <= 700 );
|
||||
|
||||
mOutputBufferSize = outputBufferSize;
|
||||
|
||||
List<Integer> stageSizes = getPrimeFactors( decimation );
|
||||
|
||||
for( int x = 0; x < stageSizes.size(); x++ )
|
||||
{
|
||||
DecimatingStage stage = new DecimatingStage( stageSizes.get( x ), order );
|
||||
|
||||
mDecimatingStages.add( stage );
|
||||
|
||||
if( x == 0 )
|
||||
{
|
||||
/* Reference to first stage -- will receive all samples */
|
||||
mFirstDecimatingStage = stage;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Wire the current stage to the previous stage */
|
||||
mDecimatingStages.get( x - 1 ).setListener( stage );
|
||||
}
|
||||
}
|
||||
|
||||
mOutput = new Output( 48000, passFrequency, attenuation, windowType,
|
||||
outputBufferSize );
|
||||
|
||||
mDecimatingStages.get( mDecimatingStages.size() - 1 )
|
||||
.setListener( mOutput );
|
||||
}
|
||||
|
||||
public void dispose()
|
||||
{
|
||||
for( DecimatingStage stage: mDecimatingStages )
|
||||
{
|
||||
stage.dispose();
|
||||
}
|
||||
|
||||
mDecimatingStages.clear();
|
||||
mDecimatingStages = null;
|
||||
mFirstDecimatingStage = null;
|
||||
|
||||
mOutput.dispose();
|
||||
mOutput = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a listener to receive the output of this CIC decimation filter
|
||||
*/
|
||||
public void setListener( Listener<RealBuffer> listener )
|
||||
{
|
||||
mOutput.setListener( listener );
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes listener from output of this CIC decimation filter
|
||||
*/
|
||||
public void removeListener()
|
||||
{
|
||||
mOutput.removeListener();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the prime factors of the decimation rate up to a maximum
|
||||
* decimation rate of 700. If you wish to have decimation rates higher
|
||||
* than 700, then add additional prime factors to the PRIMES array.
|
||||
*
|
||||
* @param decimation - integral decimation rate
|
||||
* @return - ordered list (smallest to largest) of prime factors
|
||||
*/
|
||||
public static List<Integer> getPrimeFactors( int decimation )
|
||||
{
|
||||
ArrayList<Integer> stages = new ArrayList<Integer>();
|
||||
|
||||
int pointer = 0;
|
||||
|
||||
while( decimation > 0 && pointer < PRIMES.length )
|
||||
{
|
||||
int prime = PRIMES[ pointer ];
|
||||
|
||||
if( decimation % prime == 0 )
|
||||
{
|
||||
stages.add( prime );
|
||||
|
||||
decimation /= prime;
|
||||
}
|
||||
else
|
||||
{
|
||||
pointer++;
|
||||
}
|
||||
}
|
||||
|
||||
return stages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Primary input method for receiving real buffers.
|
||||
*/
|
||||
public void receive( RealBuffer buffer )
|
||||
{
|
||||
if( mFirstDecimatingStage != null )
|
||||
{
|
||||
for( float sample: buffer.getSamples() )
|
||||
{
|
||||
mFirstDecimatingStage.receive( sample );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decimating stage combines multiple CIC stages with a decimator. The
|
||||
* number of stages is indicated by the order value and the size indicates
|
||||
* the decimation rate of this stage.
|
||||
*/
|
||||
public class DecimatingStage implements RealSampleListener
|
||||
{
|
||||
private ArrayList<Stage> mStages = new ArrayList<Stage>();
|
||||
private Stage mFirstStage;
|
||||
private RealDecimator mDecimator;
|
||||
|
||||
public DecimatingStage( int size, int order )
|
||||
{
|
||||
for( int x = 0; x < order; x++ )
|
||||
{
|
||||
Stage stage;
|
||||
|
||||
if( size == 2 )
|
||||
{
|
||||
stage = new TwoStage();
|
||||
}
|
||||
else
|
||||
{
|
||||
stage = new Stage( size );
|
||||
}
|
||||
|
||||
mStages.add( stage );
|
||||
|
||||
if( x == 0 )
|
||||
{
|
||||
mFirstStage = stage;
|
||||
}
|
||||
else
|
||||
{
|
||||
mStages.get( x - 1 ).setListener( stage );
|
||||
}
|
||||
}
|
||||
|
||||
mDecimator = new RealDecimator( size );
|
||||
|
||||
mStages.get( mStages.size() - 1 ).setListener( mDecimator );
|
||||
}
|
||||
|
||||
public void dispose()
|
||||
{
|
||||
for( Stage stage: mStages )
|
||||
{
|
||||
stage.dispose();
|
||||
}
|
||||
|
||||
mStages.clear();
|
||||
mDecimator.dispose();
|
||||
mDecimator = null;
|
||||
mFirstStage = null;
|
||||
mStages = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive( float sample )
|
||||
{
|
||||
mFirstStage.receive( sample );
|
||||
}
|
||||
|
||||
public void setListener( RealSampleListener listener )
|
||||
{
|
||||
mDecimator.setListener( listener );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Single non-decimating CIC stage component. Uses a circular buffer and a
|
||||
* running average internally to implement the stage so that stage size has
|
||||
* essentially no impact on the computational requirements of the stage
|
||||
*/
|
||||
public class Stage implements RealSampleListener
|
||||
{
|
||||
protected RealSampleListener mListener;
|
||||
|
||||
private float[] mSamples;
|
||||
|
||||
protected float mSum;
|
||||
|
||||
private int mSamplePointer = 0;
|
||||
private int mSize;
|
||||
|
||||
protected float mGain;
|
||||
|
||||
public Stage()
|
||||
{
|
||||
}
|
||||
|
||||
public Stage( int size )
|
||||
{
|
||||
mSize = size - 1;
|
||||
|
||||
mSamples = new float[ mSize ];
|
||||
|
||||
mGain = 1.0f / (float)size;
|
||||
}
|
||||
|
||||
public void dispose()
|
||||
{
|
||||
mListener = null;
|
||||
}
|
||||
|
||||
public void receive( float sample )
|
||||
{
|
||||
/* Subtract the oldest sample and add back in the newest */
|
||||
mSum = mSum - mSamples[ mSamplePointer ] + sample;
|
||||
|
||||
/* Overwrite the oldest sample with the newest */
|
||||
mSamples[ mSamplePointer ] = sample;
|
||||
|
||||
mSamplePointer++;
|
||||
|
||||
if( mSamplePointer >= mSize )
|
||||
{
|
||||
mSamplePointer = 0;
|
||||
}
|
||||
|
||||
if( mListener != null )
|
||||
{
|
||||
mListener.receive( mSum * mGain );
|
||||
}
|
||||
}
|
||||
|
||||
public void setListener( RealSampleListener listener )
|
||||
{
|
||||
mListener = listener;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Size 2 stage that removes the unnecessary circular buffer management for
|
||||
* a two-stage.
|
||||
*/
|
||||
public class TwoStage extends Stage
|
||||
{
|
||||
public TwoStage()
|
||||
{
|
||||
super();
|
||||
|
||||
mGain = 0.5f;
|
||||
}
|
||||
|
||||
public void receive( float sample )
|
||||
{
|
||||
float sum = mSum + sample;
|
||||
|
||||
mSum = sample;
|
||||
|
||||
if( mListener != null )
|
||||
{
|
||||
mListener.receive( sum * mGain );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Output adapter - applies gain correction, applies cleanup filter, casts
|
||||
* double-valued samples into float-valued complex sample and sends the
|
||||
* result to the registered listener.
|
||||
*/
|
||||
public class Output implements RealSampleListener
|
||||
{
|
||||
/* Decimated output buffers will contain 1024 samples */
|
||||
private RealToRealBufferAssembler mAssembler;
|
||||
|
||||
private RealFIRFilter_RB_RB mCleanupFilter;
|
||||
private HalfBandFilter_RB_RB mHalfBandFilter = new HalfBandFilter_RB_RB(
|
||||
Filters.FIR_HALF_BAND_31T_ONE_EIGHTH_FCO.getCoefficients(), 0.4f, false );
|
||||
|
||||
public Output( int outputSampleRate, int passFrequency, int attenuation,
|
||||
WindowType windowType, int outputBufferSize )
|
||||
{
|
||||
mCleanupFilter = new RealFIRFilter_RB_RB( FilterFactory
|
||||
.getCICCleanupFilter( outputSampleRate,
|
||||
passFrequency,
|
||||
attenuation,
|
||||
windowType ), 0.4f );
|
||||
|
||||
mAssembler = new RealToRealBufferAssembler( outputBufferSize );
|
||||
mAssembler.setListener( mCleanupFilter );
|
||||
mCleanupFilter.setListener( mHalfBandFilter );
|
||||
|
||||
}
|
||||
|
||||
public void dispose()
|
||||
{
|
||||
mAssembler.dispose();
|
||||
mCleanupFilter.dispose();
|
||||
mHalfBandFilter.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Receiver method for the output adapter to receive a filtered,
|
||||
* decimated sample, apply gain correction, apply cleanup filtering
|
||||
* and output the sample values as a complex sample.
|
||||
*/
|
||||
@Override
|
||||
public void receive( float sample )
|
||||
{
|
||||
mAssembler.receive( sample * 32.0f );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a listener to receive output samples
|
||||
*/
|
||||
public void setListener( Listener<RealBuffer> listener )
|
||||
{
|
||||
mHalfBandFilter.setListener( listener );
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the listener from receiving output samples
|
||||
*/
|
||||
public void removeListener()
|
||||
{
|
||||
mHalfBandFilter.removeListener();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,29 +17,33 @@
|
||||
******************************************************************************/
|
||||
package dsp.fsk;
|
||||
|
||||
import instrument.Instrumentable;
|
||||
import instrument.tap.Tap;
|
||||
import instrument.tap.TapGroup;
|
||||
import instrument.tap.stream.BinaryTap;
|
||||
import instrument.tap.stream.FloatTap;
|
||||
import instrument.tap.stream.SymbolEventTap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import sample.Listener;
|
||||
import sample.real.RealBuffer;
|
||||
import dsp.filter.Filters;
|
||||
import dsp.filter.FloatHalfBandFilter;
|
||||
import dsp.filter.FloatHalfBandNoDecimateFilter;
|
||||
import dsp.filter.LTRPulseShapingFilter;
|
||||
import dsp.filter.SquaringFilter;
|
||||
import dsp.filter.Window.WindowType;
|
||||
import dsp.filter.cic.RealPrimeCICDecimate;
|
||||
import dsp.filter.dc.IIRSinglePoleDCRemovalFilter;
|
||||
import dsp.symbol.Slicer;
|
||||
import dsp.symbol.Slicer.Output;
|
||||
import instrument.Instrumentable;
|
||||
import instrument.tap.Tap;
|
||||
import instrument.tap.TapGroup;
|
||||
import instrument.tap.stream.BinaryTap;
|
||||
import instrument.tap.stream.FloatBufferTap;
|
||||
import instrument.tap.stream.FloatTap;
|
||||
import instrument.tap.stream.SymbolEventTap;
|
||||
import sample.Listener;
|
||||
import sample.real.RealBuffer;
|
||||
|
||||
public class LTRFSKDecoder implements Listener<RealBuffer>, Instrumentable
|
||||
{
|
||||
private RealPrimeCICDecimate mCICDecimator;
|
||||
|
||||
private FloatHalfBandFilter mHBFilter1;
|
||||
private FloatHalfBandFilter mHBFilter2;
|
||||
private FloatHalfBandFilter mHBFilter3;
|
||||
@@ -58,6 +62,7 @@ public class LTRFSKDecoder implements Listener<RealBuffer>, Instrumentable
|
||||
private final String TAP_F4_F5 = "LTR FSK Demod Filter4 >< Filter5";
|
||||
private final String TAP_F5_F6 = "LTR FSK Demod Filter5 >< Filter6";
|
||||
private final String TAP_F6_DT = "LTR FSK Demod Filter6 >< DC Filter";
|
||||
private final String TAP_CIC = "LTR FSK Demod CIC Decimator";
|
||||
private final String TAP_DT_SF1 = "LTR FSK Demod DC Filter >< Squaring Filter";
|
||||
private final String TAP_SF1_PS = "LTR FSK Demod Squaring Filter >< Pulse Shaper";
|
||||
private final String TAP_PS_SLICER = "LTR FSK Demod Pulse Shaper >< Slicer";
|
||||
@@ -69,6 +74,8 @@ public class LTRFSKDecoder implements Listener<RealBuffer>, Instrumentable
|
||||
*/
|
||||
public LTRFSKDecoder()
|
||||
{
|
||||
mCICDecimator = new RealPrimeCICDecimate( 32, 1, 375, 60, WindowType.HAMMING, 2 );
|
||||
|
||||
mHBFilter1 = new FloatHalfBandFilter(
|
||||
Filters.FIR_HALF_BAND_31T_ONE_EIGHTH_FCO, 1.1002f );
|
||||
|
||||
@@ -112,6 +119,8 @@ public class LTRFSKDecoder implements Listener<RealBuffer>, Instrumentable
|
||||
{
|
||||
mHBFilter1.receive( sample );
|
||||
}
|
||||
|
||||
mCICDecimator.receive(buffer);
|
||||
}
|
||||
|
||||
public void addListener( Listener<Boolean> listener )
|
||||
@@ -139,6 +148,7 @@ public class LTRFSKDecoder implements Listener<RealBuffer>, Instrumentable
|
||||
group.add( new FloatTap( TAP_F4_F5, 14, 0.125f ) );
|
||||
group.add( new FloatTap( TAP_F5_F6, 15, 0.0625f ) );
|
||||
group.add( new FloatTap( TAP_F6_DT, 31, 0.0625f ) );
|
||||
group.add( new FloatBufferTap( TAP_CIC, 31, 0.0625f ) );
|
||||
group.add( new FloatTap( TAP_DT_SF1, 31, 0.0625f ) );
|
||||
group.add( new BinaryTap( TAP_SF1_PS, 33, 0.0625f ) );
|
||||
group.add( new BinaryTap( TAP_PS_SLICER, 33, 0.0625f ) );
|
||||
@@ -155,6 +165,9 @@ public class LTRFSKDecoder implements Listener<RealBuffer>, Instrumentable
|
||||
{
|
||||
switch( tap.getName() )
|
||||
{
|
||||
case TAP_CIC:
|
||||
mCICDecimator.setListener( (FloatBufferTap)tap );
|
||||
break;
|
||||
case TAP_F1_F2:
|
||||
mHBFilter1.setListener( (FloatTap)tap );
|
||||
((FloatTap)tap).setListener( mHBFilter2 );
|
||||
@@ -202,6 +215,9 @@ public class LTRFSKDecoder implements Listener<RealBuffer>, Instrumentable
|
||||
{
|
||||
switch( tap.getName() )
|
||||
{
|
||||
case TAP_CIC:
|
||||
mCICDecimator.removeListener();
|
||||
break;
|
||||
case TAP_F1_F2:
|
||||
mHBFilter1.setListener( mHBFilter2 );
|
||||
break;
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
package instrument.tap.stream;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sample.Listener;
|
||||
import sample.real.RealBuffer;
|
||||
|
||||
public class FloatBufferTap extends FloatTap implements Listener<RealBuffer>
|
||||
{
|
||||
private Listener<RealBuffer> mListener;
|
||||
private final static Logger mLog =
|
||||
LoggerFactory.getLogger( FloatBufferTap.class );
|
||||
|
||||
private Listener<RealBuffer> mRealBufferListener;
|
||||
|
||||
public FloatBufferTap( String name, int delay, float sampleRateRatio )
|
||||
{
|
||||
@@ -15,24 +21,26 @@ public class FloatBufferTap extends FloatTap implements Listener<RealBuffer>
|
||||
@Override
|
||||
public void receive( RealBuffer buffer )
|
||||
{
|
||||
if( mListener != null )
|
||||
mLog.debug("Got a buffer!");
|
||||
if( mRealBufferListener != null )
|
||||
{
|
||||
mListener.receive( buffer );
|
||||
mRealBufferListener.receive( buffer );
|
||||
}
|
||||
|
||||
for( float sample: buffer.getSamples() )
|
||||
{
|
||||
receive( sample );
|
||||
mLog.debug("Sending a sample to the tap");
|
||||
super.receive( sample );
|
||||
}
|
||||
}
|
||||
|
||||
public void setListener( Listener<RealBuffer> listener )
|
||||
{
|
||||
mListener = listener;
|
||||
mRealBufferListener = listener;
|
||||
}
|
||||
|
||||
public void removeListener( Listener<RealBuffer> listener )
|
||||
{
|
||||
mListener = null;
|
||||
mRealBufferListener = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import sample.real.RealSampleListener;
|
||||
|
||||
public class FloatTap extends StreamTap implements RealSampleListener
|
||||
{
|
||||
private RealSampleListener mListener;
|
||||
private RealSampleListener mFloatTapListener;
|
||||
|
||||
public FloatTap( String name,
|
||||
int delay,
|
||||
@@ -35,9 +35,9 @@ public class FloatTap extends StreamTap implements RealSampleListener
|
||||
@Override
|
||||
public void receive( float sample )
|
||||
{
|
||||
if( mListener != null )
|
||||
if( mFloatTapListener != null )
|
||||
{
|
||||
mListener.receive( sample );
|
||||
mFloatTapListener.receive( sample );
|
||||
}
|
||||
|
||||
for( TapListener listener: mListeners )
|
||||
@@ -48,11 +48,11 @@ public class FloatTap extends StreamTap implements RealSampleListener
|
||||
|
||||
public void setListener( RealSampleListener listener )
|
||||
{
|
||||
mListener = listener;
|
||||
mFloatTapListener = listener;
|
||||
}
|
||||
|
||||
public void removeListener( RealSampleListener listener )
|
||||
{
|
||||
mListener = null;
|
||||
mFloatTapListener = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package sample.decimator;
|
||||
|
||||
import sample.complex.ComplexSampleListener;
|
||||
import sample.real.RealSampleListener;
|
||||
|
||||
|
||||
public class RealDecimator implements ComplexSampleListener
|
||||
public class RealDecimator implements RealSampleListener
|
||||
{
|
||||
private ComplexSampleListener mListener;
|
||||
private RealSampleListener mListener;
|
||||
private int mCounter = 0;
|
||||
private int mDecimationRate;
|
||||
|
||||
@@ -36,13 +36,13 @@ public class RealDecimator implements ComplexSampleListener
|
||||
* to the registered listener
|
||||
*/
|
||||
@Override
|
||||
public void receive( float i, float q )
|
||||
public void receive( float sample )
|
||||
{
|
||||
mCounter++;
|
||||
|
||||
if( mCounter >= mDecimationRate )
|
||||
{
|
||||
mListener.receive( i, q );
|
||||
mListener.receive( sample );
|
||||
|
||||
mCounter = 0;
|
||||
}
|
||||
@@ -51,7 +51,7 @@ public class RealDecimator implements ComplexSampleListener
|
||||
/**
|
||||
* Sets the decimated output listener
|
||||
*/
|
||||
public void setListener( ComplexSampleListener listener )
|
||||
public void setListener( RealSampleListener listener )
|
||||
{
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user