mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 16:47:31 -05:00
Merge pull request #395 from DSheirer/393-raw-bitstream-recording
393 Recording raw decoded bitstream from supported decoder types
This commit is contained in:
@@ -27,7 +27,7 @@ import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.IReusableBufferListener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableAudioPacket;
|
||||
import io.github.dsheirer.sample.buffer.ReusableAudioPacketQueue;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -40,7 +40,7 @@ import org.slf4j.LoggerFactory;
|
||||
* This class is designed to support 8 kHz sample rate demodulated audio.
|
||||
*/
|
||||
public class AudioModule extends Module implements IAudioPacketProvider, IReusableBufferListener,
|
||||
ISquelchStateListener, Listener<ReusableBuffer>
|
||||
ISquelchStateListener, Listener<ReusableFloatBuffer>
|
||||
{
|
||||
protected static final Logger mLog = LoggerFactory.getLogger(AudioModule.class);
|
||||
private ReusableAudioPacketQueue mAudioPacketQueue = new ReusableAudioPacketQueue("AudioModule");
|
||||
@@ -139,11 +139,11 @@ public class AudioModule extends Module implements IAudioPacketProvider, IReusab
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ReusableBuffer reusableBuffer)
|
||||
public void receive(ReusableFloatBuffer reusableFloatBuffer)
|
||||
{
|
||||
if(mAudioPacketListener != null && mSquelchState == SquelchState.UNSQUELCH)
|
||||
{
|
||||
ReusableBuffer highPassFiltered = mHighPassFilter.filter(reusableBuffer);
|
||||
ReusableFloatBuffer highPassFiltered = mHighPassFilter.filter(reusableFloatBuffer);
|
||||
|
||||
ReusableAudioPacket audioPacket = mAudioPacketQueue.getBuffer(highPassFiltered.getSampleCount());
|
||||
audioPacket.loadAudioFrom(highPassFiltered);
|
||||
@@ -155,7 +155,7 @@ public class AudioModule extends Module implements IAudioPacketProvider, IReusab
|
||||
}
|
||||
else
|
||||
{
|
||||
reusableBuffer.decrementUserCount();
|
||||
reusableFloatBuffer.decrementUserCount();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ import io.github.dsheirer.module.decode.event.MessageActivityModel;
|
||||
import io.github.dsheirer.module.log.EventLogManager;
|
||||
import io.github.dsheirer.record.RecorderManager;
|
||||
import io.github.dsheirer.record.RecorderType;
|
||||
import io.github.dsheirer.record.binary.BinaryRecorder;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableAudioPacket;
|
||||
import io.github.dsheirer.source.Source;
|
||||
@@ -308,6 +309,25 @@ public class ChannelProcessingManager implements ChannelEventListener
|
||||
{
|
||||
processingChain.addModule(mRecorderManager.getBasebandRecorder(channel.toString()));
|
||||
}
|
||||
|
||||
/* Add decoded bit stream recorder if the decoder supports bitstream output */
|
||||
if(DecoderFactory.getBitstreamDecoders().contains(channel.getDecodeConfiguration().getDecoderType()))
|
||||
{
|
||||
if((recorders.contains(RecorderType.DEMODULATED_BIT_STREAM) &&
|
||||
channel.getChannelType() == Channel.ChannelType.STANDARD))
|
||||
{
|
||||
processingChain.addModule(new BinaryRecorder(mRecorderManager.getRecordingBasePath(),
|
||||
channel.toString()));
|
||||
}
|
||||
|
||||
/* Add traffic channel decoded bit stream recorder */
|
||||
if(recorders.contains(RecorderType.TRAFFIC_DEMODULATED_BIT_STREAM) &&
|
||||
channel.getChannelType() == Channel.ChannelType.TRAFFIC)
|
||||
{
|
||||
processingChain.addModule(new BinaryRecorder(mRecorderManager.getRecordingBasePath(),
|
||||
channel.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
processingChain.setSource(source);
|
||||
|
||||
@@ -21,7 +21,7 @@ import io.github.dsheirer.dsp.filter.resample.RealResampler;
|
||||
import io.github.dsheirer.dsp.mixer.IOscillator;
|
||||
import io.github.dsheirer.dsp.mixer.Oscillator;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -34,7 +34,7 @@ import org.slf4j.LoggerFactory;
|
||||
*
|
||||
* Provides normal or inverted decoded output.
|
||||
*/
|
||||
public class AFSK1200Decoder implements Listener<ReusableBuffer>
|
||||
public class AFSK1200Decoder implements Listener<ReusableFloatBuffer>
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(AFSK1200Decoder.class);
|
||||
|
||||
@@ -110,7 +110,7 @@ public class AFSK1200Decoder implements Listener<ReusableBuffer>
|
||||
* @param buffer containing 8.0 kHz unfiltered FM demodulated audio samples with sub-audible LTR signalling.
|
||||
*/
|
||||
@Override
|
||||
public void receive(ReusableBuffer buffer)
|
||||
public void receive(ReusableFloatBuffer buffer)
|
||||
{
|
||||
mResampler.resample(buffer);
|
||||
}
|
||||
@@ -142,10 +142,10 @@ public class AFSK1200Decoder implements Listener<ReusableBuffer>
|
||||
}
|
||||
|
||||
|
||||
public class Decoder implements Listener<ReusableBuffer>
|
||||
public class Decoder implements Listener<ReusableFloatBuffer>
|
||||
{
|
||||
@Override
|
||||
public void receive(ReusableBuffer buffer)
|
||||
public void receive(ReusableFloatBuffer buffer)
|
||||
{
|
||||
//Calculate correlation values against each 1200/1800 reference signal
|
||||
mCorrelationValuesMark = mCorrelatorMark.process(buffer);
|
||||
@@ -212,17 +212,17 @@ public class AFSK1200Decoder implements Listener<ReusableBuffer>
|
||||
* Processes each sample in the incoming sample buffer against a generated reference sample set for one symbol
|
||||
* period to derive a correlation value that is in-turn averaged over one symbol period.
|
||||
*
|
||||
* @param reusableBuffer containing FM demodulated samples
|
||||
* @param reusableFloatBuffer containing FM demodulated samples
|
||||
* @return a reusable array of correlation values for each sample
|
||||
*/
|
||||
public float[] process(ReusableBuffer reusableBuffer)
|
||||
public float[] process(ReusableFloatBuffer reusableFloatBuffer)
|
||||
{
|
||||
if(mCorrelationValues == null || mCorrelationValues.length != reusableBuffer.getSampleCount())
|
||||
if(mCorrelationValues == null || mCorrelationValues.length != reusableFloatBuffer.getSampleCount())
|
||||
{
|
||||
mCorrelationValues = new float[reusableBuffer.getSampleCount()];
|
||||
mCorrelationValues = new float[reusableFloatBuffer.getSampleCount()];
|
||||
}
|
||||
|
||||
float[] samples = reusableBuffer.getSamples();
|
||||
float[] samples = reusableFloatBuffer.getSamples();
|
||||
|
||||
int y;
|
||||
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
******************************************************************************/
|
||||
package io.github.dsheirer.dsp.am;
|
||||
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBufferQueue;
|
||||
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
|
||||
/**
|
||||
* Performs AM demodulation on baseband I/Q samples to produce demodulated float output.
|
||||
@@ -63,11 +63,11 @@ public class AMDemodulator
|
||||
* @param complexBuffer to demodulate
|
||||
* @return demodulated audio buffer.
|
||||
*/
|
||||
public ReusableBuffer demodulate(ReusableComplexBuffer complexBuffer)
|
||||
public ReusableFloatBuffer demodulate(ReusableComplexBuffer complexBuffer)
|
||||
{
|
||||
ReusableBuffer reusableBuffer = mReusableBufferQueue.getBuffer(complexBuffer.getSampleCount());
|
||||
ReusableFloatBuffer reusableFloatBuffer = mReusableBufferQueue.getBuffer(complexBuffer.getSampleCount());
|
||||
float[] input = complexBuffer.getSamples();
|
||||
float[] output = reusableBuffer.getSamples();
|
||||
float[] output = reusableFloatBuffer.getSamples();
|
||||
mOutputBufferPointer = 0;
|
||||
|
||||
for(int x= 0; x < complexBuffer.getSamples().length; x += 2)
|
||||
@@ -77,6 +77,6 @@ public class AMDemodulator
|
||||
|
||||
complexBuffer.decrementUserCount();
|
||||
|
||||
return reusableBuffer;
|
||||
return reusableFloatBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,6 +136,46 @@ public class ContinuousBufferProcessor<E> implements Listener<E>
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops this buffer processor,stops queuing of incoming buffers and flushes the internal buffer queue
|
||||
* contents to the listener.
|
||||
*/
|
||||
public void flushAndStop()
|
||||
{
|
||||
if(mRunning.compareAndSet(true, false))
|
||||
{
|
||||
if(mScheduledFuture != null)
|
||||
{
|
||||
mScheduledFuture.cancel(true);
|
||||
mScheduledFuture = null;
|
||||
}
|
||||
|
||||
process();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Distributes queued buffers to the listener
|
||||
*/
|
||||
private void process()
|
||||
{
|
||||
List<E> buffers = new ArrayList<>();
|
||||
|
||||
try
|
||||
{
|
||||
mQueue.drainTo(buffers);
|
||||
|
||||
if(mListener != null)
|
||||
{
|
||||
mListener.receive(buffers);
|
||||
}
|
||||
}
|
||||
catch(Throwable throwable)
|
||||
{
|
||||
mLog.error("Error while dispatching buffers to listener", throwable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears any buffers from the queue
|
||||
*/
|
||||
@@ -162,21 +202,7 @@ public class ContinuousBufferProcessor<E> implements Listener<E>
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
List<E> buffers = new ArrayList<>();
|
||||
|
||||
try
|
||||
{
|
||||
mQueue.drainTo(buffers);
|
||||
|
||||
if(mListener != null)
|
||||
{
|
||||
mListener.receive(buffers);
|
||||
}
|
||||
}
|
||||
catch(Throwable throwable)
|
||||
{
|
||||
mLog.error("Error while dispatching buffers to listeners", throwable);
|
||||
}
|
||||
process();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
******************************************************************************/
|
||||
package io.github.dsheirer.dsp.filter.channelizer;
|
||||
|
||||
import io.github.dsheirer.sample.buffer.AbstractReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.OverflowableReusableBufferTransferQueue;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
|
||||
public class ContinuousReusableBufferProcessor<T extends ReusableBuffer> extends ContinuousBufferProcessor<T>
|
||||
public class ContinuousReusableBufferProcessor<T extends AbstractReusableBuffer> extends ContinuousBufferProcessor<T>
|
||||
{
|
||||
/**
|
||||
* Scheduled Reusable Buffer Processor combines an internal overflowable buffer with a scheduled runnable processing
|
||||
|
||||
@@ -23,8 +23,8 @@ import io.github.dsheirer.dsp.filter.Window.WindowType;
|
||||
import io.github.dsheirer.dsp.filter.fir.real.RealFIRFilter2;
|
||||
import io.github.dsheirer.dsp.filter.halfband.real.HalfBandFilter;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBufferAssembler;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import io.github.dsheirer.sample.decimator.RealDecimator;
|
||||
import io.github.dsheirer.sample.real.RealSampleListener;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
@@ -124,7 +124,7 @@ public class RealPrimeCICDecimate
|
||||
/**
|
||||
* Adds a listener to receive the output of this CIC decimation filter
|
||||
*/
|
||||
public void setListener(Listener<ReusableBuffer> listener)
|
||||
public void setListener(Listener<ReusableFloatBuffer> listener)
|
||||
{
|
||||
mOutput.setListener(listener);
|
||||
}
|
||||
@@ -173,7 +173,7 @@ public class RealPrimeCICDecimate
|
||||
/**
|
||||
* Primary input method for receiving real buffers.
|
||||
*/
|
||||
public void receive(ReusableBuffer buffer)
|
||||
public void receive(ReusableFloatBuffer buffer)
|
||||
{
|
||||
if(mFirstDecimatingStage != null)
|
||||
{
|
||||
@@ -353,7 +353,7 @@ public class RealPrimeCICDecimate
|
||||
{
|
||||
/* Decimated output buffers will contain 1024 samples */
|
||||
private ReusableBufferAssembler mAssembler;
|
||||
private Listener<ReusableBuffer> mReusableBufferListener;
|
||||
private Listener<ReusableFloatBuffer> mReusableBufferListener;
|
||||
|
||||
private RealFIRFilter2 mCleanupFilter;
|
||||
private HalfBandFilter mHalfBandFilter = new HalfBandFilter(
|
||||
@@ -365,21 +365,21 @@ public class RealPrimeCICDecimate
|
||||
attenuation, windowType), 0.4f);
|
||||
|
||||
mAssembler = new ReusableBufferAssembler(outputBufferSize);
|
||||
mAssembler.setListener(new Listener<ReusableBuffer>()
|
||||
mAssembler.setListener(new Listener<ReusableFloatBuffer>()
|
||||
{
|
||||
@Override
|
||||
public void receive(ReusableBuffer reusableBuffer)
|
||||
public void receive(ReusableFloatBuffer reusableFloatBuffer)
|
||||
{
|
||||
|
||||
if(mReusableBufferListener != null)
|
||||
{
|
||||
ReusableBuffer cleanupFiltered = mCleanupFilter.filter(reusableBuffer);
|
||||
ReusableBuffer halfBandFiltered = mHalfBandFilter.filter(cleanupFiltered);
|
||||
ReusableFloatBuffer cleanupFiltered = mCleanupFilter.filter(reusableFloatBuffer);
|
||||
ReusableFloatBuffer halfBandFiltered = mHalfBandFilter.filter(cleanupFiltered);
|
||||
mReusableBufferListener.receive(halfBandFiltered);
|
||||
}
|
||||
else
|
||||
{
|
||||
reusableBuffer.decrementUserCount();
|
||||
reusableFloatBuffer.decrementUserCount();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -406,7 +406,7 @@ public class RealPrimeCICDecimate
|
||||
/**
|
||||
* Adds a listener to receive output samples
|
||||
*/
|
||||
public void setListener(Listener<ReusableBuffer> listener)
|
||||
public void setListener(Listener<ReusableFloatBuffer> listener)
|
||||
{
|
||||
mReusableBufferListener = listener;
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
******************************************************************************/
|
||||
package io.github.dsheirer.dsp.filter.dc;
|
||||
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBufferQueue;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -77,11 +77,11 @@ public class BufferDCFilter
|
||||
}
|
||||
}
|
||||
|
||||
public ReusableBuffer filter(ReusableBuffer unfilteredBuffer)
|
||||
public ReusableFloatBuffer filter(ReusableFloatBuffer unfilteredBuffer)
|
||||
{
|
||||
float[] unfilteredSamples = unfilteredBuffer.getSamples();
|
||||
|
||||
ReusableBuffer filteredBuffer = mReusableBufferQueue.getBuffer(unfilteredSamples.length);
|
||||
ReusableFloatBuffer filteredBuffer = mReusableBufferQueue.getBuffer(unfilteredSamples.length);
|
||||
float[] filteredSamples = filteredBuffer.getSamples();
|
||||
|
||||
float offset = getOffset(unfilteredSamples);
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
******************************************************************************/
|
||||
package io.github.dsheirer.dsp.filter.dc;
|
||||
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBufferQueue;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
|
||||
/**
|
||||
* DC removal filter for removing any DC offset that may be present when a signal is not aligned within the
|
||||
@@ -77,9 +77,9 @@ public class DCRemovalFilter
|
||||
* @param unfilteredBuffer containing samples to filter
|
||||
* @return a new reusable buffer containing the filtered samples with the user count set to 1.
|
||||
*/
|
||||
public ReusableBuffer filter(ReusableBuffer unfilteredBuffer)
|
||||
public ReusableFloatBuffer filter(ReusableFloatBuffer unfilteredBuffer)
|
||||
{
|
||||
ReusableBuffer filteredBuffer = mReusableBufferQueue.getBuffer(unfilteredBuffer.getSampleCount());
|
||||
ReusableFloatBuffer filteredBuffer = mReusableBufferQueue.getBuffer(unfilteredBuffer.getSampleCount());
|
||||
|
||||
float[] unfilteredSamples = unfilteredBuffer.getSamples();
|
||||
float[] filteredSamples = filteredBuffer.getSamples();
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
******************************************************************************/
|
||||
package io.github.dsheirer.dsp.filter.dc;
|
||||
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBufferQueue;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import io.github.dsheirer.sample.real.RealSampleListener;
|
||||
|
||||
public class IIRSinglePoleDCRemovalFilter implements RealSampleListener
|
||||
@@ -67,9 +67,9 @@ public class IIRSinglePoleDCRemovalFilter implements RealSampleListener
|
||||
* @param inputBuffer to filter
|
||||
* @return filtered samples in a new (ie reused) output buffer
|
||||
*/
|
||||
public ReusableBuffer filter(ReusableBuffer inputBuffer)
|
||||
public ReusableFloatBuffer filter(ReusableFloatBuffer inputBuffer)
|
||||
{
|
||||
ReusableBuffer outputBuffer = mReusableBufferQueue.getBuffer(inputBuffer.getSampleCount());
|
||||
ReusableFloatBuffer outputBuffer = mReusableBufferQueue.getBuffer(inputBuffer.getSampleCount());
|
||||
float[] inputSamples = inputBuffer.getSamples();
|
||||
float[] outputSamples = outputBuffer.getSamples();
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
package io.github.dsheirer.dsp.filter.fir.real;
|
||||
|
||||
import io.github.dsheirer.dsp.filter.fir.FIRFilter;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBufferQueue;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
|
||||
/**
|
||||
* Finite Impulse Response (FIR) filter for filtering individual float samples or float sample arrays.
|
||||
@@ -113,11 +113,11 @@ public class RealFIRFilter2 extends FIRFilter
|
||||
* @param unfilteredBuffer containing a sample array to be filtered
|
||||
* @return a new reusable buffer with the filtered samples.
|
||||
*/
|
||||
public ReusableBuffer filter(ReusableBuffer unfilteredBuffer)
|
||||
public ReusableFloatBuffer filter(ReusableFloatBuffer unfilteredBuffer)
|
||||
{
|
||||
float[] unfilteredSamples = unfilteredBuffer.getSamples();
|
||||
|
||||
ReusableBuffer filteredBuffer = mReusableBufferQueue.getBuffer(unfilteredSamples.length);
|
||||
ReusableFloatBuffer filteredBuffer = mReusableBufferQueue.getBuffer(unfilteredSamples.length);
|
||||
float[] filteredSamples = filteredBuffer.getSamples();
|
||||
|
||||
for(int x = 0; x < unfilteredSamples.length; x++)
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
******************************************************************************/
|
||||
package io.github.dsheirer.dsp.filter.halfband.real;
|
||||
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBufferQueue;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
public class HalfBandFilter
|
||||
@@ -84,10 +84,10 @@ public class HalfBandFilter
|
||||
mBufferPointer = mBufferPointer % mBufferSize;
|
||||
}
|
||||
|
||||
public ReusableBuffer filter(ReusableBuffer input)
|
||||
public ReusableFloatBuffer filter(ReusableFloatBuffer input)
|
||||
{
|
||||
float[] inputSamples = input.getSamples();
|
||||
ReusableBuffer output = mReusableBufferQueue.getBuffer(inputSamples.length);
|
||||
ReusableFloatBuffer output = mReusableBufferQueue.getBuffer(inputSamples.length);
|
||||
float[] outputSamples = output.getSamples();
|
||||
|
||||
for(int x = 0; x < inputSamples.length; x++)
|
||||
|
||||
@@ -18,8 +18,8 @@ package io.github.dsheirer.dsp.filter.resample;
|
||||
import com.laszlosystems.libresample4j.Resampler;
|
||||
import com.laszlosystems.libresample4j.SampleBuffers;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBufferQueue;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -32,7 +32,7 @@ public class RealResampler
|
||||
|
||||
private ReusableBufferQueue mReusableBufferQueue = new ReusableBufferQueue("RealResampler");
|
||||
private Resampler mResampler;
|
||||
private Listener<ReusableBuffer> mResampledListener;
|
||||
private Listener<ReusableFloatBuffer> mResampledListener;
|
||||
private BufferManager mBufferManager;
|
||||
private double mResampleFactor;
|
||||
|
||||
@@ -50,11 +50,11 @@ public class RealResampler
|
||||
|
||||
/**
|
||||
* Primary input method to the resampler
|
||||
* @param reusableBuffer to resample
|
||||
* @param reusableFloatBuffer to resample
|
||||
*/
|
||||
public void resample(ReusableBuffer reusableBuffer)
|
||||
public void resample(ReusableFloatBuffer reusableFloatBuffer)
|
||||
{
|
||||
mBufferManager.load(reusableBuffer);
|
||||
mBufferManager.load(reusableFloatBuffer);
|
||||
mResampler.process(mResampleFactor, mBufferManager, false);
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ public class RealResampler
|
||||
* Registers the listener to receive the resampled buffer output
|
||||
* @param resampledBufferListener to receive buffers
|
||||
*/
|
||||
public void setListener(Listener<ReusableBuffer> resampledBufferListener)
|
||||
public void setListener(Listener<ReusableFloatBuffer> resampledBufferListener)
|
||||
{
|
||||
mResampledListener = resampledBufferListener;
|
||||
}
|
||||
@@ -89,10 +89,10 @@ public class RealResampler
|
||||
/**
|
||||
* Queues the buffer sample for resampling
|
||||
*/
|
||||
public void load(ReusableBuffer reusableBuffer)
|
||||
public void load(ReusableFloatBuffer reusableFloatBuffer)
|
||||
{
|
||||
mInputBuffer.put(reusableBuffer.getSamples());
|
||||
reusableBuffer.decrementUserCount();
|
||||
mInputBuffer.put(reusableFloatBuffer.getSamples());
|
||||
reusableFloatBuffer.decrementUserCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -128,7 +128,7 @@ public class RealResampler
|
||||
|
||||
while(mOutputBuffer.position() > mOutputBufferSize)
|
||||
{
|
||||
ReusableBuffer outputBuffer = mReusableBufferQueue.getBuffer(mOutputBufferSize);
|
||||
ReusableFloatBuffer outputBuffer = mReusableBufferQueue.getBuffer(mOutputBufferSize);
|
||||
|
||||
mOutputBuffer.flip();
|
||||
mOutputBuffer.get(outputBuffer.getSamples());
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
******************************************************************************/
|
||||
package io.github.dsheirer.dsp.fm;
|
||||
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBufferQueue;
|
||||
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import io.github.dsheirer.sample.complex.Complex;
|
||||
|
||||
/**
|
||||
@@ -129,9 +129,9 @@ public class FMDemodulator
|
||||
* @param basebandSampleBuffer containing samples to demodulate
|
||||
* @return demodulated sample buffer.
|
||||
*/
|
||||
public ReusableBuffer demodulate(ReusableComplexBuffer basebandSampleBuffer)
|
||||
public ReusableFloatBuffer demodulate(ReusableComplexBuffer basebandSampleBuffer)
|
||||
{
|
||||
ReusableBuffer demodulatedBuffer = mReusableBufferQueue.getBuffer(basebandSampleBuffer.getSampleCount());
|
||||
ReusableFloatBuffer demodulatedBuffer = mReusableBufferQueue.getBuffer(basebandSampleBuffer.getSampleCount());
|
||||
|
||||
float[] basebandSamples = basebandSampleBuffer.getSamples();
|
||||
float[] demodulatedSamples = demodulatedBuffer.getSamples();
|
||||
|
||||
@@ -23,7 +23,7 @@ import io.github.dsheirer.dsp.filter.fir.real.RealFIRFilter2;
|
||||
import io.github.dsheirer.dsp.filter.fir.remez.RemezFIRFilterDesigner;
|
||||
import io.github.dsheirer.dsp.symbol.ISyncDetectListener;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -43,7 +43,7 @@ import org.slf4j.LoggerFactory;
|
||||
* adjustment may not fully compensate for mis-tuned signals and may result in missed decodes of idle bursts. However,
|
||||
* the DC filter will track a mis-tuned signal to baseband quickly upon a continuous transmission.
|
||||
*/
|
||||
public class LTRDecoder implements Listener<ReusableBuffer>, ISyncDetectListener, ISyncStateListener
|
||||
public class LTRDecoder implements Listener<ReusableFloatBuffer>, ISyncDetectListener, ISyncStateListener
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(LTRDecoder.class);
|
||||
|
||||
@@ -148,10 +148,10 @@ public class LTRDecoder implements Listener<ReusableBuffer>, ISyncDetectListener
|
||||
* @param buffer containing 8.0 kHz unfiltered FM demodulated audio samples with sub-audible LTR signalling.
|
||||
*/
|
||||
@Override
|
||||
public void receive(ReusableBuffer buffer)
|
||||
public void receive(ReusableFloatBuffer buffer)
|
||||
{
|
||||
ReusableBuffer dcFiltered = mDCFilter.filter(buffer);
|
||||
ReusableBuffer lowPassFiltered = mLowPassFilter.filter(dcFiltered);
|
||||
ReusableFloatBuffer dcFiltered = mDCFilter.filter(buffer);
|
||||
ReusableFloatBuffer lowPassFiltered = mLowPassFilter.filter(dcFiltered);
|
||||
|
||||
for(float sample : lowPassFiltered.getSamples())
|
||||
{
|
||||
|
||||
@@ -2,8 +2,8 @@ package io.github.dsheirer.dsp.gain;
|
||||
|
||||
import io.github.dsheirer.buffer.DoubleCircularBuffer;
|
||||
import io.github.dsheirer.buffer.RealCircularBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBufferQueue;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
@@ -147,9 +147,9 @@ public class AutomaticGainControl
|
||||
* @param input samples to process
|
||||
* @return output samples with gain applied
|
||||
*/
|
||||
public ReusableBuffer process(ReusableBuffer input)
|
||||
public ReusableFloatBuffer process(ReusableFloatBuffer input)
|
||||
{
|
||||
ReusableBuffer output = mReusableBufferQueue.getBuffer(input.getSampleCount());
|
||||
ReusableFloatBuffer output = mReusableBufferQueue.getBuffer(input.getSampleCount());
|
||||
|
||||
float[] inputSamples = input.getSamples();
|
||||
float[] outputSamples = output.getSamples();
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
******************************************************************************/
|
||||
package io.github.dsheirer.dsp.mixer;
|
||||
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import io.github.dsheirer.sample.complex.Complex;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -182,11 +182,11 @@ public abstract class AbstractOscillator implements IOscillator
|
||||
|
||||
/**
|
||||
* Generates enough real samples to fill the reusable buffer
|
||||
* @param reusableBuffer to fill with real samples
|
||||
* @param reusableFloatBuffer to fill with real samples
|
||||
*/
|
||||
@Override
|
||||
public void generateReal(ReusableBuffer reusableBuffer)
|
||||
public void generateReal(ReusableFloatBuffer reusableFloatBuffer)
|
||||
{
|
||||
reusableBuffer.reloadFrom(generateReal(reusableBuffer.getSampleCount()), System.currentTimeMillis());
|
||||
reusableFloatBuffer.reloadFrom(generateReal(reusableFloatBuffer.getSampleCount()), System.currentTimeMillis());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
******************************************************************************/
|
||||
package io.github.dsheirer.dsp.mixer;
|
||||
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
|
||||
/**
|
||||
* Oscillator interface.
|
||||
@@ -102,9 +102,9 @@ public interface IOscillator
|
||||
* Generates real samples and fills the reusable buffer using the current system time in millis for
|
||||
* the update timestamp.
|
||||
*
|
||||
* @param reusableBuffer to fill with complex samples
|
||||
* @param reusableFloatBuffer to fill with complex samples
|
||||
*/
|
||||
void generateReal(ReusableBuffer reusableBuffer);
|
||||
void generateReal(ReusableFloatBuffer reusableFloatBuffer);
|
||||
|
||||
/**
|
||||
* Mixes (heterodynes) the complex sample array using the current settings of this oscillator.
|
||||
|
||||
@@ -17,8 +17,8 @@ package io.github.dsheirer.gui.instrument;
|
||||
|
||||
import io.github.dsheirer.gui.instrument.decoder.AbstractDecoderPane;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBufferBroadcaster;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import io.github.dsheirer.source.IControllableFileSource;
|
||||
import io.github.dsheirer.source.IFrameLocationListener;
|
||||
import io.github.dsheirer.source.wave.ComplexWaveSource;
|
||||
@@ -177,7 +177,7 @@ public class PlaybackController extends HBox implements IFrameLocationListener
|
||||
/**
|
||||
* Adds listener to receive complex buffers from this playback
|
||||
*/
|
||||
public void addListener(Listener<ReusableBuffer> listener)
|
||||
public void addListener(Listener<ReusableFloatBuffer> listener)
|
||||
{
|
||||
mReusableBufferBroadcaster.addListener(listener);
|
||||
}
|
||||
@@ -185,7 +185,7 @@ public class PlaybackController extends HBox implements IFrameLocationListener
|
||||
/**
|
||||
* Removes the listener from receiving complex buffers from this playback
|
||||
*/
|
||||
public void removeListener(Listener<ReusableBuffer> listener)
|
||||
public void removeListener(Listener<ReusableFloatBuffer> listener)
|
||||
{
|
||||
mReusableBufferBroadcaster.removeListener(listener);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ package io.github.dsheirer.gui.instrument.chart;
|
||||
|
||||
import io.github.dsheirer.buffer.RealCircularBuffer;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.chart.LineChart;
|
||||
@@ -27,7 +27,7 @@ import javafx.scene.layout.StackPane;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class RealSampleLineChart extends LineChart implements Listener<ReusableBuffer>
|
||||
public class RealSampleLineChart extends LineChart implements Listener<ReusableFloatBuffer>
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(RealSampleLineChart.class);
|
||||
private ObservableList<Data<Integer,Float>> mSamples = FXCollections.observableArrayList();
|
||||
@@ -65,7 +65,7 @@ public class RealSampleLineChart extends LineChart implements Listener<ReusableB
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ReusableBuffer buffer)
|
||||
public void receive(ReusableFloatBuffer buffer)
|
||||
{
|
||||
for(float sample: buffer.getSamples())
|
||||
{
|
||||
|
||||
@@ -23,7 +23,7 @@ import io.github.dsheirer.gui.instrument.chart.RealSampleLineChart;
|
||||
import io.github.dsheirer.message.Message;
|
||||
import io.github.dsheirer.module.decode.DecoderType;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.VBox;
|
||||
@@ -52,7 +52,7 @@ public abstract class AbstractAFSK1200Pane extends RealDecoderPane
|
||||
private void init()
|
||||
{
|
||||
//This is force-cast without type checking ....
|
||||
addListener((Listener<ReusableBuffer>)getDecoder());
|
||||
addListener((Listener<ReusableFloatBuffer>)getDecoder());
|
||||
|
||||
addListener(getSampleLineChart());
|
||||
|
||||
|
||||
@@ -17,10 +17,10 @@ package io.github.dsheirer.gui.instrument.decoder;
|
||||
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.SampleType;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
public abstract class AbstractDecoderPane<T extends ReusableBuffer> extends VBox implements Listener<T>
|
||||
public abstract class AbstractDecoderPane<T extends ReusableFloatBuffer> extends VBox implements Listener<T>
|
||||
{
|
||||
abstract SampleType getSampleType();
|
||||
|
||||
|
||||
@@ -18,11 +18,11 @@ package io.github.dsheirer.gui.instrument.decoder;
|
||||
import io.github.dsheirer.module.decode.DecoderType;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.SampleType;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBufferBroadcaster;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import javafx.scene.text.Text;
|
||||
|
||||
public class RealDecoderPane extends AbstractDecoderPane<ReusableBuffer>
|
||||
public class RealDecoderPane extends AbstractDecoderPane<ReusableFloatBuffer>
|
||||
{
|
||||
private ReusableBufferBroadcaster mBufferBroadcaster = new ReusableBufferBroadcaster();
|
||||
private DecoderType mDecoderType;
|
||||
@@ -47,17 +47,17 @@ public class RealDecoderPane extends AbstractDecoderPane<ReusableBuffer>
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ReusableBuffer reusableBuffer)
|
||||
public void receive(ReusableFloatBuffer reusableFloatBuffer)
|
||||
{
|
||||
mBufferBroadcaster.broadcast(reusableBuffer);
|
||||
mBufferBroadcaster.broadcast(reusableFloatBuffer);
|
||||
}
|
||||
|
||||
public void addListener(Listener<ReusableBuffer> listener)
|
||||
public void addListener(Listener<ReusableFloatBuffer> listener)
|
||||
{
|
||||
mBufferBroadcaster.addListener(listener);
|
||||
}
|
||||
|
||||
public void removeListener(Listener<ReusableBuffer> listener)
|
||||
public void removeListener(Listener<ReusableFloatBuffer> listener)
|
||||
{
|
||||
mBufferBroadcaster.removeListener(listener);
|
||||
}
|
||||
|
||||
@@ -49,11 +49,14 @@ import io.github.dsheirer.sample.Broadcaster;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.IReusableBufferListener;
|
||||
import io.github.dsheirer.sample.buffer.IReusableBufferProvider;
|
||||
import io.github.dsheirer.sample.buffer.IReusableByteBufferListener;
|
||||
import io.github.dsheirer.sample.buffer.IReusableByteBufferProvider;
|
||||
import io.github.dsheirer.sample.buffer.IReusableComplexBufferListener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableAudioPacket;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBufferBroadcaster;
|
||||
import io.github.dsheirer.sample.buffer.ReusableByteBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import io.github.dsheirer.source.ComplexSource;
|
||||
import io.github.dsheirer.source.ISourceEventListener;
|
||||
import io.github.dsheirer.source.ISourceEventProvider;
|
||||
@@ -93,8 +96,9 @@ public class ProcessingChain implements IChannelEventListener
|
||||
private final static Logger mLog = LoggerFactory.getLogger(ProcessingChain.class);
|
||||
|
||||
private ReusableBufferBroadcaster<ReusableAudioPacket> mAudioPacketBroadcaster = new ReusableBufferBroadcaster<>();
|
||||
private ReusableBufferBroadcaster<ReusableBuffer> mDemodulatedAudioBufferBroadcaster = new ReusableBufferBroadcaster();
|
||||
private ReusableBufferBroadcaster<ReusableFloatBuffer> mDemodulatedAudioBufferBroadcaster = new ReusableBufferBroadcaster();
|
||||
private ReusableBufferBroadcaster<ReusableComplexBuffer> mBasebandComplexBufferBroadcaster = new ReusableBufferBroadcaster();
|
||||
private ReusableBufferBroadcaster<ReusableByteBuffer> mDemodulatedBitstreamBufferBroadcaster = new ReusableBufferBroadcaster();
|
||||
private Broadcaster<AttributeChangeRequest> mAttributeChangeRequestBroadcaster = new Broadcaster<>();
|
||||
private Broadcaster<CallEvent> mCallEventBroadcaster = new Broadcaster<>();
|
||||
private Broadcaster<ChannelEvent> mChannelEventBroadcaster = new Broadcaster<>();
|
||||
@@ -163,6 +167,7 @@ public class ProcessingChain implements IChannelEventListener
|
||||
mCallEventBroadcaster.dispose();
|
||||
mChannelEventBroadcaster.dispose();
|
||||
mBasebandComplexBufferBroadcaster.dispose();
|
||||
mDemodulatedBitstreamBufferBroadcaster.dispose();
|
||||
mMessageBroadcaster.dispose();
|
||||
mSquelchStateBroadcaster.dispose();
|
||||
}
|
||||
@@ -323,6 +328,11 @@ public class ProcessingChain implements IChannelEventListener
|
||||
mDemodulatedAudioBufferBroadcaster.addListener(((IReusableBufferListener)module).getReusableBufferListener());
|
||||
}
|
||||
|
||||
if(module instanceof IReusableByteBufferListener)
|
||||
{
|
||||
mDemodulatedBitstreamBufferBroadcaster.addListener(((IReusableByteBufferListener)module).getReusableByteBufferListener());
|
||||
}
|
||||
|
||||
if(module instanceof IReusableComplexBufferListener)
|
||||
{
|
||||
mBasebandComplexBufferBroadcaster.addListener(((IReusableComplexBufferListener)module).getReusableComplexBufferListener());
|
||||
@@ -385,6 +395,11 @@ public class ProcessingChain implements IChannelEventListener
|
||||
mDemodulatedAudioBufferBroadcaster.removeListener(((IReusableBufferListener)module).getReusableBufferListener());
|
||||
}
|
||||
|
||||
if(module instanceof IReusableByteBufferListener)
|
||||
{
|
||||
mDemodulatedBitstreamBufferBroadcaster.removeListener(((IReusableByteBufferListener) module).getReusableByteBufferListener());
|
||||
}
|
||||
|
||||
if(module instanceof IReusableComplexBufferListener)
|
||||
{
|
||||
mBasebandComplexBufferBroadcaster.removeListener(((IReusableComplexBufferListener) module).getReusableComplexBufferListener());
|
||||
@@ -452,6 +467,11 @@ public class ProcessingChain implements IChannelEventListener
|
||||
((IMessageProvider) module).setMessageListener(mMessageBroadcaster);
|
||||
}
|
||||
|
||||
if(module instanceof IReusableByteBufferProvider)
|
||||
{
|
||||
((IReusableByteBufferProvider)module).setBufferListener(mDemodulatedBitstreamBufferBroadcaster);
|
||||
}
|
||||
|
||||
if(module instanceof IReusableBufferProvider)
|
||||
{
|
||||
((IReusableBufferProvider)module).setBufferListener(mDemodulatedAudioBufferBroadcaster);
|
||||
@@ -484,6 +504,11 @@ public class ProcessingChain implements IChannelEventListener
|
||||
((IAudioPacketProvider) module).setAudioPacketListener(null);
|
||||
}
|
||||
|
||||
if(module instanceof IReusableByteBufferProvider)
|
||||
{
|
||||
((IReusableByteBufferProvider)module).removeBufferListener(mDemodulatedBitstreamBufferBroadcaster);
|
||||
}
|
||||
|
||||
if(module instanceof ICallEventProvider)
|
||||
{
|
||||
((ICallEventProvider) module).removeCallEventListener(mCallEventBroadcaster);
|
||||
@@ -549,7 +574,7 @@ public class ProcessingChain implements IChannelEventListener
|
||||
//Broadcast the source sample rate so that each of the modules can self-configure
|
||||
mSourceEventBroadcaster.broadcast(SourceEvent.sampleRateChange(mSource.getSampleRate(), "Processing Chain Startup"));
|
||||
|
||||
//Broadcast the source center frequencysample rate so that each of the modules can self-configure
|
||||
//Broadcast the source center frequency / sample rate so that each of the modules can self-configure
|
||||
mSourceEventBroadcaster.broadcast(SourceEvent.frequencyChange(mSource.getFrequency(), "Processing Chain Startup"));
|
||||
|
||||
//Setup the channel state to monitor source overflow conditions
|
||||
@@ -790,7 +815,7 @@ public class ProcessingChain implements IChannelEventListener
|
||||
/**
|
||||
* Adds listener to receive demodulated audio buffers from an modules that produce demodulated audio.
|
||||
*/
|
||||
public void addDemodulatedAudioListener(Listener<ReusableBuffer> listener)
|
||||
public void addDemodulatedAudioListener(Listener<ReusableFloatBuffer> listener)
|
||||
{
|
||||
mDemodulatedAudioBufferBroadcaster.addListener(listener);
|
||||
}
|
||||
@@ -798,7 +823,7 @@ public class ProcessingChain implements IChannelEventListener
|
||||
/**
|
||||
* Removes the listener from receiving demodulated audio buffers.
|
||||
*/
|
||||
public void removeDemodulatedAudioListener(Listener<ReusableBuffer> listener)
|
||||
public void removeDemodulatedAudioListener(Listener<ReusableFloatBuffer> listener)
|
||||
{
|
||||
mDemodulatedAudioBufferBroadcaster.removeListener(listener);
|
||||
}
|
||||
|
||||
@@ -93,6 +93,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
public class DecoderFactory
|
||||
@@ -467,4 +468,17 @@ public class DecoderFactory
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decoder(s) that support bitstreams.
|
||||
*
|
||||
* @return set of decoders that support bitstreams.
|
||||
*/
|
||||
public static EnumSet<DecoderType> getBitstreamDecoders()
|
||||
{
|
||||
// return EnumSet.of(DecoderType.P25_PHASE1);
|
||||
|
||||
//None of the decoders currently support bitstream output.
|
||||
return EnumSet.noneOf(DecoderType.class);
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ import io.github.dsheirer.dsp.afsk.AFSK1200Decoder;
|
||||
import io.github.dsheirer.module.decode.Decoder;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.IReusableBufferListener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
|
||||
/**
|
||||
* Abstract class for Audio Frequency Shift Keying (AFSK) 1200-baud decoder based decoder modules.
|
||||
@@ -28,7 +28,7 @@ import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
*
|
||||
* Sub-class implementations should invoke getDecoder().setListener() to receive decoded symbol stream.
|
||||
*/
|
||||
public abstract class AbstractAFSKDecoder extends Decoder implements IReusableBufferListener, Listener<ReusableBuffer>
|
||||
public abstract class AbstractAFSKDecoder extends Decoder implements IReusableBufferListener, Listener<ReusableFloatBuffer>
|
||||
{
|
||||
private AFSK1200Decoder mAFSK1200Decoder;
|
||||
|
||||
@@ -48,13 +48,13 @@ public abstract class AbstractAFSKDecoder extends Decoder implements IReusableBu
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ReusableBuffer reusableBuffer)
|
||||
public void receive(ReusableFloatBuffer reusableFloatBuffer)
|
||||
{
|
||||
mAFSK1200Decoder.receive(reusableBuffer);
|
||||
mAFSK1200Decoder.receive(reusableFloatBuffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Listener<ReusableBuffer> getReusableBufferListener()
|
||||
public Listener<ReusableFloatBuffer> getReusableBufferListener()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ package io.github.dsheirer.module.decode.fleetsync2;
|
||||
|
||||
import io.github.dsheirer.dsp.afsk.AFSK1200DecoderInstrumented;
|
||||
import io.github.dsheirer.gui.instrument.chart.IInstrumentedAFSK1200Decoder;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
|
||||
/**
|
||||
@@ -44,9 +44,9 @@ public class Fleetsync2DecoderInstrumented extends Fleetsync2Decoder implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ReusableBuffer reusableBuffer)
|
||||
public void receive(ReusableFloatBuffer reusableFloatBuffer)
|
||||
{
|
||||
super.receive(reusableBuffer);
|
||||
super.receive(reusableFloatBuffer);
|
||||
|
||||
bufferCount.setValue(bufferCount.intValue() + 1);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ package io.github.dsheirer.module.decode.lj1200;
|
||||
|
||||
import io.github.dsheirer.dsp.afsk.AFSK1200DecoderInstrumented;
|
||||
import io.github.dsheirer.gui.instrument.chart.IInstrumentedAFSK1200Decoder;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
|
||||
/**
|
||||
@@ -44,9 +44,9 @@ public class LJ1200DecoderInstrumented extends LJ1200Decoder implements IInstrum
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ReusableBuffer reusableBuffer)
|
||||
public void receive(ReusableFloatBuffer reusableFloatBuffer)
|
||||
{
|
||||
super.receive(reusableBuffer);
|
||||
super.receive(reusableFloatBuffer);
|
||||
|
||||
bufferCount.setValue(bufferCount.intValue() + 1);
|
||||
}
|
||||
|
||||
@@ -24,9 +24,9 @@ import io.github.dsheirer.module.decode.Decoder;
|
||||
import io.github.dsheirer.module.decode.DecoderType;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.IReusableBufferListener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
|
||||
public class LTRNetDecoder extends Decoder implements IReusableBufferListener, Listener<ReusableBuffer>
|
||||
public class LTRNetDecoder extends Decoder implements IReusableBufferListener, Listener<ReusableFloatBuffer>
|
||||
{
|
||||
public static final int LTR_NET_MESSAGE_LENGTH = 40;
|
||||
protected LTRDecoder mLTRDecoder;
|
||||
@@ -73,15 +73,15 @@ public class LTRNetDecoder extends Decoder implements IReusableBufferListener, L
|
||||
}
|
||||
|
||||
@Override
|
||||
public Listener<ReusableBuffer> getReusableBufferListener()
|
||||
public Listener<ReusableFloatBuffer> getReusableBufferListener()
|
||||
{
|
||||
return mLTRDecoder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ReusableBuffer reusableBuffer)
|
||||
public void receive(ReusableFloatBuffer reusableFloatBuffer)
|
||||
{
|
||||
mLTRDecoder.receive(reusableBuffer);
|
||||
mLTRDecoder.receive(reusableFloatBuffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,7 +17,7 @@ package io.github.dsheirer.module.decode.ltrnet;
|
||||
|
||||
import io.github.dsheirer.alias.AliasList;
|
||||
import io.github.dsheirer.dsp.fsk.LTRDecoderInstrumented;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
|
||||
public class LTRNetDecoderInstrumented extends LTRNetDecoder
|
||||
@@ -35,9 +35,9 @@ public class LTRNetDecoderInstrumented extends LTRNetDecoder
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ReusableBuffer reusableBuffer)
|
||||
public void receive(ReusableFloatBuffer reusableFloatBuffer)
|
||||
{
|
||||
super.receive(reusableBuffer);
|
||||
super.receive(reusableFloatBuffer);
|
||||
|
||||
bufferCount.setValue(bufferCount.intValue() + 1);
|
||||
}
|
||||
|
||||
@@ -24,9 +24,9 @@ import io.github.dsheirer.module.decode.Decoder;
|
||||
import io.github.dsheirer.module.decode.DecoderType;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.IReusableBufferListener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
|
||||
public class LTRStandardDecoder extends Decoder implements IReusableBufferListener, Listener<ReusableBuffer>
|
||||
public class LTRStandardDecoder extends Decoder implements IReusableBufferListener, Listener<ReusableFloatBuffer>
|
||||
{
|
||||
public static final int LTR_STANDARD_MESSAGE_LENGTH = 40;
|
||||
|
||||
@@ -65,15 +65,15 @@ public class LTRStandardDecoder extends Decoder implements IReusableBufferListen
|
||||
}
|
||||
|
||||
@Override
|
||||
public Listener<ReusableBuffer> getReusableBufferListener()
|
||||
public Listener<ReusableFloatBuffer> getReusableBufferListener()
|
||||
{
|
||||
return mLTRDecoder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ReusableBuffer reusableBuffer)
|
||||
public void receive(ReusableFloatBuffer reusableFloatBuffer)
|
||||
{
|
||||
mLTRDecoder.receive(reusableBuffer);
|
||||
mLTRDecoder.receive(reusableFloatBuffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,7 +17,7 @@ package io.github.dsheirer.module.decode.mdc1200;
|
||||
|
||||
import io.github.dsheirer.dsp.afsk.AFSK1200DecoderInstrumented;
|
||||
import io.github.dsheirer.gui.instrument.chart.IInstrumentedAFSK1200Decoder;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
|
||||
/**
|
||||
@@ -44,9 +44,9 @@ public class MDCDecoderInstrumented extends MDCDecoder implements IInstrumentedA
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ReusableBuffer reusableBuffer)
|
||||
public void receive(ReusableFloatBuffer reusableFloatBuffer)
|
||||
{
|
||||
super.receive(reusableBuffer);
|
||||
super.receive(reusableFloatBuffer);
|
||||
|
||||
bufferCount.setValue(bufferCount.intValue() + 1);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ package io.github.dsheirer.module.decode.mpt1327;
|
||||
|
||||
import io.github.dsheirer.dsp.afsk.AFSK1200DecoderInstrumented;
|
||||
import io.github.dsheirer.gui.instrument.chart.IInstrumentedAFSK1200Decoder;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
|
||||
/**
|
||||
@@ -44,9 +44,9 @@ public class MPT1327DecoderInstrumented extends MPT1327Decoder implements IInstr
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ReusableBuffer reusableBuffer)
|
||||
public void receive(ReusableFloatBuffer reusableFloatBuffer)
|
||||
{
|
||||
super.receive(reusableBuffer);
|
||||
super.receive(reusableFloatBuffer);
|
||||
|
||||
bufferCount.setValue(bufferCount.intValue() + 1);
|
||||
}
|
||||
|
||||
@@ -2,13 +2,13 @@ package io.github.dsheirer.module.decode.p25;
|
||||
|
||||
import io.github.dsheirer.dsp.gain.DirectGainControl;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import io.github.dsheirer.sample.real.RealSampleListener;
|
||||
import io.github.dsheirer.sample.real.RealSampleProvider;
|
||||
import io.github.dsheirer.source.ISourceEventListener;
|
||||
import io.github.dsheirer.source.SourceEvent;
|
||||
|
||||
public class C4FMSymbolFilter implements Listener<ReusableBuffer>, ISourceEventListener, RealSampleProvider
|
||||
public class C4FMSymbolFilter implements Listener<ReusableFloatBuffer>, ISourceEventListener, RealSampleProvider
|
||||
{
|
||||
private static final float TAPS[][] =
|
||||
{
|
||||
@@ -215,7 +215,7 @@ public class C4FMSymbolFilter implements Listener<ReusableBuffer>, ISourceEventL
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ReusableBuffer buffer)
|
||||
public void receive(ReusableFloatBuffer buffer)
|
||||
{
|
||||
for(float sample : buffer.getSamples())
|
||||
{
|
||||
|
||||
@@ -24,9 +24,9 @@ import io.github.dsheirer.module.decode.DecoderType;
|
||||
import io.github.dsheirer.module.decode.config.DecodeConfiguration;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.IReusableBufferListener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
|
||||
public class PassportDecoder extends Decoder implements IReusableBufferListener, Listener<ReusableBuffer>
|
||||
public class PassportDecoder extends Decoder implements IReusableBufferListener, Listener<ReusableFloatBuffer>
|
||||
{
|
||||
public static final int PASSPORT_MESSAGE_LENGTH = 68;
|
||||
|
||||
@@ -52,15 +52,15 @@ public class PassportDecoder extends Decoder implements IReusableBufferListener,
|
||||
}
|
||||
|
||||
@Override
|
||||
public Listener<ReusableBuffer> getReusableBufferListener()
|
||||
public Listener<ReusableFloatBuffer> getReusableBufferListener()
|
||||
{
|
||||
return mLTRDecoder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ReusableBuffer reusableBuffer)
|
||||
public void receive(ReusableFloatBuffer reusableFloatBuffer)
|
||||
{
|
||||
mLTRDecoder.receive(reusableBuffer);
|
||||
mLTRDecoder.receive(reusableFloatBuffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,7 +17,7 @@ package io.github.dsheirer.module.decode.tait;
|
||||
|
||||
import io.github.dsheirer.dsp.afsk.AFSK1200DecoderInstrumented;
|
||||
import io.github.dsheirer.gui.instrument.chart.IInstrumentedAFSK1200Decoder;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
|
||||
/**
|
||||
@@ -44,9 +44,9 @@ public class Tait1200DecoderInstrumented extends Tait1200Decoder implements IIns
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ReusableBuffer reusableBuffer)
|
||||
public void receive(ReusableFloatBuffer reusableFloatBuffer)
|
||||
{
|
||||
super.receive(reusableBuffer);
|
||||
super.receive(reusableFloatBuffer);
|
||||
|
||||
bufferCount.setValue(bufferCount.intValue() + 1);
|
||||
}
|
||||
|
||||
@@ -29,8 +29,8 @@ import io.github.dsheirer.module.Module;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.IReusableBufferProvider;
|
||||
import io.github.dsheirer.sample.buffer.IReusableComplexBufferListener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import io.github.dsheirer.source.ISourceEventListener;
|
||||
import io.github.dsheirer.source.SourceEvent;
|
||||
import org.slf4j.Logger;
|
||||
@@ -55,7 +55,7 @@ public class AMDemodulatorModule extends Module implements ISourceEventListener,
|
||||
private double mChannelBandwidth;
|
||||
private double mOutputSampleRate;
|
||||
private RealResampler mResampler;
|
||||
private Listener<ReusableBuffer> mResampledReusableBufferListener;
|
||||
private Listener<ReusableFloatBuffer> mResampledReusableBufferListener;
|
||||
private SourceEventProcessor mSourceEventProcessor = new SourceEventProcessor();
|
||||
|
||||
/**
|
||||
@@ -109,7 +109,7 @@ public class AMDemodulatorModule extends Module implements ISourceEventListener,
|
||||
public void receive(ReusableComplexBuffer basebandBuffer)
|
||||
{
|
||||
ReusableComplexBuffer filteredBuffer = mIQFilter.filter(basebandBuffer);
|
||||
ReusableBuffer demodulated = mDemodulator.demodulate(filteredBuffer);
|
||||
ReusableFloatBuffer demodulated = mDemodulator.demodulate(filteredBuffer);
|
||||
mResampler.resample(demodulated);
|
||||
}
|
||||
|
||||
@@ -117,12 +117,12 @@ public class AMDemodulatorModule extends Module implements ISourceEventListener,
|
||||
* Processes resampled audio buffers produced by the resampler.
|
||||
* @param resampledAudio buffer to process.
|
||||
*/
|
||||
private void processResampledAudio(ReusableBuffer resampledAudio)
|
||||
private void processResampledAudio(ReusableFloatBuffer resampledAudio)
|
||||
{
|
||||
if(mResampledReusableBufferListener != null)
|
||||
{
|
||||
ReusableBuffer filteredAudio = mLowPassFilter.filter(resampledAudio);
|
||||
ReusableBuffer gainApplied = mAGC.process(filteredAudio);
|
||||
ReusableFloatBuffer filteredAudio = mLowPassFilter.filter(resampledAudio);
|
||||
ReusableFloatBuffer gainApplied = mAGC.process(filteredAudio);
|
||||
mResampledReusableBufferListener.receive(gainApplied);
|
||||
}
|
||||
else
|
||||
@@ -172,7 +172,7 @@ public class AMDemodulatorModule extends Module implements ISourceEventListener,
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBufferListener(Listener<ReusableBuffer> listener)
|
||||
public void setBufferListener(Listener<ReusableFloatBuffer> listener)
|
||||
{
|
||||
mResampledReusableBufferListener = listener;
|
||||
}
|
||||
@@ -253,10 +253,10 @@ public class AMDemodulatorModule extends Module implements ISourceEventListener,
|
||||
|
||||
mResampler = new RealResampler(sampleRate, mOutputSampleRate, 2000, 1000);
|
||||
|
||||
mResampler.setListener(new Listener<ReusableBuffer>()
|
||||
mResampler.setListener(new Listener<ReusableFloatBuffer>()
|
||||
{
|
||||
@Override
|
||||
public void receive(ReusableBuffer resampledAudioBuffer)
|
||||
public void receive(ReusableFloatBuffer resampledAudioBuffer)
|
||||
{
|
||||
processResampledAudio(resampledAudioBuffer);
|
||||
}
|
||||
|
||||
@@ -26,8 +26,8 @@ import io.github.dsheirer.module.Module;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.IReusableBufferProvider;
|
||||
import io.github.dsheirer.sample.buffer.IReusableComplexBufferListener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import io.github.dsheirer.source.ISourceEventListener;
|
||||
import io.github.dsheirer.source.SourceEvent;
|
||||
import org.slf4j.Logger;
|
||||
@@ -47,7 +47,7 @@ public class FMDemodulatorModule extends Module implements ISourceEventListener,
|
||||
private FMDemodulator mDemodulator = new FMDemodulator();
|
||||
private RealResampler mResampler;
|
||||
private SourceEventProcessor mSourceEventProcessor = new SourceEventProcessor();
|
||||
private Listener<ReusableBuffer> mResampledReusableBufferListener;
|
||||
private Listener<ReusableFloatBuffer> mResampledReusableBufferListener;
|
||||
private double mChannelBandwidth;
|
||||
private double mOutputSampleRate;
|
||||
|
||||
@@ -106,7 +106,7 @@ public class FMDemodulatorModule extends Module implements ISourceEventListener,
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBufferListener(Listener<ReusableBuffer> listener)
|
||||
public void setBufferListener(Listener<ReusableFloatBuffer> listener)
|
||||
{
|
||||
mResampledReusableBufferListener = listener;
|
||||
}
|
||||
@@ -128,7 +128,7 @@ public class FMDemodulatorModule extends Module implements ISourceEventListener,
|
||||
}
|
||||
|
||||
ReusableComplexBuffer basebandFilteredBuffer = mIQFilter.filter(reusableComplexBuffer);
|
||||
ReusableBuffer demodulatedBuffer = mDemodulator.demodulate(basebandFilteredBuffer);
|
||||
ReusableFloatBuffer demodulatedBuffer = mDemodulator.demodulate(basebandFilteredBuffer);
|
||||
|
||||
if(mResampler != null)
|
||||
{
|
||||
@@ -204,18 +204,18 @@ public class FMDemodulatorModule extends Module implements ISourceEventListener,
|
||||
|
||||
mResampler = new RealResampler(sampleRate, mOutputSampleRate, 2000, 1000);
|
||||
|
||||
mResampler.setListener(new Listener<ReusableBuffer>()
|
||||
mResampler.setListener(new Listener<ReusableFloatBuffer>()
|
||||
{
|
||||
@Override
|
||||
public void receive(ReusableBuffer reusableBuffer)
|
||||
public void receive(ReusableFloatBuffer reusableFloatBuffer)
|
||||
{
|
||||
if(mResampledReusableBufferListener != null)
|
||||
{
|
||||
mResampledReusableBufferListener.receive(reusableBuffer);
|
||||
mResampledReusableBufferListener.receive(reusableFloatBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
reusableBuffer.decrementUserCount();
|
||||
reusableFloatBuffer.decrementUserCount();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014-2016 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/>
|
||||
* sdr-trunk
|
||||
* Copyright (C) 2014-2018 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.record;
|
||||
|
||||
@@ -22,7 +20,7 @@ import io.github.dsheirer.gui.editor.Editor;
|
||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.JCheckBox;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.List;
|
||||
@@ -30,121 +28,168 @@ import java.util.List;
|
||||
public class RecordConfigurationEditor extends Editor<Channel>
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
private JCheckBox mAudioRecorder;
|
||||
private JCheckBox mBasebandRecorder;
|
||||
private JCheckBox mTrafficBasebandRecorder;
|
||||
private JCheckBox mBitstreamRecorder;
|
||||
private JCheckBox mTrafficBitstreamRecorder;
|
||||
|
||||
public RecordConfigurationEditor()
|
||||
{
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
setLayout( new MigLayout( "fill,wrap 4", "", "[][grow]" ) );
|
||||
|
||||
mAudioRecorder = new JCheckBox( "Audio" );
|
||||
mAudioRecorder.setEnabled( false );
|
||||
mAudioRecorder.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
setModified( true );
|
||||
}
|
||||
} );
|
||||
add( mAudioRecorder );
|
||||
setLayout(new MigLayout("fill,wrap 2", "", "[][][][grow]"));
|
||||
|
||||
mBasebandRecorder = new JCheckBox( "Baseband I/Q" );
|
||||
mBasebandRecorder.setEnabled( false );
|
||||
mBasebandRecorder.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
setModified( true );
|
||||
}
|
||||
} );
|
||||
add( mBasebandRecorder );
|
||||
mAudioRecorder = new JCheckBox("Audio");
|
||||
mAudioRecorder.setEnabled(false);
|
||||
mAudioRecorder.addActionListener(new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
setModified(true);
|
||||
}
|
||||
});
|
||||
add(mAudioRecorder, "wrap");
|
||||
|
||||
mTrafficBasebandRecorder = new JCheckBox( "Traffic Channel Baseband I/Q" );
|
||||
mTrafficBasebandRecorder.setEnabled( false );
|
||||
mTrafficBasebandRecorder.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
setModified( true );
|
||||
}
|
||||
} );
|
||||
add( mTrafficBasebandRecorder );
|
||||
mBasebandRecorder = new JCheckBox("Baseband I/Q");
|
||||
mBasebandRecorder.setEnabled(false);
|
||||
mBasebandRecorder.addActionListener(new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
setModified(true);
|
||||
}
|
||||
});
|
||||
add(mBasebandRecorder);
|
||||
|
||||
mTrafficBasebandRecorder = new JCheckBox("Traffic Channel Baseband I/Q");
|
||||
mTrafficBasebandRecorder.setEnabled(false);
|
||||
mTrafficBasebandRecorder.addActionListener(new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
setModified(true);
|
||||
}
|
||||
});
|
||||
add(mTrafficBasebandRecorder);
|
||||
|
||||
mBitstreamRecorder = new JCheckBox("Demodulated Bitstream");
|
||||
mBitstreamRecorder.setEnabled(false);
|
||||
mBitstreamRecorder.addActionListener(new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
setModified(true);
|
||||
}
|
||||
});
|
||||
add(mBitstreamRecorder);
|
||||
|
||||
mTrafficBitstreamRecorder = new JCheckBox("Traffic Channel Bitstream");
|
||||
mTrafficBitstreamRecorder.setEnabled(false);
|
||||
mTrafficBitstreamRecorder.addActionListener(new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
setModified(true);
|
||||
}
|
||||
});
|
||||
add(mTrafficBitstreamRecorder);
|
||||
}
|
||||
|
||||
private void setControlsEnabled( boolean enabled )
|
||||
|
||||
private void setControlsEnabled(boolean enabled)
|
||||
{
|
||||
if( mAudioRecorder.isEnabled() != enabled )
|
||||
{
|
||||
mAudioRecorder.setEnabled( enabled );
|
||||
}
|
||||
|
||||
if( mBasebandRecorder.isEnabled() != enabled )
|
||||
{
|
||||
mBasebandRecorder.setEnabled( enabled );
|
||||
}
|
||||
|
||||
if( mTrafficBasebandRecorder.isEnabled() != enabled )
|
||||
{
|
||||
mTrafficBasebandRecorder.setEnabled( enabled );
|
||||
}
|
||||
if(mAudioRecorder.isEnabled() != enabled)
|
||||
{
|
||||
mAudioRecorder.setEnabled(enabled);
|
||||
}
|
||||
|
||||
if(mBasebandRecorder.isEnabled() != enabled)
|
||||
{
|
||||
mBasebandRecorder.setEnabled(enabled);
|
||||
}
|
||||
|
||||
if(mTrafficBasebandRecorder.isEnabled() != enabled)
|
||||
{
|
||||
mTrafficBasebandRecorder.setEnabled(enabled);
|
||||
}
|
||||
|
||||
if(mBitstreamRecorder.isEnabled() != enabled)
|
||||
{
|
||||
mBitstreamRecorder.setEnabled(enabled);
|
||||
}
|
||||
|
||||
if(mTrafficBitstreamRecorder.isEnabled() != enabled)
|
||||
{
|
||||
mTrafficBitstreamRecorder.setEnabled(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public void save()
|
||||
{
|
||||
if( hasItem() && isModified() )
|
||||
{
|
||||
RecordConfiguration config = getItem().getRecordConfiguration();
|
||||
|
||||
config.clearRecorders();
|
||||
|
||||
if( mAudioRecorder.isSelected() )
|
||||
{
|
||||
config.addRecorder( RecorderType.AUDIO );
|
||||
}
|
||||
|
||||
if( mBasebandRecorder.isSelected() )
|
||||
{
|
||||
config.addRecorder( RecorderType.BASEBAND );
|
||||
}
|
||||
|
||||
if( mTrafficBasebandRecorder.isSelected() )
|
||||
{
|
||||
config.addRecorder( RecorderType.TRAFFIC_BASEBAND );
|
||||
}
|
||||
}
|
||||
|
||||
setModified( false );
|
||||
if(hasItem() && isModified())
|
||||
{
|
||||
RecordConfiguration config = getItem().getRecordConfiguration();
|
||||
|
||||
config.clearRecorders();
|
||||
|
||||
if(mAudioRecorder.isSelected())
|
||||
{
|
||||
config.addRecorder(RecorderType.AUDIO);
|
||||
}
|
||||
|
||||
if(mBasebandRecorder.isSelected())
|
||||
{
|
||||
config.addRecorder(RecorderType.BASEBAND);
|
||||
}
|
||||
|
||||
if(mTrafficBasebandRecorder.isSelected())
|
||||
{
|
||||
config.addRecorder(RecorderType.TRAFFIC_BASEBAND);
|
||||
}
|
||||
|
||||
if(mBitstreamRecorder.isSelected())
|
||||
{
|
||||
config.addRecorder(RecorderType.DEMODULATED_BIT_STREAM);
|
||||
}
|
||||
|
||||
if(mTrafficBitstreamRecorder.isSelected())
|
||||
{
|
||||
config.addRecorder(RecorderType.TRAFFIC_DEMODULATED_BIT_STREAM);
|
||||
}
|
||||
}
|
||||
|
||||
setModified(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItem(Channel channel)
|
||||
{
|
||||
super.setItem(channel);
|
||||
|
||||
if(hasItem())
|
||||
{
|
||||
setControlsEnabled(true);
|
||||
|
||||
List<RecorderType> recorders = getItem().getRecordConfiguration().getRecorders();
|
||||
mAudioRecorder.setSelected(recorders.contains(RecorderType.AUDIO));
|
||||
mBasebandRecorder.setSelected(recorders.contains(RecorderType.BASEBAND));
|
||||
mTrafficBasebandRecorder.setSelected(recorders.contains(RecorderType.TRAFFIC_BASEBAND));
|
||||
mBitstreamRecorder.setSelected(recorders.contains(RecorderType.DEMODULATED_BIT_STREAM));
|
||||
mTrafficBitstreamRecorder.setSelected(recorders.contains(RecorderType.TRAFFIC_DEMODULATED_BIT_STREAM));
|
||||
}
|
||||
else
|
||||
{
|
||||
setControlsEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItem( Channel channel )
|
||||
{
|
||||
super.setItem( channel );
|
||||
|
||||
if( hasItem() )
|
||||
{
|
||||
setControlsEnabled( true );
|
||||
|
||||
List<RecorderType> recorders = getItem().getRecordConfiguration().getRecorders();
|
||||
mAudioRecorder.setSelected( recorders.contains( RecorderType.AUDIO ) );
|
||||
mBasebandRecorder.setSelected( recorders.contains( RecorderType.BASEBAND ) );
|
||||
mTrafficBasebandRecorder.setSelected( recorders.contains( RecorderType.TRAFFIC_BASEBAND ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
setControlsEnabled( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* 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 io.github.dsheirer.record;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class Recorder
|
||||
{
|
||||
RecorderType mRecorderType;
|
||||
|
||||
public Recorder()
|
||||
{
|
||||
}
|
||||
|
||||
public String getFileName()
|
||||
{
|
||||
return "No Recording";
|
||||
}
|
||||
|
||||
public void start() throws IOException
|
||||
{
|
||||
}
|
||||
|
||||
public void stop() throws IOException
|
||||
{
|
||||
}
|
||||
|
||||
public void pause()
|
||||
{
|
||||
}
|
||||
|
||||
public void resume()
|
||||
{
|
||||
}
|
||||
|
||||
public Recorder( RecorderType type )
|
||||
{
|
||||
mRecorderType = type;
|
||||
}
|
||||
|
||||
public RecorderType getRecorderType()
|
||||
{
|
||||
return mRecorderType;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
/*
|
||||
* *********************************************************************************************************************
|
||||
/*******************************************************************************
|
||||
* sdr-trunk
|
||||
* Copyright (C) 2014-2017 Dennis Sheirer
|
||||
* Copyright (C) 2014-2018 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
|
||||
@@ -12,8 +11,8 @@
|
||||
*
|
||||
* 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.record;
|
||||
|
||||
import io.github.dsheirer.channel.metadata.Metadata;
|
||||
@@ -29,6 +28,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
@@ -228,13 +228,18 @@ public class RecorderManager implements Listener<ReusableAudioPacket>
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public Path getRecordingBasePath()
|
||||
{
|
||||
return SystemProperties.getInstance().getApplicationFolder("recordings");
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a baseband recorder for use in a processing chain.
|
||||
*/
|
||||
public ComplexBufferWaveRecorder getBasebandRecorder(String channelName)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(SystemProperties.getInstance().getApplicationFolder("recordings"));
|
||||
sb.append(getRecordingBasePath());
|
||||
sb.append(File.separator).append(channelName).append("_baseband");
|
||||
|
||||
return new ComplexBufferWaveRecorder(BASEBAND_SAMPLE_RATE, sb.toString());
|
||||
|
||||
@@ -1,30 +1,59 @@
|
||||
/*******************************************************************************
|
||||
* 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/>
|
||||
* sdr-trunk
|
||||
* Copyright (C) 2014-2018 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.record;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
/**
|
||||
* Supported recorder types.
|
||||
*/
|
||||
public enum RecorderType
|
||||
{
|
||||
/**
|
||||
* Audio - 8kHz PCM
|
||||
*/
|
||||
AUDIO( "Audio (.wav)"),
|
||||
BASEBAND( "Baseband I/Q (.wav)"),
|
||||
TRAFFIC_BASEBAND( "Traffic Channel Baseband I/Q (.wav)" );
|
||||
|
||||
|
||||
/**
|
||||
* Baseband, 16-bit complex inphase/quadrature samples at the channel sample rate.
|
||||
*/
|
||||
BASEBAND( "Baseband I/Q (.wav)"),
|
||||
|
||||
/**
|
||||
* Demodulated bit stream at the baud rate of the decoder
|
||||
*/
|
||||
DEMODULATED_BIT_STREAM("Demodulated Bitstream (.bits)"),
|
||||
|
||||
/**
|
||||
* Traffic channel baseband, 16-bit complex inphase/quadrature samples at the channel sample rate.
|
||||
*/
|
||||
TRAFFIC_BASEBAND( "Traffic Channel Baseband I/Q (.wav)" ),
|
||||
|
||||
/**
|
||||
* Traffic channel demodulated bit stream at the baud rate of the decoder
|
||||
*/
|
||||
TRAFFIC_DEMODULATED_BIT_STREAM("Traffic Channel Demodulated Bitstream (.bits)");
|
||||
|
||||
private String mDisplayString;
|
||||
|
||||
|
||||
/**
|
||||
* Recorders available to all decoders
|
||||
*/
|
||||
public static final EnumSet<RecorderType> DEFAULT_RECORDER_TYPES = EnumSet.of(AUDIO, BASEBAND, TRAFFIC_BASEBAND);
|
||||
|
||||
RecorderType( String displayString )
|
||||
{
|
||||
mDisplayString = displayString;
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
/*******************************************************************************
|
||||
* sdr-trunk
|
||||
* Copyright (C) 2014-2018 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.record.binary;
|
||||
|
||||
import io.github.dsheirer.dsp.filter.channelizer.ContinuousReusableBufferProcessor;
|
||||
import io.github.dsheirer.module.Module;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.IReusableByteBufferListener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableByteBuffer;
|
||||
import io.github.dsheirer.util.TimeStamp;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* Binary recorder module for recording demodulated bit/byte streams
|
||||
*
|
||||
* Designed to record reusable byte buffers generated by a channel decoder.
|
||||
*
|
||||
* The contents of the file are the raw bytes as demodulated by the decoder with
|
||||
* no header or timestamps, other than the timestamp included in the filename.
|
||||
*/
|
||||
public class BinaryRecorder extends Module implements IReusableByteBufferListener
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(BinaryRecorder.class);
|
||||
|
||||
private ContinuousReusableBufferProcessor<ReusableByteBuffer> mBufferProcessor =
|
||||
new ContinuousReusableBufferProcessor<>(500, 50);
|
||||
|
||||
private AtomicBoolean mRunning = new AtomicBoolean();
|
||||
private Path mBaseRecordingPath;
|
||||
private String mRecordingIdentifier;
|
||||
private BinaryWriter mBinaryWriter = new BinaryWriter();
|
||||
|
||||
/**
|
||||
* Constructs a binary recorder.
|
||||
*
|
||||
* @param baseRecordingPath where the recording should be created
|
||||
* @param recordingIdentifier to include in the recording file name.
|
||||
*/
|
||||
public BinaryRecorder(Path baseRecordingPath, String recordingIdentifier)
|
||||
{
|
||||
mBaseRecordingPath = baseRecordingPath;
|
||||
mRecordingIdentifier = recordingIdentifier;
|
||||
mBufferProcessor.setListener(mBinaryWriter);
|
||||
}
|
||||
|
||||
public void start()
|
||||
{
|
||||
if(mRunning.compareAndSet(false, true))
|
||||
{
|
||||
try
|
||||
{
|
||||
mBinaryWriter.start(getRecordingPath());
|
||||
mBufferProcessor.start();
|
||||
}
|
||||
catch(IOException io)
|
||||
{
|
||||
mLog.error("Error starting binary baseband recorder", io);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void stop()
|
||||
{
|
||||
if(mRunning.compareAndSet(true, false))
|
||||
{
|
||||
if(mBufferProcessor != null)
|
||||
{
|
||||
mBufferProcessor.flushAndStop();
|
||||
mBufferProcessor.setListener(null);
|
||||
|
||||
try
|
||||
{
|
||||
mBinaryWriter.stop();
|
||||
}
|
||||
catch(IOException ioe)
|
||||
{
|
||||
mLog.error("Error stopping binary recorder", ioe);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a recording path/file name using the base path and a timestamped
|
||||
* filename with the recording identifier.
|
||||
*
|
||||
* @return path to use for the recording file
|
||||
*/
|
||||
private Path getRecordingPath()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(TimeStamp.getTimeStamp("_"));
|
||||
sb.append("_");
|
||||
sb.append(mRecordingIdentifier);
|
||||
sb.append(".bits");
|
||||
|
||||
return mBaseRecordingPath.resolve(sb.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Listener<ReusableByteBuffer> getReusableByteBufferListener()
|
||||
{
|
||||
return mBufferProcessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose()
|
||||
{
|
||||
stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Binary writer implementation for reusable byte buffers delivered from buffer processor
|
||||
*/
|
||||
public class BinaryWriter implements Listener<List<ReusableByteBuffer>>
|
||||
{
|
||||
private Path mCurrentPath;
|
||||
private WritableByteChannel mWritableByteChannel;
|
||||
|
||||
public void start(Path path) throws IOException
|
||||
{
|
||||
mCurrentPath = path;
|
||||
mWritableByteChannel = Files.newByteChannel(path,
|
||||
EnumSet.of(StandardOpenOption.CREATE, StandardOpenOption.WRITE));
|
||||
}
|
||||
|
||||
public void stop() throws IOException
|
||||
{
|
||||
if(mWritableByteChannel != null)
|
||||
{
|
||||
mWritableByteChannel.close();
|
||||
}
|
||||
|
||||
mWritableByteChannel = null;
|
||||
mCurrentPath = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(List<ReusableByteBuffer> reusableComplexBuffers)
|
||||
{
|
||||
for(ReusableByteBuffer buffer: reusableComplexBuffers)
|
||||
{
|
||||
if(mWritableByteChannel != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
ByteBuffer byteBuffer = ByteBuffer.wrap(buffer.getSamplesCopy());
|
||||
mWritableByteChannel.write(byteBuffer);
|
||||
}
|
||||
catch(IOException ioe)
|
||||
{
|
||||
mLog.error("Error recording demodulated bits to file [" +
|
||||
(mCurrentPath != null ? mCurrentPath.toString() : "no file") + "] - stopping recorder");
|
||||
|
||||
try
|
||||
{
|
||||
stop();
|
||||
}
|
||||
catch(IOException ioe2)
|
||||
{
|
||||
mLog.error("Error stopping recorder after write error", ioe2.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buffer.decrementUserCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.github.dsheirer.sample;
|
||||
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
@@ -56,7 +56,7 @@ public class ConversionUtils
|
||||
* Converts the float samples in a complex buffer to a little endian 16-bit
|
||||
* buffer
|
||||
*/
|
||||
public static ByteBuffer convertToSigned16BitSamples(ReusableBuffer buffer)
|
||||
public static ByteBuffer convertToSigned16BitSamples(ReusableFloatBuffer buffer)
|
||||
{
|
||||
return convertToSigned16BitSamples(buffer.getSamples());
|
||||
}
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
******************************************************************************/
|
||||
package io.github.dsheirer.sample.adapter;
|
||||
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
|
||||
public abstract class AbstractSampleAdapter<T extends ReusableBuffer>
|
||||
public abstract class AbstractSampleAdapter<T extends ReusableFloatBuffer>
|
||||
{
|
||||
public abstract T convert(byte[] sampleBytes);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
******************************************************************************/
|
||||
package io.github.dsheirer.sample.adapter;
|
||||
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import io.github.dsheirer.source.mixer.MixerChannel;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.slf4j.Logger;
|
||||
@@ -46,10 +46,10 @@ public class RealChannelShortAdapter extends RealSampleAdapter
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReusableBuffer convert(byte[] samples)
|
||||
public ReusableFloatBuffer convert(byte[] samples)
|
||||
{
|
||||
ReusableBuffer reusableBuffer = getBuffer(samples.length / 4);
|
||||
float[] convertedSamples = reusableBuffer.getSamples();
|
||||
ReusableFloatBuffer reusableFloatBuffer = getBuffer(samples.length / 4);
|
||||
float[] convertedSamples = reusableFloatBuffer.getSamples();
|
||||
|
||||
mByteBuffer = ByteBuffer.wrap(samples);
|
||||
|
||||
@@ -76,7 +76,7 @@ public class RealChannelShortAdapter extends RealSampleAdapter
|
||||
}
|
||||
}
|
||||
|
||||
return reusableBuffer;
|
||||
return reusableFloatBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
******************************************************************************/
|
||||
package io.github.dsheirer.sample.adapter;
|
||||
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBufferQueue;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
|
||||
public abstract class RealSampleAdapter extends AbstractSampleAdapter<ReusableBuffer>
|
||||
public abstract class RealSampleAdapter extends AbstractSampleAdapter<ReusableFloatBuffer>
|
||||
{
|
||||
private ReusableBufferQueue mReusableBufferQueue;
|
||||
|
||||
@@ -32,7 +32,7 @@ public abstract class RealSampleAdapter extends AbstractSampleAdapter<ReusableBu
|
||||
mReusableBufferQueue = new ReusableBufferQueue(debugName);
|
||||
}
|
||||
|
||||
protected ReusableBuffer getBuffer(int size)
|
||||
protected ReusableFloatBuffer getBuffer(int size)
|
||||
{
|
||||
return mReusableBufferQueue.getBuffer(size);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
******************************************************************************/
|
||||
package io.github.dsheirer.sample.adapter;
|
||||
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
@@ -40,10 +40,10 @@ public class RealShortAdapter extends RealSampleAdapter
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReusableBuffer convert(byte[] samples)
|
||||
public ReusableFloatBuffer convert(byte[] samples)
|
||||
{
|
||||
ReusableBuffer reusableBuffer = getBuffer(samples.length / 2);
|
||||
float[] convertedSamples = reusableBuffer.getSamples();
|
||||
ReusableFloatBuffer reusableFloatBuffer = getBuffer(samples.length / 2);
|
||||
float[] convertedSamples = reusableFloatBuffer.getSamples();
|
||||
|
||||
int pointer = 0;
|
||||
|
||||
@@ -58,7 +58,7 @@ public class RealShortAdapter extends RealSampleAdapter
|
||||
pointer++;
|
||||
}
|
||||
|
||||
return reusableBuffer;
|
||||
return reusableFloatBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,5 +19,5 @@ import io.github.dsheirer.sample.Listener;
|
||||
|
||||
public interface IReusableBufferListener
|
||||
{
|
||||
Listener<ReusableBuffer> getReusableBufferListener();
|
||||
Listener<ReusableFloatBuffer> getReusableBufferListener();
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ public interface IReusableBufferProvider
|
||||
/**
|
||||
* Adds the listener to receive complex buffer samples
|
||||
*/
|
||||
void setBufferListener(Listener<ReusableBuffer> listener);
|
||||
void setBufferListener(Listener<ReusableFloatBuffer> listener);
|
||||
|
||||
/**
|
||||
* Removes the listener from receiving complex buffer samples
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*******************************************************************************
|
||||
* sdr-trunk
|
||||
* Copyright (C) 2014-2018 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.sample.buffer;
|
||||
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
|
||||
public interface IReusableByteBufferListener<ReusableByteBuffer>
|
||||
{
|
||||
Listener<ReusableByteBuffer> getReusableByteBufferListener();
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*******************************************************************************
|
||||
* sdr-trunk
|
||||
* Copyright (C) 2014-2018 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.sample.buffer;
|
||||
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
|
||||
public interface IReusableByteBufferProvider
|
||||
{
|
||||
/**
|
||||
* Adds the listener to receive complex buffer samples
|
||||
*/
|
||||
void setBufferListener(Listener<ReusableByteBuffer> listener);
|
||||
|
||||
/**
|
||||
* Removes the listener from receiving complex buffer samples
|
||||
*/
|
||||
void removeBufferListener(Listener<ReusableByteBuffer> listener);
|
||||
|
||||
/**
|
||||
* Indicates if there are any complex buffer listeners registered
|
||||
*/
|
||||
boolean hasBufferListeners();
|
||||
}
|
||||
@@ -113,16 +113,16 @@ public class ReusableAudioPacket extends AbstractReusableBuffer
|
||||
* Loads a copy of the float sample data from the reusable buffer into this audio packet, resizing the
|
||||
* internal audio sample buffer as necessary.
|
||||
*
|
||||
* @param reusableBuffer to load audio sample data from
|
||||
* @param reusableFloatBuffer to load audio sample data from
|
||||
*/
|
||||
public void loadAudioFrom(ReusableBuffer reusableBuffer)
|
||||
public void loadAudioFrom(ReusableFloatBuffer reusableFloatBuffer)
|
||||
{
|
||||
if(reusableBuffer.getSamples().length != mAudioSamples.length)
|
||||
if(reusableFloatBuffer.getSamples().length != mAudioSamples.length)
|
||||
{
|
||||
resize(reusableBuffer.getSamples().length);
|
||||
resize(reusableFloatBuffer.getSamples().length);
|
||||
}
|
||||
|
||||
System.arraycopy(reusableBuffer.getSamples(), 0, mAudioSamples, 0, reusableBuffer.getSamples().length);
|
||||
System.arraycopy(reusableFloatBuffer.getSamples(), 0, mAudioSamples, 0, reusableFloatBuffer.getSamples().length);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,16 +19,16 @@ import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.real.RealSampleListener;
|
||||
|
||||
/**
|
||||
* Assembles single float samples into a ReusableBuffer containing an array of floats
|
||||
* Assembles single float samples into a ReusableFloatBuffer containing an array of floats
|
||||
*/
|
||||
public class ReusableBufferAssembler implements RealSampleListener
|
||||
{
|
||||
private int mBufferSize;
|
||||
private int mBufferPointer;
|
||||
private ReusableBuffer mCurrentBuffer;
|
||||
private ReusableFloatBuffer mCurrentBuffer;
|
||||
private ReusableBufferQueue mReusableBufferQueue = new ReusableBufferQueue("Real");
|
||||
|
||||
private Listener<ReusableBuffer> mListener;
|
||||
private Listener<ReusableFloatBuffer> mListener;
|
||||
|
||||
public ReusableBufferAssembler(int bufferSize)
|
||||
{
|
||||
@@ -73,7 +73,7 @@ public class ReusableBufferAssembler implements RealSampleListener
|
||||
}
|
||||
}
|
||||
|
||||
public void setListener(Listener<ReusableBuffer> listener)
|
||||
public void setListener(Listener<ReusableFloatBuffer> listener)
|
||||
{
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package io.github.dsheirer.sample.buffer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class ReusableBufferQueue extends AbstractReusableBufferQueue<ReusableBuffer>
|
||||
public class ReusableBufferQueue extends AbstractReusableBufferQueue<ReusableFloatBuffer>
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(ReusableBufferQueue.class);
|
||||
|
||||
@@ -35,13 +35,13 @@ public class ReusableBufferQueue extends AbstractReusableBufferQueue<ReusableBuf
|
||||
* @param size of the samples that will be loaded into the buffer
|
||||
* @return a reusable buffer
|
||||
*/
|
||||
public ReusableBuffer getBuffer(int size)
|
||||
public ReusableFloatBuffer getBuffer(int size)
|
||||
{
|
||||
ReusableBuffer buffer = getRecycledBuffer();
|
||||
ReusableFloatBuffer buffer = getRecycledBuffer();
|
||||
|
||||
if(buffer == null)
|
||||
{
|
||||
buffer = new ReusableBuffer(this, new float[size]);
|
||||
buffer = new ReusableFloatBuffer(this, new float[size]);
|
||||
buffer.setDebugName("Owner:" + getDebugName());
|
||||
incrementBufferCount();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/*******************************************************************************
|
||||
* sdr-trunk
|
||||
* Copyright (C) 2014-2018 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.sample.buffer;
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
public class ReusableByteBuffer extends AbstractReusableBuffer
|
||||
{
|
||||
private byte[] mSamples;
|
||||
|
||||
/**
|
||||
* Creates a reusable, timestamped byte buffer using the specified time in milliseconds.
|
||||
*
|
||||
* NOTE: reusability of this buffer requires strict user count tracking. Each component that receives this
|
||||
* buffer should not modify the buffer contents. Each component should also increment the user count before
|
||||
* sending this buffer to another component and should decrement the user count when finished using this buffer.
|
||||
*
|
||||
* @param bufferDisposedListener to be notified when all consumers/users are finished using the buffer
|
||||
* @param bytes of data
|
||||
* @param timestamp in millis for the buffer
|
||||
*/
|
||||
ReusableByteBuffer(IReusableBufferDisposedListener bufferDisposedListener, byte[] bytes, long timestamp)
|
||||
{
|
||||
super(bufferDisposedListener, timestamp);
|
||||
mSamples = bytes;
|
||||
|
||||
Validate.notNull(bufferDisposedListener, "Reusable Byte Buffer Listener cannot be null");
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a timestamped byte buffer using the current system time in milliseconds.
|
||||
*
|
||||
* NOTE: reusability of this buffer requires strict user count tracking. Each component that receives this
|
||||
* buffer should not modify the buffer contents. Each component should also increment the user count before
|
||||
* sending this buffer to another component and should decrement the user count when finished using this buffer.
|
||||
*
|
||||
* @param bufferDisposedListener to be notified when all consumers are finished using the buffer
|
||||
* @param bytes of data
|
||||
*/
|
||||
public ReusableByteBuffer(IReusableBufferDisposedListener bufferDisposedListener, byte[] bytes)
|
||||
{
|
||||
this(bufferDisposedListener, bytes, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
/**
|
||||
* Samples for this buffer
|
||||
*/
|
||||
public byte[] getBytes()
|
||||
{
|
||||
return mSamples;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of the samples from this buffer
|
||||
*/
|
||||
public byte[] getSamplesCopy()
|
||||
{
|
||||
byte[] bytes = getBytes();
|
||||
byte[] copy = new byte[bytes.length];
|
||||
System.arraycopy(bytes, 0, copy, 0, bytes.length);
|
||||
return copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of bytes contained in this buffer
|
||||
*/
|
||||
public int getSampleCount()
|
||||
{
|
||||
return getBytes().length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resizes the internal array to the size argument
|
||||
*
|
||||
* @param size for the internal array
|
||||
*/
|
||||
protected void resize(int size)
|
||||
{
|
||||
if(mSamples.length != size)
|
||||
{
|
||||
mSamples = new byte[size];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*******************************************************************************
|
||||
* sdr-trunk
|
||||
* Copyright (C) 2014-2018 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.sample.buffer;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class ReusableByteBufferQueue extends AbstractReusableBufferQueue<ReusableByteBuffer>
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(ReusableByteBufferQueue.class);
|
||||
|
||||
public ReusableByteBufferQueue(String debugName)
|
||||
{
|
||||
super(debugName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reusable buffer from an internal recycling queue, or creates a new buffer if there are currently no
|
||||
* buffers available for reuse. The user count is set to one and must be managed throughout the lifecycle
|
||||
* of the buffer.
|
||||
*
|
||||
* @param size of the samples that will be loaded into the buffer
|
||||
* @return a reusable buffer
|
||||
*/
|
||||
public ReusableByteBuffer getBuffer(int size)
|
||||
{
|
||||
ReusableByteBuffer buffer = getRecycledBuffer();
|
||||
|
||||
if(buffer == null)
|
||||
{
|
||||
buffer = new ReusableByteBuffer(this, new byte[size]);
|
||||
buffer.setDebugName("Owner:" + getDebugName());
|
||||
incrementBufferCount();
|
||||
}
|
||||
|
||||
buffer.resize(size);
|
||||
buffer.incrementUserCount();
|
||||
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@
|
||||
******************************************************************************/
|
||||
package io.github.dsheirer.sample.buffer;
|
||||
|
||||
public class ReusableComplexBuffer extends ReusableBuffer
|
||||
public class ReusableComplexBuffer extends ReusableFloatBuffer
|
||||
{
|
||||
/**
|
||||
* Creates a reusable, timestamped complex buffer using the specified time in milliseconds.
|
||||
|
||||
@@ -19,7 +19,7 @@ import org.apache.commons.lang3.Validate;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
public class ReusableBuffer extends AbstractReusableBuffer
|
||||
public class ReusableFloatBuffer extends AbstractReusableBuffer
|
||||
{
|
||||
private float[] mSamples;
|
||||
|
||||
@@ -34,7 +34,7 @@ public class ReusableBuffer extends AbstractReusableBuffer
|
||||
* @param samples of data
|
||||
* @param timestamp in millis for the buffer
|
||||
*/
|
||||
ReusableBuffer(IReusableBufferDisposedListener bufferDisposedListener, float[] samples, long timestamp)
|
||||
ReusableFloatBuffer(IReusableBufferDisposedListener bufferDisposedListener, float[] samples, long timestamp)
|
||||
{
|
||||
super(bufferDisposedListener, timestamp);
|
||||
mSamples = samples;
|
||||
@@ -79,7 +79,7 @@ public class ReusableBuffer extends AbstractReusableBuffer
|
||||
* @param bufferDisposedListener to be notified when all consumers are finished using the buffer
|
||||
* @param samples of data
|
||||
*/
|
||||
public ReusableBuffer(IReusableBufferDisposedListener bufferDisposedListener, float[] samples)
|
||||
public ReusableFloatBuffer(IReusableBufferDisposedListener bufferDisposedListener, float[] samples)
|
||||
{
|
||||
this(bufferDisposedListener, samples, System.currentTimeMillis());
|
||||
}
|
||||
@@ -2,10 +2,10 @@ package io.github.dsheirer.source;
|
||||
|
||||
import io.github.dsheirer.sample.Provider;
|
||||
import io.github.dsheirer.sample.SampleType;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
|
||||
|
||||
public abstract class RealSource extends Source implements Provider<ReusableBuffer>
|
||||
public abstract class RealSource extends Source implements Provider<ReusableFloatBuffer>
|
||||
{
|
||||
@Override
|
||||
public SampleType getSampleType()
|
||||
|
||||
@@ -17,7 +17,7 @@ package io.github.dsheirer.source.mixer;
|
||||
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.adapter.AbstractSampleAdapter;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import io.github.dsheirer.source.SourceEvent;
|
||||
import io.github.dsheirer.source.heartbeat.HeartbeatManager;
|
||||
import io.github.dsheirer.util.ThreadPool;
|
||||
@@ -37,7 +37,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
* the samples to an array of floats using the specified adapter. Dispatches float arrays to the registered
|
||||
* buffer listener.
|
||||
*/
|
||||
public class MixerReader<T extends ReusableBuffer> implements Runnable
|
||||
public class MixerReader<T extends ReusableFloatBuffer> implements Runnable
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(MixerReader.class);
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ package io.github.dsheirer.source.mixer;
|
||||
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.adapter.AbstractSampleAdapter;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import io.github.dsheirer.source.RealSource;
|
||||
import io.github.dsheirer.source.SourceEvent;
|
||||
|
||||
@@ -101,7 +101,7 @@ public class RealMixerSource extends RealSource
|
||||
/**
|
||||
* Sets the listener to receive sample data in reusable buffers.
|
||||
*/
|
||||
public void setListener(Listener<ReusableBuffer> listener)
|
||||
public void setListener(Listener<ReusableFloatBuffer> listener)
|
||||
{
|
||||
mMixerReader.setBufferListener(listener);
|
||||
}
|
||||
@@ -110,7 +110,7 @@ public class RealMixerSource extends RealSource
|
||||
* Removes the listener from receiving sample data.
|
||||
* @param listener
|
||||
*/
|
||||
public void removeListener(Listener<ReusableBuffer> listener)
|
||||
public void removeListener(Listener<ReusableFloatBuffer> listener)
|
||||
{
|
||||
mMixerReader.removeBufferListener();
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@ package io.github.dsheirer.source.wave;
|
||||
|
||||
import io.github.dsheirer.sample.ConversionUtils;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBufferQueue;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import io.github.dsheirer.source.IControllableFileSource;
|
||||
import io.github.dsheirer.source.IFrameLocationListener;
|
||||
import io.github.dsheirer.source.RealSource;
|
||||
@@ -45,7 +45,7 @@ public class RealWaveSource extends RealSource implements IControllableFileSourc
|
||||
private int mBytesPerFrame;
|
||||
private int mFrameCounter = 0;
|
||||
private long mFrequency = 0;
|
||||
private Listener<ReusableBuffer> mListener;
|
||||
private Listener<ReusableFloatBuffer> mListener;
|
||||
private AudioInputStream mInputStream;
|
||||
private File mFile;
|
||||
|
||||
@@ -230,10 +230,10 @@ public class RealWaveSource extends RealSource implements IControllableFileSourc
|
||||
|
||||
float[] samples = ConversionUtils.convertFromSigned16BitSamples(buffer);
|
||||
|
||||
ReusableBuffer reusableBuffer = mReusableBufferQueue.getBuffer(samples.length);
|
||||
reusableBuffer.reloadFrom(samples, System.currentTimeMillis());
|
||||
ReusableFloatBuffer reusableFloatBuffer = mReusableBufferQueue.getBuffer(samples.length);
|
||||
reusableFloatBuffer.reloadFrom(samples, System.currentTimeMillis());
|
||||
|
||||
mListener.receive(reusableBuffer);
|
||||
mListener.receive(reusableFloatBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -242,7 +242,7 @@ public class RealWaveSource extends RealSource implements IControllableFileSourc
|
||||
* Registers the listener to receive sample buffers as they are read from the wave file
|
||||
*/
|
||||
@Override
|
||||
public void setListener(Listener<ReusableBuffer> listener)
|
||||
public void setListener(Listener<ReusableFloatBuffer> listener)
|
||||
{
|
||||
mListener = listener;
|
||||
}
|
||||
@@ -251,7 +251,7 @@ public class RealWaveSource extends RealSource implements IControllableFileSourc
|
||||
* Unregisters the listener from receiving sample buffers
|
||||
*/
|
||||
@Override
|
||||
public void removeListener(Listener<ReusableBuffer> listener)
|
||||
public void removeListener(Listener<ReusableFloatBuffer> listener)
|
||||
{
|
||||
mListener = null;
|
||||
}
|
||||
|
||||
@@ -26,9 +26,9 @@ import io.github.dsheirer.dsp.filter.smoothing.SmoothingFilter.SmoothingType;
|
||||
import io.github.dsheirer.module.ProcessingChain;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.SampleType;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableComplexBufferQueue;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import io.github.dsheirer.settings.ColorSetting.ColorSettingName;
|
||||
import io.github.dsheirer.settings.ColorSettingMenuItem;
|
||||
import io.github.dsheirer.settings.Setting;
|
||||
@@ -60,7 +60,7 @@ import java.awt.event.MouseMotionListener;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class ChannelSpectrumPanel extends JPanel implements ChannelEventListener,
|
||||
Listener<ReusableBuffer>, SettingChangeListener, SpectralDisplayAdjuster
|
||||
Listener<ReusableFloatBuffer>, SettingChangeListener, SpectralDisplayAdjuster
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -267,9 +267,9 @@ public class ChannelSpectrumPanel extends JPanel implements ChannelEventListener
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ReusableBuffer buffer)
|
||||
public void receive(ReusableFloatBuffer buffer)
|
||||
{
|
||||
ReusableBuffer decimated = mDecimatingFilter.filter(buffer);
|
||||
ReusableFloatBuffer decimated = mDecimatingFilter.filter(buffer);
|
||||
|
||||
//Hack: we're placing real samples in a complex buffer that the DFT
|
||||
//processor is expecting.
|
||||
|
||||
Reference in New Issue
Block a user