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,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 );
}
}
}

View 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;
}
}

View 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
View 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;
}
}

View 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
View 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
View 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 );
}

View 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 ) );
}
}

View 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;
}
}

View 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 );
}

View 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;
}
}

View 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() ) );
}
}

View 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 ] );
}
}

View 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 );
}
}