Initial code check in continued

This commit is contained in:
dennis.sheirer
2014-04-26 19:48:24 +00:00
parent 960a6f9952
commit 3dfedcf8d1
474 changed files with 76613 additions and 0 deletions

View File

@@ -0,0 +1,100 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 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.nbfm;
import sample.Listener;
import sample.complex.ComplexSample;
public class FMDiscriminator implements Listener<ComplexSample>
{
private Listener<Float> mListener;
private ComplexSample mPreviousSample = new ComplexSample( 0.0f, 0.0f );
private double mGain;
/**
* Implements a polar discriminator with ArcTangent angle estimator to
* demodulate complex sampled frequency modulated signals.
*
* @param gain - gain to be applied to the demodulated output - can be
* dynamically applied to continuously adjust audio output
*/
public FMDiscriminator( double gain )
{
mGain = gain;
}
public void dispose()
{
mListener = null;
mPreviousSample = null;
}
public synchronized void setGain( double gain )
{
mGain = gain;
}
@Override
public void receive( ComplexSample currentSample )
{
/**
* Multiply the current sample against the complex conjugate of the
* previous sample to derive the phase delta between the two samples
*
* Negating the previous sample quadrature produces the conjugate
*/
double i = ( currentSample.inphase() * mPreviousSample.inphase() ) -
( currentSample.quadrature() * -mPreviousSample.quadrature() );
double q = ( currentSample.quadrature() * mPreviousSample.inphase() ) +
( currentSample.inphase() * -mPreviousSample.quadrature() );
double angle;
//Check for divide by zero
if( i == 0 )
{
angle = 0.0;
}
else
{
/**
* Use the arcus tangent of imaginary (q) divided by real (i) to
* get the phase angle (+/-) which was directly manipulated by the
* original message waveform during the modulation. This value now
* serves as the instantaneous amplitude of the demodulated signal
*/
double denominator = 1.0d / i;
angle = Math.atan( (double)q * denominator );
}
if( mListener != null )
{
mListener.receive( (float)( angle * mGain ) );
}
/**
* Store the current sample to use during the next iteration
*/
mPreviousSample = currentSample;
}
public void setListener( Listener<Float> listener )
{
mListener = listener;
}
}

View File

@@ -0,0 +1,92 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 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.nbfm;
import sample.Broadcaster;
import sample.Listener;
import sample.complex.ComplexSample;
import dsp.filter.ComplexFIRFilter;
import dsp.filter.FilterFactory;
import dsp.filter.FloatFIRFilter;
import dsp.filter.Window.WindowType;
public class FilteringNBFMDemodulator implements Listener<ComplexSample>
{
private Broadcaster<Float> mBroadcaster = new Broadcaster<Float>();
private ComplexFIRFilter mIQFilter;
private FloatFIRFilter mAudioFilter;
private FMDiscriminator mDiscriminator;
public FilteringNBFMDemodulator( double[] iqFilter, double iqGain,
double[] audioFilter, double audioGain )
{
mIQFilter = new ComplexFIRFilter( iqFilter, iqGain );
mAudioFilter = new FloatFIRFilter( audioFilter, audioGain );
/**
* Add the FM polar discriminator with a gain of 32768, to match
* the fact that we're producing demodulated float values
*/
mDiscriminator = new FMDiscriminator( 32768 );
mIQFilter.setListener( mDiscriminator );
mDiscriminator.setListener( mAudioFilter );
mAudioFilter.setListener( mBroadcaster );
}
/**
* Implements a quadrature narrow-band demodulator that produces float
* valued demodulated, audio filtered output samples.
*/
public FilteringNBFMDemodulator()
{
this( FilterFactory.getLowPass( 48000, 4000, 6000, 48, WindowType.HAMMING, true ),
1.0002,
FilterFactory.getLowPass( 48000, 3000, 6000, 48, WindowType.HAMMING, true ),
2 );
}
/**
* Receive method for complex samples that are fed into this class to be
* processed
*/
@Override
public void receive( ComplexSample quadratureSample )
{
mIQFilter.receive( quadratureSample );
}
/**
* Adds a listener to receive demodulated samples
*/
public void addListener( Listener<Float> listener )
{
mBroadcaster.addListener( listener );
}
/**
* Removes a listener from receiving demodulated samples
*/
public void removeListener( Listener<Float> listener )
{
mBroadcaster.removeListener( listener );
}
}

View File

@@ -0,0 +1,92 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 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.nbfm;
import sample.Broadcaster;
import sample.Listener;
import sample.complex.ComplexSample;
import dsp.filter.ComplexFIRFilter;
import dsp.filter.FilterFactory;
import dsp.filter.Window.WindowType;
public class NBFMDemodulator implements Listener<ComplexSample>
{
private Broadcaster<Float> mBroadcaster = new Broadcaster<Float>();
private ComplexFIRFilter mIQFilter;
private FMDiscriminator mDiscriminator;
public NBFMDemodulator( double[] iqFilter, double iqGain )
{
mIQFilter = new ComplexFIRFilter( iqFilter, iqGain );
/**
* Add the FM polar discriminator with a gain of 32768, to match
* the fact that we're producing demodulated float values
*/
mDiscriminator = new FMDiscriminator( 32768 );
mIQFilter.setListener( mDiscriminator );
mDiscriminator.setListener( mBroadcaster );
}
public void dispose()
{
mDiscriminator.dispose();
mBroadcaster.dispose();
mIQFilter.dispose();
}
/**
* Implements a quadrature narrow-band demodulator that produces float
* valued demodulated, audio filtered output samples.
*/
public NBFMDemodulator()
{
this( FilterFactory.getLowPass( 48000, 4000, 73, WindowType.HAMMING ),
1.0002 );
}
/**
* Receive method for complex samples that are fed into this class to be
* processed
*/
@Override
public void receive( ComplexSample sample )
{
mIQFilter.receive( sample );
}
/**
* Adds a listener to receive demodulated samples
*/
public void addListener( Listener<Float> listener )
{
mBroadcaster.addListener( listener );
}
/**
* Removes a listener from receiving demodulated samples
*/
public void removeListener( Listener<Float> listener )
{
mBroadcaster.removeListener( listener );
}
}