mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 16:47:31 -05:00
Initial code check in continued
This commit is contained in:
76
src/sample/Broadcaster.java
Normal file
76
src/sample/Broadcaster.java
Normal file
@@ -0,0 +1,76 @@
|
||||
/*******************************************************************************
|
||||
* 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 sample;
|
||||
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
/**
|
||||
* Broadcasts a received float sample to multiple listeners
|
||||
*/
|
||||
public class Broadcaster<T> implements Listener<T>
|
||||
{
|
||||
private CopyOnWriteArrayList<Listener<T>> mListeners =
|
||||
new CopyOnWriteArrayList<Listener<T>>();
|
||||
|
||||
@Override
|
||||
public void receive( T t )
|
||||
{
|
||||
broadcast( t );
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear listeners to prepare for garbage collection
|
||||
*/
|
||||
public void dispose()
|
||||
{
|
||||
mListeners.clear();
|
||||
}
|
||||
|
||||
public boolean hasListeners()
|
||||
{
|
||||
return !mListeners.isEmpty();
|
||||
}
|
||||
|
||||
public int getListenerCount()
|
||||
{
|
||||
return mListeners.size();
|
||||
}
|
||||
|
||||
public void addListener( Listener<T> listener )
|
||||
{
|
||||
mListeners.add( listener );
|
||||
}
|
||||
|
||||
public void removeListener( Listener<T> listener )
|
||||
{
|
||||
mListeners.remove( listener );
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
mListeners.clear();
|
||||
}
|
||||
|
||||
public void broadcast( T t )
|
||||
{
|
||||
for( Listener<T> listener: mListeners )
|
||||
{
|
||||
listener.receive( t );
|
||||
}
|
||||
}
|
||||
}
|
||||
36
src/sample/BufferOverflow.java
Normal file
36
src/sample/BufferOverflow.java
Normal file
@@ -0,0 +1,36 @@
|
||||
/*******************************************************************************
|
||||
* 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 sample;
|
||||
|
||||
/**
|
||||
* Buffer overflow event. Used for broadcasting overflow events to listeners.
|
||||
*/
|
||||
public class BufferOverflow
|
||||
{
|
||||
private String mSource;
|
||||
|
||||
public BufferOverflow( String source )
|
||||
{
|
||||
mSource = source;
|
||||
}
|
||||
|
||||
public String getSource()
|
||||
{
|
||||
return mSource;
|
||||
}
|
||||
}
|
||||
56
src/sample/ComplexToFloatSampleConverter.java
Normal file
56
src/sample/ComplexToFloatSampleConverter.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/*******************************************************************************
|
||||
* 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 sample;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import sample.complex.ComplexSample;
|
||||
import source.mixer.MixerChannel;
|
||||
|
||||
/**
|
||||
* Receives complex samples and send either the left channel or the right
|
||||
* channel to the short sample listener
|
||||
*/
|
||||
public class ComplexToFloatSampleConverter implements Listener<List<ComplexSample>>
|
||||
{
|
||||
private MixerChannel mChannel;
|
||||
private Listener<Float> mListener;
|
||||
|
||||
public ComplexToFloatSampleConverter( Listener<Float> listener,
|
||||
MixerChannel channel )
|
||||
{
|
||||
mListener = listener;
|
||||
mChannel = channel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive( List<ComplexSample> samples )
|
||||
{
|
||||
for( ComplexSample sample: samples )
|
||||
{
|
||||
mListener.receive( mChannel == MixerChannel.LEFT ?
|
||||
sample.left() :
|
||||
sample.right() );
|
||||
}
|
||||
}
|
||||
|
||||
public Listener<Float> getListener()
|
||||
{
|
||||
return mListener;
|
||||
}
|
||||
}
|
||||
70
src/sample/Decimator.java
Normal file
70
src/sample/Decimator.java
Normal file
@@ -0,0 +1,70 @@
|
||||
/*******************************************************************************
|
||||
* 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 sample;
|
||||
|
||||
|
||||
public class Decimator<T> implements Listener<T>
|
||||
{
|
||||
private int mDecimationFactor;
|
||||
private int mDecimationPointer = 0;
|
||||
private Listener<T> mListener;
|
||||
|
||||
/**
|
||||
* Constructs the class to consume samples and decimate them by the
|
||||
* DECIMATIONFACTOR.
|
||||
*
|
||||
* @param decimationFactor - number of samples to decimate. Provides one
|
||||
* sample to registered listeners and discards the next decimationFactor - 1
|
||||
* samples.
|
||||
*/
|
||||
public Decimator( int decimationFactor )
|
||||
{
|
||||
mDecimationFactor = decimationFactor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Receives and broadcasts a sample and then discards the next
|
||||
* decimationFactor -1 samples
|
||||
*/
|
||||
public void receive( T t )
|
||||
{
|
||||
if( mDecimationPointer == 0 )
|
||||
{
|
||||
if( mListener != null )
|
||||
{
|
||||
mListener.receive( t );
|
||||
}
|
||||
}
|
||||
|
||||
mDecimationPointer++;
|
||||
|
||||
//Reset the decimation pointer once it equals the decimation factor
|
||||
if( mDecimationPointer == mDecimationFactor )
|
||||
{
|
||||
mDecimationPointer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a sample listener to receive samples
|
||||
*/
|
||||
public void setListener( Listener<T> listener )
|
||||
{
|
||||
mListener = listener;
|
||||
}
|
||||
}
|
||||
60
src/sample/FloatArrayToComplexAdapter.java
Normal file
60
src/sample/FloatArrayToComplexAdapter.java
Normal file
@@ -0,0 +1,60 @@
|
||||
/*******************************************************************************
|
||||
* 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 sample;
|
||||
|
||||
import sample.complex.ComplexSample;
|
||||
|
||||
public class FloatArrayToComplexAdapter implements Listener<Float[]>
|
||||
{
|
||||
private Listener<ComplexSample> mListener;
|
||||
|
||||
@Override
|
||||
public void receive( Float[] samples )
|
||||
{
|
||||
if( samples != null )
|
||||
{
|
||||
for( int x = 0; x < samples.length; x += 2 )
|
||||
{
|
||||
if( mListener != null &&
|
||||
samples[ x ] != null &&
|
||||
samples[ x + 1 ] != null )
|
||||
{
|
||||
mListener.receive( new ComplexSample( samples[ x ],
|
||||
samples[ x + 1 ] ) );
|
||||
}
|
||||
}
|
||||
|
||||
samples = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setListener( Listener<ComplexSample> listener )
|
||||
{
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
public void removeListener( Listener<ComplexSample> listener )
|
||||
{
|
||||
mListener = null;
|
||||
}
|
||||
|
||||
public void dispose()
|
||||
{
|
||||
mListener = null;
|
||||
}
|
||||
}
|
||||
23
src/sample/Listener.java
Normal file
23
src/sample/Listener.java
Normal file
@@ -0,0 +1,23 @@
|
||||
/*******************************************************************************
|
||||
* 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 sample;
|
||||
|
||||
public interface Listener<T>
|
||||
{
|
||||
public void receive( T t );
|
||||
}
|
||||
25
src/sample/Provider.java
Normal file
25
src/sample/Provider.java
Normal file
@@ -0,0 +1,25 @@
|
||||
/*******************************************************************************
|
||||
* 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 sample;
|
||||
|
||||
public interface Provider<T>
|
||||
{
|
||||
public void setListener( Listener<T> listener );
|
||||
|
||||
public void removeListener( Listener<T> listener );
|
||||
}
|
||||
225
src/sample/complex/ComplexSample.java
Normal file
225
src/sample/complex/ComplexSample.java
Normal file
@@ -0,0 +1,225 @@
|
||||
/*******************************************************************************
|
||||
* 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 sample.complex;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import log.Log;
|
||||
|
||||
/**
|
||||
* ComplexSample for handling left/right channel audio, or inphase/quadrature
|
||||
* samples, etc.
|
||||
*/
|
||||
public class ComplexSample implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private float mLeft;
|
||||
private float mRight;
|
||||
|
||||
public ComplexSample( float left, float right )
|
||||
{
|
||||
mLeft = left;
|
||||
mRight = right;
|
||||
}
|
||||
|
||||
public static void main( String[] args )
|
||||
{
|
||||
Log.info( "Starting ... " );
|
||||
|
||||
int frequency = 15000;
|
||||
int sampleRate = 2000000;
|
||||
|
||||
float anglePerSample = (float)( 2.0d * Math.PI * (float)frequency / (float)sampleRate );
|
||||
|
||||
ComplexSample current = new ComplexSample( 0.0f, -1.0f );
|
||||
|
||||
ComplexSample stepPerSample = ComplexSample.fromAngle( anglePerSample );
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
for( int x = 0; x < sampleRate; x++ )
|
||||
{
|
||||
// Log.info( x + " " + current.toString() );
|
||||
current.multiply( stepPerSample );
|
||||
current.fastNormalize();
|
||||
}
|
||||
|
||||
Log.info( "Elapsed: " + ( System.currentTimeMillis() - start ) );
|
||||
|
||||
Log.info( "Finished!" );
|
||||
}
|
||||
|
||||
public ComplexSample copy()
|
||||
{
|
||||
return new ComplexSample( mLeft, mRight );
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "I:" + mLeft + " Q:" + mRight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new sample representing the conjugate of this one
|
||||
*/
|
||||
public ComplexSample conjugate()
|
||||
{
|
||||
return new ComplexSample( mLeft, -mRight );
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies this sample by the scalor value
|
||||
*/
|
||||
public void multiply( float scalor )
|
||||
{
|
||||
mLeft *= scalor;
|
||||
mRight *= scalor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies this sample by the multiplier sample
|
||||
*/
|
||||
public void multiply( ComplexSample multiplier )
|
||||
{
|
||||
float inphase = ( inphase() * multiplier.inphase() ) -
|
||||
( quadrature() * multiplier.quadrature() );
|
||||
|
||||
float quadrature = ( quadrature() * multiplier.inphase() ) +
|
||||
( inphase() * multiplier.quadrature() );
|
||||
|
||||
mLeft = inphase;
|
||||
mRight = quadrature;
|
||||
}
|
||||
|
||||
public static ComplexSample multiply( ComplexSample sample1,
|
||||
ComplexSample sample2 )
|
||||
{
|
||||
float inphase = ( sample1.inphase() * sample2.inphase() ) -
|
||||
( sample1.quadrature() * sample2.quadrature() );
|
||||
|
||||
float quadrature = ( sample1.quadrature() * sample2.inphase() ) +
|
||||
( sample1.inphase() * sample2.quadrature() );
|
||||
|
||||
return new ComplexSample( inphase, quadrature );
|
||||
}
|
||||
|
||||
public static ComplexSample multiply( ComplexSample sample,
|
||||
Float left, Float right )
|
||||
{
|
||||
float l = ( sample.left() * left ) - ( sample.right() * right );
|
||||
float r = ( sample.right() * left ) + ( sample.left() * right );
|
||||
|
||||
return new ComplexSample( l, r );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the adder sample values to this sample
|
||||
*/
|
||||
public void add( ComplexSample adder )
|
||||
{
|
||||
mLeft += adder.left();
|
||||
mRight += adder.right();
|
||||
}
|
||||
|
||||
/**
|
||||
* Magnitude of this sample
|
||||
*/
|
||||
public float magnitude()
|
||||
{
|
||||
return (float)Math.sqrt( magnitudeSquared() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Magnitude squared of this sample
|
||||
*/
|
||||
public float magnitudeSquared()
|
||||
{
|
||||
return (float)( ( inphase() * inphase() ) +
|
||||
( quadrature() * quadrature() ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the vector length to 1 (unit circle)
|
||||
*/
|
||||
public void normalize()
|
||||
{
|
||||
multiply( (float)( 1.0f / magnitude() ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the vector length to 1 (unit circle),
|
||||
* avoiding square root multiplication
|
||||
*/
|
||||
public void fastNormalize()
|
||||
{
|
||||
multiply( (float)( 1.95f - magnitudeSquared() ) );
|
||||
}
|
||||
|
||||
public float left()
|
||||
{
|
||||
return mLeft;
|
||||
}
|
||||
|
||||
public float right()
|
||||
{
|
||||
return mRight;
|
||||
}
|
||||
|
||||
public float inphase()
|
||||
{
|
||||
return mLeft;
|
||||
}
|
||||
|
||||
public float quadrature()
|
||||
{
|
||||
return mRight;
|
||||
}
|
||||
|
||||
public float x()
|
||||
{
|
||||
return mLeft;
|
||||
}
|
||||
|
||||
public float y()
|
||||
{
|
||||
return mRight;
|
||||
}
|
||||
|
||||
public float real()
|
||||
{
|
||||
return mLeft;
|
||||
}
|
||||
|
||||
public float imaginery()
|
||||
{
|
||||
return mRight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new complex sample representing the angle with unit circle
|
||||
* magnitude
|
||||
* @param angle in radians
|
||||
* @return
|
||||
*/
|
||||
public static ComplexSample fromAngle( float angle )
|
||||
{
|
||||
return new ComplexSample( (float)Math.cos( angle ),
|
||||
(float)Math.sin( angle ) );
|
||||
}
|
||||
}
|
||||
72
src/sample/complex/ComplexSampleAssembler.java
Normal file
72
src/sample/complex/ComplexSampleAssembler.java
Normal file
@@ -0,0 +1,72 @@
|
||||
/*******************************************************************************
|
||||
* 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 sample.complex;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import sample.Listener;
|
||||
import sample.Provider;
|
||||
|
||||
public class ComplexSampleAssembler implements Listener<ComplexSample>,
|
||||
Provider<List<ComplexSample>>
|
||||
{
|
||||
private ArrayList mBuffer;
|
||||
private int mBufferSize;
|
||||
private Listener<List<ComplexSample>> mListener;
|
||||
|
||||
public ComplexSampleAssembler( int bufferSize )
|
||||
{
|
||||
mBufferSize = bufferSize;
|
||||
mBuffer = new ArrayList<ComplexSample>();
|
||||
}
|
||||
|
||||
public void dispose()
|
||||
{
|
||||
mBuffer.clear();
|
||||
mListener = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive( ComplexSample sample )
|
||||
{
|
||||
mBuffer.add( sample );
|
||||
|
||||
if( mBuffer.size() >= mBufferSize )
|
||||
{
|
||||
if( mListener != null )
|
||||
{
|
||||
mListener.receive( mBuffer );
|
||||
}
|
||||
|
||||
mBuffer = new ArrayList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setListener( Listener<List<ComplexSample>> listener )
|
||||
{
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener( Listener<List<ComplexSample>> listener )
|
||||
{
|
||||
mListener = null;
|
||||
}
|
||||
}
|
||||
25
src/sample/complex/ComplexSampleListListener.java
Normal file
25
src/sample/complex/ComplexSampleListListener.java
Normal file
@@ -0,0 +1,25 @@
|
||||
/*******************************************************************************
|
||||
* 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 sample.complex;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ComplexSampleListListener
|
||||
{
|
||||
public void receive( List<ComplexSample> samples );
|
||||
}
|
||||
107
src/sample/complex/ComplexSampleRateCounter.java
Normal file
107
src/sample/complex/ComplexSampleRateCounter.java
Normal file
@@ -0,0 +1,107 @@
|
||||
/*******************************************************************************
|
||||
* 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 sample.complex;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import log.Log;
|
||||
import sample.Listener;
|
||||
import source.tuner.FrequencyChangeListener;
|
||||
import buffer.FloatAveragingBuffer;
|
||||
|
||||
public class ComplexSampleRateCounter implements Listener<ComplexSample>,
|
||||
ComplexSampleListListener,
|
||||
FrequencyChangeListener
|
||||
{
|
||||
private int mCounter;
|
||||
private int mAverageCounter;
|
||||
private int mExpectedSampleRate;
|
||||
private long mLastRun = 0;
|
||||
private int mBufferSize = 100;
|
||||
private FloatAveragingBuffer mAveragingBuffer;
|
||||
|
||||
public ComplexSampleRateCounter( int expectedSampleRate, int bufferSize )
|
||||
{
|
||||
mExpectedSampleRate = expectedSampleRate;
|
||||
mBufferSize = bufferSize;
|
||||
|
||||
mAveragingBuffer = new FloatAveragingBuffer( mBufferSize );
|
||||
|
||||
mLastRun = System.currentTimeMillis();
|
||||
|
||||
Log.info( "Complex Sample Rate Counter started ...." );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive( ComplexSample sample )
|
||||
{
|
||||
mCounter++;
|
||||
|
||||
if( mCounter >= mExpectedSampleRate )
|
||||
{
|
||||
mCounter = 0;
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
long elapsed = now - mLastRun;
|
||||
mLastRun = now;
|
||||
|
||||
float average = (float)mExpectedSampleRate * 1000.0f / (float)elapsed;
|
||||
float runningAverage = mAveragingBuffer.get( average );
|
||||
|
||||
mAverageCounter++;
|
||||
|
||||
Log.info( "Complex Sample Rate Avg " + mAverageCounter +
|
||||
" current [" + elapsed + " ms/" + average +
|
||||
" hz] average [" + runningAverage + " hz] expected [" +
|
||||
mExpectedSampleRate + " hz] over [" +
|
||||
mBufferSize + "] buffer length" );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive( List<ComplexSample> samples )
|
||||
{
|
||||
mCounter += samples.size();
|
||||
|
||||
if( mCounter >= mExpectedSampleRate )
|
||||
{
|
||||
mCounter -= mExpectedSampleRate;
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
long elapsed = now - mLastRun;
|
||||
mLastRun = now;
|
||||
|
||||
float average = (float)mExpectedSampleRate * 1000.0f / (float)elapsed;
|
||||
float runningAverage = mAveragingBuffer.get( average );
|
||||
|
||||
mAverageCounter++;
|
||||
|
||||
Log.info( "Complex Sample Rate Avg " + mAverageCounter +
|
||||
" current [" + elapsed + " ms/" + average +
|
||||
" hz] average [" + runningAverage + " hz] expected [" +
|
||||
mExpectedSampleRate + " hz] over [" +
|
||||
mBufferSize + "] buffer length" );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void frequencyChanged( int frequency, int bandwidth )
|
||||
{
|
||||
mExpectedSampleRate = bandwidth;
|
||||
}
|
||||
}
|
||||
49
src/sample/complex/ComplexSampleUtils.java
Normal file
49
src/sample/complex/ComplexSampleUtils.java
Normal file
@@ -0,0 +1,49 @@
|
||||
/*******************************************************************************
|
||||
* 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 sample.complex;
|
||||
|
||||
|
||||
public class ComplexSampleUtils
|
||||
{
|
||||
|
||||
public static ComplexSample multiply( ComplexSample a,
|
||||
ComplexSample b )
|
||||
{
|
||||
return new ComplexSample(
|
||||
( a.inphase() * b.inphase() ) - ( a.quadrature() * b.quadrature() ),
|
||||
( ( a.quadrature() * b.inphase() ) + ( a.inphase() * b.quadrature() ) ) );
|
||||
}
|
||||
|
||||
public static ComplexSample minus( ComplexSample a, ComplexSample b )
|
||||
{
|
||||
return new ComplexSample( a.inphase() - b.inphase(),
|
||||
a.quadrature() - b.quadrature() );
|
||||
}
|
||||
|
||||
public static double magnitude( ComplexSample sample )
|
||||
{
|
||||
return Math.sqrt( magnitudeSquared( sample ) );
|
||||
}
|
||||
|
||||
public static int magnitudeSquared( ComplexSample sample )
|
||||
{
|
||||
return (int)( ( sample.inphase() * sample.inphase() ) +
|
||||
( sample.quadrature() * sample.quadrature() ) );
|
||||
}
|
||||
|
||||
}
|
||||
57
src/sample/complex/RTLComplexSample.java
Normal file
57
src/sample/complex/RTLComplexSample.java
Normal file
@@ -0,0 +1,57 @@
|
||||
/*******************************************************************************
|
||||
* 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 sample.complex;
|
||||
|
||||
@Deprecated
|
||||
public class RTLComplexSample extends ComplexSample
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static float[] mValues;
|
||||
|
||||
/**
|
||||
* Creates a lookup table that converts the 8-bit valued range from 0 - 255
|
||||
* into scaled float values of -128 to 0 to 127
|
||||
*/
|
||||
static
|
||||
{
|
||||
mValues = new float[ 256 ];
|
||||
|
||||
float scale = (float)( 1.0f / 127.0f );
|
||||
|
||||
for( int x = 0; x < 256; x++ )
|
||||
{
|
||||
mValues[ x ] = (float)( x - 128 ) * scale;
|
||||
}
|
||||
|
||||
mValues[ 128 ] = 0.0000001f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a complex sample from the sample format produced by the
|
||||
* RTL-2832 chip, where the byte values run from 0 - 255, but represent
|
||||
* the value -127 to 127
|
||||
*
|
||||
* @param left
|
||||
* @param right
|
||||
*/
|
||||
public RTLComplexSample( byte left, byte right )
|
||||
{
|
||||
super( mValues[ left & 0xFF ], mValues[ right & 0xFF ] );
|
||||
}
|
||||
}
|
||||
33
src/sample/complex/ThreadKiller.java
Normal file
33
src/sample/complex/ThreadKiller.java
Normal file
@@ -0,0 +1,33 @@
|
||||
/*******************************************************************************
|
||||
* 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 sample.complex;
|
||||
|
||||
/**
|
||||
* Poison Pill class to kill a processing thread. Where a thread accepts
|
||||
* ComplexSample objects, send this class to the thread as a sentinal value
|
||||
* to kill the processing thread.
|
||||
*/
|
||||
public class ThreadKiller extends ComplexSample
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public ThreadKiller()
|
||||
{
|
||||
super( 0, 0 );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user