330 WIP - updates the demodulator viewer with an eye diagram and symbol

chart.  Testing various configurations to see which yields the best
PLL and symbol timing locks.
This commit is contained in:
Denny
2018-02-18 16:20:45 -05:00
parent eaf7c7d11e
commit dda37a1198
20 changed files with 844 additions and 279 deletions

View File

@@ -1,78 +1,103 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014,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 io.github.dsheirer.dsp.fm;
import io.github.dsheirer.sample.complex.Complex;
public abstract class FMDemodulator
{
private float mPreviousI = 0.0f;
private float mPreviousQ = 0.0f;
protected float mGain;
private float mPreviousI = 0.0f;
private float mPreviousQ = 0.0f;
protected float mGain;
public FMDemodulator( float gain )
{
mGain = gain;
}
public FMDemodulator(float gain)
{
mGain = gain;
}
public float demodulate( float currentI, float currentQ )
{
/**
* 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 inphase = ( currentI * mPreviousI ) - ( currentQ * -mPreviousQ );
double quadrature = ( currentQ * mPreviousI ) + ( currentI * -mPreviousQ );
double angle = 0.0f;
//Check for divide by zero
if( inphase != 0 )
{
/**
* Use the arc-tangent of quadrature divided by inphase 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 / inphase;
angle = Math.atan( (double)quadrature * denominator );
}
/**
* Store the current sample to use during the next iteration
*/
mPreviousI = currentI;
mPreviousQ = currentQ;
return (float)( angle * mGain );
}
public float demodulate(float currentI, float currentQ)
{
/**
* 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 inphase = (currentI * mPreviousI) - (currentQ * -mPreviousQ);
double quadrature = (currentQ * mPreviousI) + (currentI * -mPreviousQ);
public abstract void dispose();
double angle = 0.0f;
public void reset()
{
mPreviousI = 0.0f;
mPreviousQ = 0.0f;
}
//Check for divide by zero
if(inphase != 0)
{
/**
* Use the arc-tangent of quadrature divided by inphase 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 / inphase;
angle = Math.atan((double)quadrature * denominator);
}
public void setGain( float gain )
{
mGain = gain;
}
/**
* Store the current sample to use during the next iteration
*/
mPreviousI = currentI;
mPreviousQ = currentQ;
return (float)(angle * mGain);
}
public static double demodulate(Complex previous, Complex current)
{
double inphase = (current.inphase() * previous.inphase()) - (current.quadrature() * -previous.quadrature());
double quadrature = (current.quadrature() * previous.inphase()) + (current.inphase() * -previous.quadrature());
double angle = 0.0f;
//Check for divide by zero
if(inphase != 0)
{
/**
* Use the arc-tangent of quadrature divided by inphase 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 / inphase;
angle = Math.atan((double)quadrature * denominator);
}
return angle;
}
public abstract void dispose();
public void reset()
{
mPreviousI = 0.0f;
mPreviousQ = 0.0f;
}
public void setGain(float gain)
{
mGain = gain;
}
}

View File

@@ -26,8 +26,7 @@ import org.slf4j.LoggerFactory;
public class FMDemodulator_CB extends FMDemodulator implements Listener<ComplexBuffer>
{
private final static Logger mLog =
LoggerFactory.getLogger( FMDemodulator_CB.class );
private final static Logger mLog = LoggerFactory.getLogger( FMDemodulator_CB.class );
private Listener<RealBuffer> mListener;