/*******************************************************************************
* 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 instrument.tap.stream;
import gui.SDRTrunk;
import instrument.gui.SampleModel;
import instrument.tap.Tap;
import instrument.tap.TapViewPanel;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import java.util.List;
import java.util.Observable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sample.complex.Complex;
public class ComplexSampleTapViewPanel extends TapViewPanel
{
private static final long serialVersionUID = 1L;
private final static Logger mLog = LoggerFactory.getLogger( SDRTrunk.class );
private Tap mTap;
private List<Complex> mSamples;
private int mSampleCount;
public ComplexSampleTapViewPanel( ComplexSampleTap tap )
{
super( new SampleModel<ComplexTap>(), tap.getName() );
setSize( new Dimension( 400, 400 ) );
mTap = tap;
mTap.addListener( getModel() );
mSampleCount = (int)( 2000 * tap.getSampleRateRatio() );
getModel().setSampleCount( mSampleCount );
getModel().setDelay( tap.getDelay() );
mLog.info( "Complex Tap Panel [" + tap.getName() + "] count: " +
getModel().getSampleCount() + " delay:" + getModel().getDelay() );
}
@Override
public void update( Observable arg0, Object arg1 )
{
mSamples = (List<Complex>)getModel().getSamples();
repaint();
}
public void paintComponent( Graphics g )
{
super.paintComponent( g );
Graphics2D g2 = (Graphics2D)g;
int height = getHeight();
int width = getWidth();
g2.setColor( Color.DARK_GRAY );
float middle = (float)height / 4.0f;
g2.drawLine( 0, (int)middle, width, (int)middle );
g2.drawLine( 0, (int)( 3 * middle ), width, (int)( 3 * middle ) );
if( mSamples != null &&
mSamples.size() > 0 )
{
g2.setColor( getForeground() );
g2.drawString( mLabel, 5 , 15 );
Path2D.Float polylineReal =
new Path2D.Float( Path2D.Float.WIND_EVEN_ODD, mSamples.size() );
Path2D.Float polylineImag =
new Path2D.Float( Path2D.Float.WIND_EVEN_ODD, mSamples.size() );
/* Move to the first point */
Point2D.Float firstReal = resolve( 0, mSamples.get( 0 ), Type.REAL );
polylineReal.moveTo( firstReal.x, firstReal.y );
Point2D.Float firstImag = resolve( 0, mSamples.get( 0 ), Type.IMAGINERY );
polylineImag.moveTo( firstImag.x, firstImag.y );
for( int x = 1; x < mSamples.size(); x++ )
{
Point2D.Float pointReal = resolve( x, mSamples.get( x ), Type.REAL );
polylineReal.lineTo( pointReal.x, pointReal.y );
Point2D.Float pointImag = resolve( x, mSamples.get( x ), Type.IMAGINERY );
polylineImag.lineTo( pointImag.x, pointImag.y );
// mLog.debug( "Imag y:" + pointImag.getY() + " height:" + getHeight() );
}
g2.draw( polylineReal );
g2.draw( polylineImag );
}
g2.dispose();
}
private Point2D.Float resolve( int index, Complex sample, Type type )
{
int middle = (int)( getHeight() / 4 );
float y = middle - ( middle * mVerticalZoom * ( type == Type.REAL ?
sample.real() : sample.imaginary()) );
if( type == Type.IMAGINERY )
{
y += ( middle * 2 );
}
/* Clip y to zero as necessary */
y = ( y < 0 ) ? 0 : y;
/* Clip y to max height as necessary */
y = ( y > getHeight() ) ? getHeight() : y;
float indexWidth = (float)getWidth() / (float)mSampleCount;
float x = (float)index * indexWidth;
Point2D.Float point = new Point2D.Float( x, y );
return new Point2D.Float( x , y );
}
public enum Type{ REAL,IMAGINERY };
}