diff --git a/.idea/dictionaries/denny.xml b/.idea/dictionaries/denny.xml
index a9674196..35e8bffe 100644
--- a/.idea/dictionaries/denny.xml
+++ b/.idea/dictionaries/denny.xml
@@ -14,6 +14,7 @@
overflowable
polyphase
remez
+ resampler
samplerate
sdrtrunk
sheirer
diff --git a/src/main/java/io/github/dsheirer/audio/AudioModule2.java b/src/main/java/io/github/dsheirer/audio/AudioModule2.java
new file mode 100644
index 00000000..c2f498ac
--- /dev/null
+++ b/src/main/java/io/github/dsheirer/audio/AudioModule2.java
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * 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
+ *
+ ******************************************************************************/
+package io.github.dsheirer.audio;
+
+import io.github.dsheirer.audio.squelch.ISquelchStateListener;
+import io.github.dsheirer.audio.squelch.SquelchState;
+import io.github.dsheirer.channel.metadata.Metadata;
+import io.github.dsheirer.dsp.filter.resample.RealResampler;
+import io.github.dsheirer.module.Module;
+import io.github.dsheirer.sample.Listener;
+import io.github.dsheirer.sample.buffer.ReusableBuffer;
+import io.github.dsheirer.sample.real.IFilteredRealBufferListener;
+import io.github.dsheirer.sample.real.RealBuffer;
+import io.github.dsheirer.source.ISourceEventListener;
+import io.github.dsheirer.source.SourceEvent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Provides packaging of demodulated audio sample buffers into audio packets for
+ * broadcast to registered audio packet listeners. Includes audio packet
+ * metadata in constructed audio packets.
+ *
+ * Incorporates audio squelch state listener to control if audio packets are
+ * broadcast or ignored.
+ */
+public class AudioModule2 extends Module implements IAudioPacketProvider, IFilteredRealBufferListener,
+ ISquelchStateListener, ISourceEventListener, Listener
+{
+ protected static final Logger mLog = LoggerFactory.getLogger(AudioModule2.class);
+ private static final double OUTPUT_SAMPLE_RATE = 8000.0;
+ private SquelchStateListener mSquelchStateListener = new SquelchStateListener();
+ private SquelchState mSquelchState = SquelchState.SQUELCH;
+ private Listener mAudioPacketListener;
+ private Listener mResampledBufferListener;
+ private RealResampler mAudioResampler;
+ private Metadata mMetadata;
+
+ public AudioModule2(Metadata metadata)
+ {
+ mMetadata = metadata;
+
+ mResampledBufferListener = new Listener()
+ {
+ @Override
+ public void receive(ReusableBuffer reusableBuffer)
+ {
+ if(mAudioPacketListener != null)
+ {
+ AudioPacket packet = new AudioPacket(reusableBuffer.getSamplesCopy(), mMetadata.copyOf());
+ reusableBuffer.decrementUserCount();
+ mAudioPacketListener.receive(packet);
+ }
+ }
+ };
+
+ setSampleRate(25000.0);
+ }
+
+ /**
+ * Sets the incoming sample rate
+ */
+ private void setSampleRate(double sampleRate)
+ {
+ mAudioResampler = new RealResampler(sampleRate, OUTPUT_SAMPLE_RATE);
+ mAudioResampler.setListener(mResampledBufferListener);
+ }
+
+ @Override
+ public void dispose()
+ {
+ mSquelchStateListener = null;
+ mAudioPacketListener = null;
+ }
+
+ @Override
+ public void reset()
+ {
+ }
+
+ @Override
+ public void start()
+ {
+ /* No start operations provided */
+ }
+
+ @Override
+ public void stop()
+ {
+ /* Issue an end audio packet in case a recorder is still rolling */
+ if(mAudioPacketListener != null)
+ {
+ mAudioPacketListener.receive(new AudioPacket(AudioPacket.Type.END, mMetadata.copyOf()));
+ }
+ }
+
+ /**
+ * Processes demodulated audio samples into audio packets with current audio
+ * metadata and sends to the registered listener
+ */
+ @Override
+ public void receive(RealBuffer buffer)
+ {
+ if(mAudioResampler != null && mSquelchState == SquelchState.UNSQUELCH)
+ {
+ mAudioResampler.receive(buffer);
+ }
+ }
+
+ @Override
+ public Listener getFilteredRealBufferListener()
+ {
+ return this;
+ }
+
+ @Override
+ public void setAudioPacketListener(Listener listener)
+ {
+ mAudioPacketListener = listener;
+ }
+
+ @Override
+ public void removeAudioPacketListener()
+ {
+ mAudioPacketListener = null;
+ }
+
+ @Override
+ public Listener getSourceEventListener()
+ {
+ return new Listener()
+ {
+ @Override
+ public void receive(SourceEvent sourceEvent)
+ {
+ if(sourceEvent.getEvent() == SourceEvent.Event.NOTIFICATION_SAMPLE_RATE_CHANGE)
+ {
+ setSampleRate(sourceEvent.getValue().doubleValue());
+ }
+ }
+ };
+ }
+
+ @Override
+ public Listener getSquelchStateListener()
+ {
+ return mSquelchStateListener;
+ }
+
+ /**
+ * Wrapper for squelch state listener
+ */
+ public class SquelchStateListener implements Listener
+ {
+ @Override
+ public void receive(SquelchState state)
+ {
+ if(state == SquelchState.SQUELCH && mAudioPacketListener != null)
+ {
+ mAudioPacketListener.receive(new AudioPacket(AudioPacket.Type.END, mMetadata.copyOf()));
+ }
+
+ mSquelchState = state;
+ }
+ }
+}
diff --git a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/AbstractComplexPolyphaseChannelizer.java b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/AbstractComplexPolyphaseChannelizer.java
index cbffb3f7..7de9ead9 100644
--- a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/AbstractComplexPolyphaseChannelizer.java
+++ b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/AbstractComplexPolyphaseChannelizer.java
@@ -20,7 +20,7 @@ package io.github.dsheirer.dsp.filter.channelizer;
import io.github.dsheirer.sample.Broadcaster;
import io.github.dsheirer.sample.Listener;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.source.ISourceEventListener;
import io.github.dsheirer.source.SourceEvent;
import org.slf4j.Logger;
diff --git a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/ChannelizerViewer.java b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/ChannelizerViewer.java
index 820ea2c0..c6d6c25f 100644
--- a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/ChannelizerViewer.java
+++ b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/ChannelizerViewer.java
@@ -18,7 +18,7 @@ package io.github.dsheirer.dsp.filter.channelizer;
import io.github.dsheirer.sample.Listener;
import io.github.dsheirer.sample.SampleType;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.settings.SettingsManager;
import io.github.dsheirer.source.ISourceEventProcessor;
import io.github.dsheirer.source.SourceEvent;
@@ -258,7 +258,7 @@ public class ChannelizerViewer extends JFrame
for(int x = 0; x < mChannelCount; x++)
{
- TunerChannelSource source = mTestTuner.getChannelSourceManager().getSpecialSource(x);
+ TunerChannelSource source = mTestTuner.getChannelSourceManager().getTestingSource(x);
DiscreteChannelPanel channelPanel = new DiscreteChannelPanel(mSettingsManager, source, x);
channelPanel.setDFTSize(mChannelPanelDFTSize);
@@ -327,8 +327,7 @@ public class ChannelizerViewer extends JFrame
@Override
public void receive(ReusableComplexBuffer reusableComplexBuffer)
{
- mDFTProcessor.receive(reusableComplexBuffer.incrementUserCount());
- reusableComplexBuffer.decrementUserCount();
+ mDFTProcessor.receive(reusableComplexBuffer);
}
@Override
@@ -373,7 +372,8 @@ public class ChannelizerViewer extends JFrame
mLog.debug("Samples:" + Arrays.toString(complexBuffer.getSamples()));
}
- mDFTProcessor.receive(complexBuffer.incrementUserCount());
+ complexBuffer.incrementUserCount();
+ mDFTProcessor.receive(complexBuffer);
complexBuffer.decrementUserCount();
}
});
@@ -420,7 +420,8 @@ public class ChannelizerViewer extends JFrame
@Override
public void receive(ReusableComplexBuffer reusableComplexBuffer)
{
- mDFTProcessor.receive(reusableComplexBuffer.incrementUserCount());
+ reusableComplexBuffer.incrementUserCount();
+ mDFTProcessor.receive(reusableComplexBuffer);
reusableComplexBuffer.decrementUserCount();
}
@@ -476,7 +477,8 @@ public class ChannelizerViewer extends JFrame
mLog.debug("Samples:" + Arrays.toString(complexBuffer.getSamples()));
}
- mDFTProcessor.receive(complexBuffer.incrementUserCount());
+ complexBuffer.incrementUserCount();
+ mDFTProcessor.receive(complexBuffer);
complexBuffer.decrementUserCount();
}
});
@@ -502,7 +504,8 @@ public class ChannelizerViewer extends JFrame
@Override
public void receive(ReusableComplexBuffer reusableComplexBuffer)
{
- mDFTProcessor.receive(reusableComplexBuffer.incrementUserCount());
+ reusableComplexBuffer.incrementUserCount();
+ mDFTProcessor.receive(reusableComplexBuffer);
reusableComplexBuffer.decrementUserCount();
}
diff --git a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/ComplexPolyphaseChannelizerM2.java b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/ComplexPolyphaseChannelizerM2.java
index ddb01ae7..4ed168e1 100644
--- a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/ComplexPolyphaseChannelizerM2.java
+++ b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/ComplexPolyphaseChannelizerM2.java
@@ -21,7 +21,7 @@ package io.github.dsheirer.dsp.filter.channelizer;
import io.github.dsheirer.dsp.filter.FilterFactory;
import io.github.dsheirer.dsp.filter.Window.WindowType;
import io.github.dsheirer.dsp.filter.design.FilterDesignException;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import org.jtransforms.fft.FloatFFT_1D;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/ScheduledBufferProcessor.java b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/ContinuousBufferProcessor.java
similarity index 80%
rename from src/main/java/io/github/dsheirer/dsp/filter/channelizer/ScheduledBufferProcessor.java
rename to src/main/java/io/github/dsheirer/dsp/filter/channelizer/ContinuousBufferProcessor.java
index 7c3ca3d7..8c6ec27c 100644
--- a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/ScheduledBufferProcessor.java
+++ b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/ContinuousBufferProcessor.java
@@ -28,15 +28,13 @@ import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
-public class ScheduledBufferProcessor implements Listener
+public class ContinuousBufferProcessor implements Listener
{
- private final static Logger mLog = LoggerFactory.getLogger(ScheduledBufferProcessor.class);
+ private final static Logger mLog = LoggerFactory.getLogger(ContinuousBufferProcessor.class);
private OverflowableTransferQueue mQueue;
private Listener mListener;
private ScheduledFuture> mScheduledFuture;
- private long mDistributionInterval;
- private int mMaxBuffersPerInterval;
private AtomicBoolean mRunning = new AtomicBoolean();
/**
@@ -52,14 +50,10 @@ public class ScheduledBufferProcessor implements Listener
*
* @param maximumSize of the internal queue (overflow happens when this is exceeded)
* @param resetThreshold of the internal queue (overflow reset happens once queue size falls below this threshold
- * @param distributionInterval in milliseconds specifying how often the internal scheduled thread pool buffer
- * distributor should run
- * @param maxBuffersPerInterval maximum number of buffers to pull from the internal queue during each distribution
- * interval
*/
- public ScheduledBufferProcessor(int maximumSize, int resetThreshold, long distributionInterval, int maxBuffersPerInterval)
+ public ContinuousBufferProcessor(int maximumSize, int resetThreshold)
{
- this(new OverflowableTransferQueue<>(maximumSize, resetThreshold), distributionInterval, maxBuffersPerInterval);
+ this(new OverflowableTransferQueue<>(maximumSize, resetThreshold));
}
/**
@@ -74,16 +68,10 @@ public class ScheduledBufferProcessor implements Listener
* notifications of overflow and reset state. Queue sizing parameters are specified in the constructor.
*
* @param queue implmentation of an overflowable transfer queue
- * @param distributionInterval in milliseconds specifying how often the internal scheduled thread pool buffer
- * distributor should run
- * @param maxBuffersPerInterval maximum number of buffers to pull from the internal queue during each distribution
- * interval
*/
- public ScheduledBufferProcessor(OverflowableTransferQueue queue, long distributionInterval, int maxBuffersPerInterval)
+ public ContinuousBufferProcessor(OverflowableTransferQueue queue)
{
mQueue = queue;
- mDistributionInterval = distributionInterval;
- mMaxBuffersPerInterval = maxBuffersPerInterval;
}
/**
@@ -116,6 +104,7 @@ public class ScheduledBufferProcessor implements Listener
@Override
public void receive(E e)
{
+// mLog.debug(" Queuing: " + e.toString());
mQueue.offer(e);
}
@@ -126,7 +115,7 @@ public class ScheduledBufferProcessor implements Listener
{
if(mRunning.compareAndSet(false, true))
{
- mScheduledFuture = ThreadPool.SCHEDULED.scheduleAtFixedRate(new Processor(), 0, mDistributionInterval, TimeUnit.MILLISECONDS);
+ mScheduledFuture = ThreadPool.SCHEDULED.scheduleAtFixedRate(new Processor(), 0, 5, TimeUnit.MILLISECONDS);
}
}
@@ -175,17 +164,22 @@ public class ScheduledBufferProcessor implements Listener
{
try
{
- mQueue.drainTo(mBuffers, mMaxBuffersPerInterval);
+ mQueue.drainTo(mBuffers, 10);
if(mListener != null)
{
- for(E buffer: mBuffers)
+ while(!mBuffers.isEmpty())
{
- mListener.receive(buffer);
+ for(E buffer: mBuffers)
+ {
+// mLog.debug("Dispatching: " + buffer.toString() + " Count:" + mBuffers.size());
+ mListener.receive(buffer);
+ }
+
+ mBuffers.clear();
+ mQueue.drainTo(mBuffers, 10);
}
}
-
- mBuffers.clear();
}
catch(Throwable throwable)
{
diff --git a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/ScheduledReusableBufferProcessor.java b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/ContinuousReusableBufferProcessor.java
similarity index 71%
rename from src/main/java/io/github/dsheirer/dsp/filter/channelizer/ScheduledReusableBufferProcessor.java
rename to src/main/java/io/github/dsheirer/dsp/filter/channelizer/ContinuousReusableBufferProcessor.java
index 24eb7843..0439fb11 100644
--- a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/ScheduledReusableBufferProcessor.java
+++ b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/ContinuousReusableBufferProcessor.java
@@ -15,10 +15,10 @@
******************************************************************************/
package io.github.dsheirer.dsp.filter.channelizer;
-import io.github.dsheirer.sample.complex.reusable.OverflowableReusableBufferTransferQueue;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.OverflowableReusableBufferTransferQueue;
+import io.github.dsheirer.sample.buffer.ReusableBuffer;
-public class ScheduledReusableBufferProcessor extends ScheduledBufferProcessor
+public class ContinuousReusableBufferProcessor extends ContinuousBufferProcessor
{
/**
* Scheduled Reusable Buffer Processor combines an internal overflowable buffer with a scheduled runnable processing
@@ -33,13 +33,9 @@ public class ScheduledReusableBufferProcessor extends ScheduledBufferProcessor(maximumSize, resetThreshold));
}
}
diff --git a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/PolyphaseChannelManager.java b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/PolyphaseChannelManager.java
index ee5ec599..d9118020 100644
--- a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/PolyphaseChannelManager.java
+++ b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/PolyphaseChannelManager.java
@@ -23,8 +23,8 @@ import io.github.dsheirer.dsp.filter.channelizer.output.TwoChannelOutputProcesso
import io.github.dsheirer.dsp.filter.design.FilterDesignException;
import io.github.dsheirer.sample.Broadcaster;
import io.github.dsheirer.sample.Listener;
-import io.github.dsheirer.sample.complex.reusable.IReusableComplexBufferProvider;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.IReusableBufferProvider;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.source.ISourceEventProcessor;
import io.github.dsheirer.source.SourceEvent;
import io.github.dsheirer.source.SourceException;
@@ -52,13 +52,13 @@ public class PolyphaseChannelManager implements ISourceEventProcessor
private static final int POLYPHASE_FILTER_TAPS_PER_CHANNEL = 17;
private Broadcaster mSourceEventBroadcaster = new Broadcaster<>();
- private IReusableComplexBufferProvider mReusableBufferProvider;
+ private IReusableBufferProvider mReusableBufferProvider;
private List mChannelSources = new CopyOnWriteArrayList<>();
private ChannelCalculator mChannelCalculator;
private ComplexPolyphaseChannelizerM2 mPolyphaseChannelizer;
private ChannelSourceEventListener mChannelSourceEventListener = new ChannelSourceEventListener();
private BufferSourceEventMonitor mBufferSourceEventMonitor = new BufferSourceEventMonitor();
- private ScheduledBufferProcessor mBufferProcessor;
+ private ContinuousBufferProcessor mBufferProcessor;
private Map mOutputProcessorFilters = new HashMap<>();
/**
@@ -76,7 +76,8 @@ public class PolyphaseChannelManager implements ISourceEventProcessor
* @param frequency of the provided complex buffer samples
* @param sampleRate of the provided complex buffer samples
*/
- public PolyphaseChannelManager(IReusableComplexBufferProvider reusableBufferProvider, long frequency, double sampleRate)
+ public PolyphaseChannelManager(IReusableBufferProvider reusableBufferProvider,
+ long frequency, double sampleRate)
{
if(reusableBufferProvider == null)
{
@@ -95,7 +96,7 @@ public class PolyphaseChannelManager implements ISourceEventProcessor
mChannelCalculator = new ChannelCalculator(sampleRate, channelCount, frequency, CHANNEL_OVERSAMPLING);
- mBufferProcessor = new ScheduledBufferProcessor(500, 100, 50, 50);
+ mBufferProcessor = new ContinuousBufferProcessor(200, 50);
mBufferProcessor.setListener(mBufferSourceEventMonitor);
updateChannelizerSampleRate(sampleRate);
@@ -160,7 +161,7 @@ public class PolyphaseChannelManager implements ISourceEventProcessor
return channelSource;
}
- public TunerChannelSource getSpecialChannel(int index)
+ public TunerChannelSource getTestChannel(int index)
{
PolyphaseChannelSource channelSource = null;
@@ -181,6 +182,7 @@ public class PolyphaseChannelManager implements ISourceEventProcessor
}
catch(IllegalArgumentException iae)
{
+ mLog.error("Error", iae);
}
return channelSource;
@@ -582,15 +584,19 @@ public class PolyphaseChannelManager implements ISourceEventProcessor
if(mPolyphaseChannelizer != null)
{
- mPolyphaseChannelizer.receive(reusableComplexBuffer.incrementUserCount());
+ //User count management is handled by the channelizer
+ mPolyphaseChannelizer.receive(reusableComplexBuffer);
+ }
+ else
+ {
+ reusableComplexBuffer.decrementUserCount();
}
}
catch(Throwable throwable)
{
mLog.error("Error", throwable);
+ reusableComplexBuffer.decrementUserCount();
}
-
- reusableComplexBuffer.decrementUserCount();
}
}
}
\ No newline at end of file
diff --git a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/PolyphaseChannelSource.java b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/PolyphaseChannelSource.java
index 0e62e6c7..b6a6a99f 100644
--- a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/PolyphaseChannelSource.java
+++ b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/PolyphaseChannelSource.java
@@ -17,8 +17,8 @@ package io.github.dsheirer.dsp.filter.channelizer;
import io.github.dsheirer.dsp.filter.channelizer.output.IPolyphaseChannelOutputProcessor;
import io.github.dsheirer.sample.Listener;
-import io.github.dsheirer.sample.complex.reusable.ReusableBufferAssembler;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableBufferAssembler;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.source.SourceEvent;
import io.github.dsheirer.source.tuner.channel.TunerChannel;
import io.github.dsheirer.source.tuner.channel.TunerChannelSource;
diff --git a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/SynthesizerViewer.java b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/SynthesizerViewer.java
index 75d48dea..ff8ae0d9 100644
--- a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/SynthesizerViewer.java
+++ b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/SynthesizerViewer.java
@@ -23,8 +23,8 @@ import io.github.dsheirer.dsp.mixer.IOscillator;
import io.github.dsheirer.dsp.mixer.LowPhaseNoiseOscillator;
import io.github.dsheirer.sample.Listener;
import io.github.dsheirer.sample.SampleType;
-import io.github.dsheirer.sample.complex.reusable.ReusableBufferQueue;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBufferQueue;
import io.github.dsheirer.sample.real.IOverflowListener;
import io.github.dsheirer.settings.SettingsManager;
import io.github.dsheirer.source.SourceEvent;
@@ -177,8 +177,7 @@ public class SynthesizerViewer extends JFrame
@Override
public void receive(ReusableComplexBuffer reusableComplexBuffer)
{
- mDFTProcessor.receive(reusableComplexBuffer.incrementUserCount());
- reusableComplexBuffer.decrementUserCount();
+ mDFTProcessor.receive(reusableComplexBuffer);
}
}
@@ -212,8 +211,7 @@ public class SynthesizerViewer extends JFrame
@Override
public void receive(ReusableComplexBuffer reusableComplexBuffer)
{
- mDFTProcessor.receive(reusableComplexBuffer.incrementUserCount());
- reusableComplexBuffer.decrementUserCount();
+ mDFTProcessor.receive(reusableComplexBuffer);
}
}
@@ -277,7 +275,7 @@ public class SynthesizerViewer extends JFrame
private TwoChannelSynthesizerM2 mSynthesizer;
private FS4DownConverter mFS4DownConverter = new FS4DownConverter();
private int mSamplesPerCycle = CHANNEL_SAMPLE_RATE / DATA_GENERATOR_FRAME_RATE;
- private ReusableBufferQueue mReusableBufferQueue = new ReusableBufferQueue();
+ private ReusableComplexBufferQueue mReusableComplexBufferQueue = new ReusableComplexBufferQueue("SynthesizerViewer");
public DataGenerationManager()
{
@@ -296,19 +294,22 @@ public class SynthesizerViewer extends JFrame
@Override
public void run()
{
- ReusableComplexBuffer channel1Buffer = mReusableBufferQueue.getBuffer(mSamplesPerCycle);
+ ReusableComplexBuffer channel1Buffer = mReusableComplexBufferQueue.getBuffer(mSamplesPerCycle);
getChannel1ControlPanel().getOscillator().generateComplex(channel1Buffer);
- ReusableComplexBuffer channel2Buffer = mReusableBufferQueue.getBuffer(mSamplesPerCycle);
+ ReusableComplexBuffer channel2Buffer = mReusableComplexBufferQueue.getBuffer(mSamplesPerCycle);
getChannel2ControlPanel().getOscillator().generateComplex(channel2Buffer);
float[] synthesized = mSynthesizer.process(channel1Buffer.getSamples(), channel2Buffer.getSamples());
mFS4DownConverter.mixComplex(synthesized);
- ReusableComplexBuffer synthesizedBuffer = mReusableBufferQueue.getBuffer(synthesized.length);
+ ReusableComplexBuffer synthesizedBuffer = mReusableComplexBufferQueue.getBuffer(synthesized.length);
- getChannel1Panel().receive(channel1Buffer.incrementUserCount());
- getChannel2Panel().receive(channel2Buffer.incrementUserCount());
- getSpectrumPanel().receive(synthesizedBuffer.incrementUserCount());
+ channel1Buffer.incrementUserCount();
+ getChannel1Panel().receive(channel1Buffer);
+ channel2Buffer.incrementUserCount();
+ getChannel2Panel().receive(channel2Buffer);
+ synthesizedBuffer.incrementUserCount();
+ getSpectrumPanel().receive(synthesizedBuffer);
}
}
diff --git a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/output/ChannelOutputProcessor.java b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/output/ChannelOutputProcessor.java
index 5f9f2954..60cfc9f7 100644
--- a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/output/ChannelOutputProcessor.java
+++ b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/output/ChannelOutputProcessor.java
@@ -22,7 +22,7 @@ import io.github.dsheirer.dsp.filter.channelizer.PolyphaseChannelResultsBuffer;
import io.github.dsheirer.dsp.mixer.IOscillator;
import io.github.dsheirer.dsp.mixer.Oscillator;
import io.github.dsheirer.sample.OverflowableTransferQueue;
-import io.github.dsheirer.sample.complex.reusable.ReusableBufferAssembler;
+import io.github.dsheirer.sample.buffer.ReusableBufferAssembler;
import io.github.dsheirer.sample.real.IOverflowListener;
import io.github.dsheirer.source.Source;
import org.slf4j.Logger;
diff --git a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/output/IPolyphaseChannelOutputProcessor.java b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/output/IPolyphaseChannelOutputProcessor.java
index 2dc2216a..3726866e 100644
--- a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/output/IPolyphaseChannelOutputProcessor.java
+++ b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/output/IPolyphaseChannelOutputProcessor.java
@@ -19,7 +19,7 @@
package io.github.dsheirer.dsp.filter.channelizer.output;
import io.github.dsheirer.dsp.filter.channelizer.PolyphaseChannelResultsBuffer;
-import io.github.dsheirer.sample.complex.reusable.ReusableBufferAssembler;
+import io.github.dsheirer.sample.buffer.ReusableBufferAssembler;
import io.github.dsheirer.source.Source;
import java.util.List;
diff --git a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/output/OneChannelOutputProcessor.java b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/output/OneChannelOutputProcessor.java
index b17970f9..1c5e534a 100644
--- a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/output/OneChannelOutputProcessor.java
+++ b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/output/OneChannelOutputProcessor.java
@@ -19,7 +19,7 @@
package io.github.dsheirer.dsp.filter.channelizer.output;
import io.github.dsheirer.dsp.filter.channelizer.PolyphaseChannelResultsBuffer;
-import io.github.dsheirer.sample.complex.reusable.ReusableBufferAssembler;
+import io.github.dsheirer.sample.buffer.ReusableBufferAssembler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/output/TwoChannelOutputProcessor.java b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/output/TwoChannelOutputProcessor.java
index dcc637a5..d51096c2 100644
--- a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/output/TwoChannelOutputProcessor.java
+++ b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/output/TwoChannelOutputProcessor.java
@@ -18,7 +18,7 @@ package io.github.dsheirer.dsp.filter.channelizer.output;
import io.github.dsheirer.dsp.filter.channelizer.PolyphaseChannelResultsBuffer;
import io.github.dsheirer.dsp.filter.channelizer.TwoChannelSynthesizerM2;
import io.github.dsheirer.dsp.mixer.FS4DownConverter;
-import io.github.dsheirer.sample.complex.reusable.ReusableBufferAssembler;
+import io.github.dsheirer.sample.buffer.ReusableBufferAssembler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/src/main/java/io/github/dsheirer/dsp/filter/fir/complex/ComplexFIRFilter.java b/src/main/java/io/github/dsheirer/dsp/filter/fir/complex/ComplexFIRFilter.java
index 6c28556e..ece55ce4 100644
--- a/src/main/java/io/github/dsheirer/dsp/filter/fir/complex/ComplexFIRFilter.java
+++ b/src/main/java/io/github/dsheirer/dsp/filter/fir/complex/ComplexFIRFilter.java
@@ -17,13 +17,13 @@ package io.github.dsheirer.dsp.filter.fir.complex;
import io.github.dsheirer.dsp.filter.fir.FIRFilter;
import io.github.dsheirer.dsp.filter.fir.real.RealFIRFilter;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBufferQueue;
import io.github.dsheirer.sample.complex.Complex;
-import io.github.dsheirer.sample.complex.reusable.ReusableBufferQueue;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
public class ComplexFIRFilter extends FIRFilter
{
- private ReusableBufferQueue mReusableBufferQueue = new ReusableBufferQueue("Complex FIR Filter");
+ private ReusableComplexBufferQueue mReusableComplexBufferQueue = new ReusableComplexBufferQueue("Complex FIR Filter");
private RealFIRFilter mIFilter;
private RealFIRFilter mQFilter;
@@ -84,7 +84,7 @@ public class ComplexFIRFilter extends FIRFilter
*/
public ReusableComplexBuffer filter(ReusableComplexBuffer originalBuffer)
{
- ReusableComplexBuffer filteredBuffer = mReusableBufferQueue.getBuffer(originalBuffer.getSamples().length);
+ ReusableComplexBuffer filteredBuffer = mReusableComplexBufferQueue.getBuffer(originalBuffer.getSamples().length);
filteredBuffer.setTimestamp(originalBuffer.getTimestamp());
float[] samples = originalBuffer.getSamples();
@@ -107,6 +107,6 @@ public class ComplexFIRFilter extends FIRFilter
{
mIFilter.dispose();
mQFilter.dispose();
- mReusableBufferQueue.dispose();
+ mReusableComplexBufferQueue.dispose();
}
}
diff --git a/src/main/java/io/github/dsheirer/dsp/filter/resample/AudioResampler.java b/src/main/java/io/github/dsheirer/dsp/filter/resample/AudioResampler.java
deleted file mode 100644
index c67401b9..00000000
--- a/src/main/java/io/github/dsheirer/dsp/filter/resample/AudioResampler.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*******************************************************************************
- * 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
- *
- ******************************************************************************/
-package io.github.dsheirer.dsp.filter.resample;
-
-import com.laszlosystems.libresample4j.Resampler;
-import io.github.dsheirer.module.Module;
-import io.github.dsheirer.sample.Listener;
-import io.github.dsheirer.source.ISourceEventListener;
-import io.github.dsheirer.source.SourceEvent;
-
-public class AudioResampler extends Module implements ISourceEventListener
-{
- private Resampler mResampler;
-
- public AudioResampler(double inputRate, double outputRate)
- {
- double resampleRate = outputRate / inputRate;
-
- mResampler = new Resampler(true, resampleRate, resampleRate);
- }
-
- public float[] resample(float[] samples)
- {
- return null;
- }
-
- @Override
- public void reset()
- {
-
- }
-
- @Override
- public void start()
- {
-
- }
-
- @Override
- public void stop()
- {
-
- }
-
- @Override
- public void dispose()
- {
-
- }
-
- @Override
- public Listener getSourceEventListener()
- {
- //TODO: we should get the channel sample rate and setup the resampler to output 8 kHz audio
- return null;
- }
-}
diff --git a/src/main/java/io/github/dsheirer/dsp/filter/resample/RealResampler.java b/src/main/java/io/github/dsheirer/dsp/filter/resample/RealResampler.java
new file mode 100644
index 00000000..ece20c3d
--- /dev/null
+++ b/src/main/java/io/github/dsheirer/dsp/filter/resample/RealResampler.java
@@ -0,0 +1,166 @@
+/*******************************************************************************
+ * 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
+ *
+ ******************************************************************************/
+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.real.RealBuffer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.nio.ByteBuffer;
+import java.nio.FloatBuffer;
+
+public class RealResampler implements Listener
+{
+ protected static final Logger mLog = LoggerFactory.getLogger(RealResampler.class);
+
+ private Resampler mResampler;
+ private Listener mResampledListener;
+ private BufferManager mBufferManager = new BufferManager();
+ private ReusableBufferQueue mReusableBufferQueue = new ReusableBufferQueue("RealResampler");
+ private double mResampleFactor;
+
+ /**
+ * Resampler for real sample buffers.
+ * @param inputRate
+ * @param outputRate
+ */
+ public RealResampler(double inputRate, double outputRate)
+ {
+ mResampleFactor = outputRate / inputRate;
+ mResampler = new Resampler(true, mResampleFactor, mResampleFactor);
+ }
+
+ /**
+ * Primary input method to the resampler
+ * @param realBuffer to resample
+ */
+ @Override
+ public void receive(RealBuffer realBuffer)
+ {
+ mBufferManager.load(realBuffer);
+ mResampler.process(mResampleFactor, mBufferManager, false);
+ }
+
+ /**
+ * Registers the listener to receive the resampled buffer output
+ * @param resampledBufferListener to receive buffers
+ */
+ public void setListener(Listener resampledBufferListener)
+ {
+ mResampledListener = resampledBufferListener;
+ }
+
+ /**
+ * Buffer manager for input and output buffers used during the resampling process. The manager will
+ * auto-resize the input and output buffers to meet the size of the incoming sample buffers.
+ */
+ public class BufferManager implements SampleBuffers
+ {
+ private int mBufferLength = 1000;
+ private FloatBuffer mInputBuffer = ByteBuffer.allocate(mBufferLength).asFloatBuffer();
+ private FloatBuffer mOutputBuffer = ByteBuffer.allocate(mBufferLength).asFloatBuffer();
+
+ public void resize(int bufferLength)
+ {
+ int floatBufferLength = bufferLength * 4;
+
+ FloatBuffer inputBuffer = ByteBuffer.allocate(floatBufferLength).asFloatBuffer();
+ inputBuffer.put(mInputBuffer);
+ mInputBuffer = inputBuffer;
+
+ FloatBuffer outputBuffer = ByteBuffer.allocate(floatBufferLength).asFloatBuffer();
+ outputBuffer.put(mOutputBuffer);
+ mOutputBuffer = outputBuffer;
+
+ mBufferLength = bufferLength;
+ }
+
+ /**
+ * Current length of the input and output buffers
+ */
+ public int getBufferLength()
+ {
+ return mBufferLength;
+ }
+
+ /**
+ * Queues the buffer sample for resampling
+ */
+ public void load(RealBuffer realBuffer)
+ {
+ int remaining = mInputBuffer.remaining();
+
+ if(mInputBuffer.remaining() < realBuffer.getSamples().length)
+ {
+ resize(mInputBuffer.capacity() + (realBuffer.getSamples().length - mInputBuffer.remaining()));
+ }
+
+ mInputBuffer.put(realBuffer.getSamples());
+ }
+
+ @Override
+ public int getInputBufferLength()
+ {
+ return mInputBuffer.position();
+ }
+
+ @Override
+ public int getOutputBufferLength()
+ {
+ return mOutputBuffer.remaining();
+ }
+
+ /**
+ * Provides input to the resampler
+ */
+ @Override
+ public void produceInput(float[] samples, int offset, int length)
+ {
+ mInputBuffer.flip();
+ mInputBuffer.get(samples, offset, length);
+ mInputBuffer.compact();
+ }
+
+ /**
+ * Receives output from the resampler and dispatches output buffers periodically.
+ */
+ @Override
+ public void consumeOutput(float[] samples, int offset, int length)
+ {
+ mOutputBuffer.put(samples, offset, length);
+
+ while(mOutputBuffer.position() > 200)
+ {
+ ReusableBuffer outputBuffer = mReusableBufferQueue.getBuffer(200);
+
+ mOutputBuffer.flip();
+ mOutputBuffer.get(outputBuffer.getSamples());
+ mOutputBuffer.compact();
+
+ if(mResampledListener != null)
+ {
+ outputBuffer.incrementUserCount();
+ mResampledListener.receive(outputBuffer);
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/io/github/dsheirer/dsp/gain/ComplexFeedForwardGainControl.java b/src/main/java/io/github/dsheirer/dsp/gain/ComplexFeedForwardGainControl.java
index 13c54eda..3cb99948 100644
--- a/src/main/java/io/github/dsheirer/dsp/gain/ComplexFeedForwardGainControl.java
+++ b/src/main/java/io/github/dsheirer/dsp/gain/ComplexFeedForwardGainControl.java
@@ -16,11 +16,11 @@
package io.github.dsheirer.dsp.gain;
import io.github.dsheirer.buffer.FloatCircularBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBufferQueue;
import io.github.dsheirer.sample.complex.Complex;
import io.github.dsheirer.sample.complex.ComplexBuffer;
import io.github.dsheirer.sample.complex.ComplexSampleListener;
-import io.github.dsheirer.sample.complex.reusable.ReusableBufferQueue;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
public class ComplexFeedForwardGainControl implements ComplexSampleListener
{
@@ -29,7 +29,7 @@ public class ComplexFeedForwardGainControl implements ComplexSampleListener
private ComplexSampleListener mListener;
private FloatCircularBuffer mEnvelopeHistory;
- private ReusableBufferQueue mReusableBufferQueue = new ReusableBufferQueue("ComplexFeedForwardGainControl");
+ private ReusableComplexBufferQueue mReusableComplexBufferQueue = new ReusableComplexBufferQueue("ComplexFeedForwardGainControl");
private float mMaxEnvelope = 0.0f;
private float mGain = 1.0f;
@@ -157,7 +157,7 @@ public class ComplexFeedForwardGainControl implements ComplexSampleListener
{
float[] samples = buffer.getSamples();
- ReusableComplexBuffer filteredBuffer = mReusableBufferQueue.getBuffer(samples.length);
+ ReusableComplexBuffer filteredBuffer = mReusableComplexBufferQueue.getBuffer(samples.length);
filteredBuffer.setTimestamp(buffer.getTimestamp());
float[] filtered = filteredBuffer.getSamples();
diff --git a/src/main/java/io/github/dsheirer/dsp/mixer/AbstractOscillator.java b/src/main/java/io/github/dsheirer/dsp/mixer/AbstractOscillator.java
index 5be64115..3f7df3f8 100644
--- a/src/main/java/io/github/dsheirer/dsp/mixer/AbstractOscillator.java
+++ b/src/main/java/io/github/dsheirer/dsp/mixer/AbstractOscillator.java
@@ -15,8 +15,8 @@
******************************************************************************/
package io.github.dsheirer.dsp.mixer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.sample.complex.Complex;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -160,7 +160,7 @@ public abstract class AbstractOscillator implements IOscillator
@Override
public void generateComplex(ReusableComplexBuffer reusableComplexBuffer)
{
- int sampleCount = reusableComplexBuffer.getSampleLength();
+ int sampleCount = reusableComplexBuffer.getSampleCount();
if(mSampleBuffer == null || mSampleBuffer.capacity() != sampleCount * 2)
{
diff --git a/src/main/java/io/github/dsheirer/dsp/mixer/IOscillator.java b/src/main/java/io/github/dsheirer/dsp/mixer/IOscillator.java
index 1f843dda..18f522d5 100644
--- a/src/main/java/io/github/dsheirer/dsp/mixer/IOscillator.java
+++ b/src/main/java/io/github/dsheirer/dsp/mixer/IOscillator.java
@@ -15,7 +15,7 @@
******************************************************************************/
package io.github.dsheirer.dsp.mixer;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
/**
* Oscillator interface.
diff --git a/src/main/java/io/github/dsheirer/dsp/psk/PSKDemodulator.java b/src/main/java/io/github/dsheirer/dsp/psk/PSKDemodulator.java
index c187a408..aebc59e6 100644
--- a/src/main/java/io/github/dsheirer/dsp/psk/PSKDemodulator.java
+++ b/src/main/java/io/github/dsheirer/dsp/psk/PSKDemodulator.java
@@ -17,9 +17,9 @@ package io.github.dsheirer.dsp.psk;
import io.github.dsheirer.dsp.psk.pll.IPhaseLockedLoop;
import io.github.dsheirer.sample.Listener;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.sample.complex.Complex;
import io.github.dsheirer.sample.complex.ComplexSampleListener;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
public abstract class PSKDemodulator implements ComplexSampleListener
{
diff --git a/src/main/java/io/github/dsheirer/instrument/gui/viewer/PlaybackController.java b/src/main/java/io/github/dsheirer/instrument/gui/viewer/PlaybackController.java
index 6462901f..ee74737e 100644
--- a/src/main/java/io/github/dsheirer/instrument/gui/viewer/PlaybackController.java
+++ b/src/main/java/io/github/dsheirer/instrument/gui/viewer/PlaybackController.java
@@ -17,8 +17,8 @@ package io.github.dsheirer.instrument.gui.viewer;
import io.github.dsheirer.instrument.gui.viewer.decoder.DecoderPane;
import io.github.dsheirer.sample.Listener;
-import io.github.dsheirer.sample.complex.reusable.ReusableBufferBroadcaster;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableBufferBroadcaster;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.source.IControllableFileSource;
import io.github.dsheirer.source.IFrameLocationListener;
import io.github.dsheirer.source.wave.ComplexWaveSource;
diff --git a/src/main/java/io/github/dsheirer/instrument/gui/viewer/chart/ComplexPhaseLineChart.java b/src/main/java/io/github/dsheirer/instrument/gui/viewer/chart/ComplexPhaseLineChart.java
index 3d7694a2..000f3a50 100644
--- a/src/main/java/io/github/dsheirer/instrument/gui/viewer/chart/ComplexPhaseLineChart.java
+++ b/src/main/java/io/github/dsheirer/instrument/gui/viewer/chart/ComplexPhaseLineChart.java
@@ -18,8 +18,8 @@ package io.github.dsheirer.instrument.gui.viewer.chart;
import io.github.dsheirer.buffer.ComplexCircularBuffer;
import io.github.dsheirer.dsp.gain.ComplexGain;
import io.github.dsheirer.sample.Listener;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.sample.complex.Complex;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.value.ChangeListener;
diff --git a/src/main/java/io/github/dsheirer/instrument/gui/viewer/chart/ComplexSampleLineChart.java b/src/main/java/io/github/dsheirer/instrument/gui/viewer/chart/ComplexSampleLineChart.java
index bec81eef..d1b4b00c 100644
--- a/src/main/java/io/github/dsheirer/instrument/gui/viewer/chart/ComplexSampleLineChart.java
+++ b/src/main/java/io/github/dsheirer/instrument/gui/viewer/chart/ComplexSampleLineChart.java
@@ -18,8 +18,8 @@ package io.github.dsheirer.instrument.gui.viewer.chart;
import io.github.dsheirer.buffer.ComplexCircularBuffer;
import io.github.dsheirer.dsp.gain.ComplexGain;
import io.github.dsheirer.sample.Listener;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.sample.complex.Complex;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.value.ChangeListener;
diff --git a/src/main/java/io/github/dsheirer/instrument/gui/viewer/chart/FMDemodulatedLineChart.java b/src/main/java/io/github/dsheirer/instrument/gui/viewer/chart/FMDemodulatedLineChart.java
index c209a5db..334db601 100644
--- a/src/main/java/io/github/dsheirer/instrument/gui/viewer/chart/FMDemodulatedLineChart.java
+++ b/src/main/java/io/github/dsheirer/instrument/gui/viewer/chart/FMDemodulatedLineChart.java
@@ -18,8 +18,8 @@ package io.github.dsheirer.instrument.gui.viewer.chart;
import io.github.dsheirer.buffer.DoubleCircularBuffer;
import io.github.dsheirer.dsp.fm.FMDemodulator;
import io.github.dsheirer.sample.Listener;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.sample.complex.Complex;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.chart.LineChart;
diff --git a/src/main/java/io/github/dsheirer/instrument/gui/viewer/decoder/DecoderPane.java b/src/main/java/io/github/dsheirer/instrument/gui/viewer/decoder/DecoderPane.java
index daaa092d..82d3ae86 100644
--- a/src/main/java/io/github/dsheirer/instrument/gui/viewer/decoder/DecoderPane.java
+++ b/src/main/java/io/github/dsheirer/instrument/gui/viewer/decoder/DecoderPane.java
@@ -17,8 +17,8 @@ package io.github.dsheirer.instrument.gui.viewer.decoder;
import io.github.dsheirer.module.decode.DecoderType;
import io.github.dsheirer.sample.Listener;
-import io.github.dsheirer.sample.complex.reusable.ReusableBufferBroadcaster;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableBufferBroadcaster;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
diff --git a/src/main/java/io/github/dsheirer/instrument/gui/viewer/decoder/P25Phase1C4FMPane.java b/src/main/java/io/github/dsheirer/instrument/gui/viewer/decoder/P25Phase1C4FMPane.java
index 381e83be..56a3cff0 100644
--- a/src/main/java/io/github/dsheirer/instrument/gui/viewer/decoder/P25Phase1C4FMPane.java
+++ b/src/main/java/io/github/dsheirer/instrument/gui/viewer/decoder/P25Phase1C4FMPane.java
@@ -24,7 +24,7 @@ import io.github.dsheirer.message.Message;
import io.github.dsheirer.module.decode.DecoderType;
import io.github.dsheirer.module.decode.p25.P25DecoderC4FMInstrumented;
import io.github.dsheirer.sample.Listener;
-import io.github.dsheirer.sample.complex.reusable.ReusableBufferBroadcaster;
+import io.github.dsheirer.sample.buffer.ReusableBufferBroadcaster;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import org.slf4j.Logger;
diff --git a/src/main/java/io/github/dsheirer/instrument/gui/viewer/decoder/P25Phase1LSMPane.java b/src/main/java/io/github/dsheirer/instrument/gui/viewer/decoder/P25Phase1LSMPane.java
index b93fa58e..33b0f7e4 100644
--- a/src/main/java/io/github/dsheirer/instrument/gui/viewer/decoder/P25Phase1LSMPane.java
+++ b/src/main/java/io/github/dsheirer/instrument/gui/viewer/decoder/P25Phase1LSMPane.java
@@ -24,7 +24,7 @@ import io.github.dsheirer.message.Message;
import io.github.dsheirer.module.decode.DecoderType;
import io.github.dsheirer.module.decode.p25.P25DecoderLSMInstrumented;
import io.github.dsheirer.sample.Listener;
-import io.github.dsheirer.sample.complex.reusable.ReusableBufferBroadcaster;
+import io.github.dsheirer.sample.buffer.ReusableBufferBroadcaster;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import org.slf4j.Logger;
diff --git a/src/main/java/io/github/dsheirer/module/ProcessingChain.java b/src/main/java/io/github/dsheirer/module/ProcessingChain.java
index 060190ff..34b81cdb 100644
--- a/src/main/java/io/github/dsheirer/module/ProcessingChain.java
+++ b/src/main/java/io/github/dsheirer/module/ProcessingChain.java
@@ -49,8 +49,8 @@ import io.github.dsheirer.record.wave.ComplexBufferWaveRecorder;
import io.github.dsheirer.record.wave.RealBufferWaveRecorder;
import io.github.dsheirer.sample.Broadcaster;
import io.github.dsheirer.sample.Listener;
-import io.github.dsheirer.sample.complex.reusable.IReusableComplexBufferListener;
-import io.github.dsheirer.sample.complex.reusable.ReusableBufferBroadcaster;
+import io.github.dsheirer.sample.buffer.IReusableComplexBufferListener;
+import io.github.dsheirer.sample.buffer.ReusableBufferBroadcaster;
import io.github.dsheirer.sample.real.IFilteredRealBufferListener;
import io.github.dsheirer.sample.real.IFilteredRealBufferProvider;
import io.github.dsheirer.sample.real.IUnFilteredRealBufferListener;
diff --git a/src/main/java/io/github/dsheirer/module/decode/DecoderFactory.java b/src/main/java/io/github/dsheirer/module/decode/DecoderFactory.java
index 146e8f3a..c2020df7 100644
--- a/src/main/java/io/github/dsheirer/module/decode/DecoderFactory.java
+++ b/src/main/java/io/github/dsheirer/module/decode/DecoderFactory.java
@@ -20,7 +20,7 @@ package io.github.dsheirer.module.decode;
import io.github.dsheirer.alias.AliasList;
import io.github.dsheirer.alias.AliasModel;
-import io.github.dsheirer.audio.AudioModule;
+import io.github.dsheirer.audio.AudioModule2;
import io.github.dsheirer.channel.metadata.Metadata;
import io.github.dsheirer.channel.state.AlwaysUnsquelchedDecoderState;
import io.github.dsheirer.channel.traffic.TrafficChannelManager;
@@ -184,14 +184,14 @@ public class DecoderFactory
modules.add(new AlwaysUnsquelchedDecoderState(DecoderType.AM, channel.getName()));
modules.add(new AMDemodulatorModule());
modules.add(new DemodulatedAudioFilterModule(4000, 6000));
- modules.add(new AudioModule(metadata));
+ modules.add(new AudioModule2(metadata));
break;
case NBFM:
modules.add(new NBFMDecoder(decodeConfig));
modules.add(new AlwaysUnsquelchedDecoderState(DecoderType.NBFM, channel.getName()));
modules.add(new FMDemodulatorModule(NBFM_PASS_FREQUENCY, NBFM_STOP_FREQUENCY));
modules.add(new DemodulatedAudioFilterModule(4000, 6000));
- modules.add(new AudioModule(metadata));
+ modules.add(new AudioModule2(metadata));
break;
case LTR_STANDARD:
MessageDirection direction = ((DecodeConfigLTRStandard) decodeConfig).getMessageDirection();
@@ -199,14 +199,14 @@ public class DecoderFactory
modules.add(new LTRStandardDecoderState(aliasList));
modules.add(new FMDemodulatorModule(NBFM_PASS_FREQUENCY, NBFM_STOP_FREQUENCY));
modules.add(new DemodulatedAudioFilterModule(4000, 6000));
- modules.add(new AudioModule(metadata));
+ modules.add(new AudioModule2(metadata));
break;
case LTR_NET:
modules.add(new LTRNetDecoder((DecodeConfigLTRNet) decodeConfig, aliasList));
modules.add(new LTRNetDecoderState(aliasList));
modules.add(new FMDemodulatorModule(NBFM_PASS_FREQUENCY, NBFM_STOP_FREQUENCY));
modules.add(new DemodulatedAudioFilterModule(4000, 6000));
- modules.add(new AudioModule(metadata));
+ modules.add(new AudioModule2(metadata));
break;
case MPT1327:
DecodeConfigMPT1327 mptConfig = (DecodeConfigMPT1327) decodeConfig;
@@ -229,14 +229,14 @@ public class DecoderFactory
modules.add(new FMDemodulatorModule(NBFM_PASS_FREQUENCY, NBFM_STOP_FREQUENCY));
modules.add(new DemodulatedAudioFilterModule(P25_C4FM_DEMOD_FILTER, 1.0f));
- modules.add(new AudioModule(metadata));
+ modules.add(new AudioModule2(metadata));
break;
case PASSPORT:
modules.add(new PassportDecoder(decodeConfig, aliasList));
modules.add(new PassportDecoderState(aliasList));
modules.add(new FMDemodulatorModule(NBFM_PASS_FREQUENCY, NBFM_STOP_FREQUENCY));
modules.add(new DemodulatedAudioFilterModule(4000, 6000));
- modules.add(new AudioModule(metadata));
+ modules.add(new AudioModule2(metadata));
break;
case P25_PHASE1:
DecodeConfigP25Phase1 p25Config = (DecodeConfigP25Phase1) decodeConfig;
diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/P25Decoder.java b/src/main/java/io/github/dsheirer/module/decode/p25/P25Decoder.java
index dfcf230b..f88348cf 100644
--- a/src/main/java/io/github/dsheirer/module/decode/p25/P25Decoder.java
+++ b/src/main/java/io/github/dsheirer/module/decode/p25/P25Decoder.java
@@ -19,8 +19,8 @@ import io.github.dsheirer.alias.AliasList;
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.complex.reusable.IReusableComplexBufferListener;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.IReusableComplexBufferListener;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.source.ISourceEventListener;
import io.github.dsheirer.source.ISourceEventProvider;
import io.github.dsheirer.source.SourceEvent;
diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/P25DecoderC4FM.java b/src/main/java/io/github/dsheirer/module/decode/p25/P25DecoderC4FM.java
index f37f3aae..1155ec58 100644
--- a/src/main/java/io/github/dsheirer/module/decode/p25/P25DecoderC4FM.java
+++ b/src/main/java/io/github/dsheirer/module/decode/p25/P25DecoderC4FM.java
@@ -24,7 +24,7 @@ import io.github.dsheirer.dsp.gain.ComplexFeedForwardGainControl;
import io.github.dsheirer.dsp.psk.DQPSKDecisionDirectedDemodulator;
import io.github.dsheirer.dsp.psk.InterpolatingSampleBuffer;
import io.github.dsheirer.dsp.psk.pll.CostasLoop;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.source.SourceEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/P25DecoderC4FMInstrumented.java b/src/main/java/io/github/dsheirer/module/decode/p25/P25DecoderC4FMInstrumented.java
index 46762450..c69a44e6 100644
--- a/src/main/java/io/github/dsheirer/module/decode/p25/P25DecoderC4FMInstrumented.java
+++ b/src/main/java/io/github/dsheirer/module/decode/p25/P25DecoderC4FMInstrumented.java
@@ -20,8 +20,8 @@ import io.github.dsheirer.dsp.psk.DQPSKDecisionDirectedDemodulatorInstrumented;
import io.github.dsheirer.dsp.psk.InterpolatingSampleBufferInstrumented;
import io.github.dsheirer.dsp.psk.SymbolDecisionData;
import io.github.dsheirer.sample.Listener;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.sample.complex.Complex;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
public class P25DecoderC4FMInstrumented extends P25DecoderC4FM
{
diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/P25DecoderLSM.java b/src/main/java/io/github/dsheirer/module/decode/p25/P25DecoderLSM.java
index 1fd4c683..d9dea665 100644
--- a/src/main/java/io/github/dsheirer/module/decode/p25/P25DecoderLSM.java
+++ b/src/main/java/io/github/dsheirer/module/decode/p25/P25DecoderLSM.java
@@ -23,7 +23,7 @@ import io.github.dsheirer.dsp.gain.ComplexFeedForwardGainControl;
import io.github.dsheirer.dsp.psk.DQPSKGardnerDemodulator;
import io.github.dsheirer.dsp.psk.InterpolatingSampleBuffer;
import io.github.dsheirer.dsp.psk.pll.CostasLoop;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.source.SourceEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/P25DecoderLSMInstrumented.java b/src/main/java/io/github/dsheirer/module/decode/p25/P25DecoderLSMInstrumented.java
index 41292d32..7997ae9f 100644
--- a/src/main/java/io/github/dsheirer/module/decode/p25/P25DecoderLSMInstrumented.java
+++ b/src/main/java/io/github/dsheirer/module/decode/p25/P25DecoderLSMInstrumented.java
@@ -20,8 +20,8 @@ import io.github.dsheirer.dsp.psk.DQPSKGardnerDemodulatorInstrumented;
import io.github.dsheirer.dsp.psk.InterpolatingSampleBufferInstrumented;
import io.github.dsheirer.dsp.psk.SymbolDecisionData;
import io.github.dsheirer.sample.Listener;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.sample.complex.Complex;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
public class P25DecoderLSMInstrumented extends P25DecoderLSM
{
diff --git a/src/main/java/io/github/dsheirer/module/demodulate/am/AMDemodulatorModule.java b/src/main/java/io/github/dsheirer/module/demodulate/am/AMDemodulatorModule.java
index e55b51cb..f155c890 100644
--- a/src/main/java/io/github/dsheirer/module/demodulate/am/AMDemodulatorModule.java
+++ b/src/main/java/io/github/dsheirer/module/demodulate/am/AMDemodulatorModule.java
@@ -23,9 +23,9 @@ import io.github.dsheirer.dsp.filter.fir.real.RealFIRFilter_RB_RB;
import io.github.dsheirer.dsp.gain.AutomaticGainControl_RB;
import io.github.dsheirer.module.Module;
import io.github.dsheirer.sample.Listener;
+import io.github.dsheirer.sample.buffer.IReusableComplexBufferListener;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.sample.complex.ComplexBuffer;
-import io.github.dsheirer.sample.complex.reusable.IReusableComplexBufferListener;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
import io.github.dsheirer.sample.real.IFilteredRealBufferProvider;
import io.github.dsheirer.sample.real.RealBuffer;
diff --git a/src/main/java/io/github/dsheirer/module/demodulate/fm/FMDemodulatorModule.java b/src/main/java/io/github/dsheirer/module/demodulate/fm/FMDemodulatorModule.java
index a976a3fa..b06864c8 100644
--- a/src/main/java/io/github/dsheirer/module/demodulate/fm/FMDemodulatorModule.java
+++ b/src/main/java/io/github/dsheirer/module/demodulate/fm/FMDemodulatorModule.java
@@ -23,8 +23,8 @@ import io.github.dsheirer.dsp.filter.fir.complex.ComplexFIRFilter_CB_CB;
import io.github.dsheirer.dsp.fm.FMDemodulator_CB;
import io.github.dsheirer.module.Module;
import io.github.dsheirer.sample.Listener;
-import io.github.dsheirer.sample.complex.reusable.IReusableComplexBufferListener;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.IReusableComplexBufferListener;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.sample.real.IUnFilteredRealBufferProvider;
import io.github.dsheirer.sample.real.RealBuffer;
import io.github.dsheirer.source.ISourceEventListener;
diff --git a/src/main/java/io/github/dsheirer/record/wave/ComplexBufferWaveRecorder.java b/src/main/java/io/github/dsheirer/record/wave/ComplexBufferWaveRecorder.java
index 12b519a3..ff68d8fb 100644
--- a/src/main/java/io/github/dsheirer/record/wave/ComplexBufferWaveRecorder.java
+++ b/src/main/java/io/github/dsheirer/record/wave/ComplexBufferWaveRecorder.java
@@ -18,9 +18,9 @@ package io.github.dsheirer.record.wave;
import io.github.dsheirer.module.Module;
import io.github.dsheirer.sample.ConversionUtils;
import io.github.dsheirer.sample.Listener;
-import io.github.dsheirer.sample.complex.reusable.IReusableBufferDisposedListener;
-import io.github.dsheirer.sample.complex.reusable.IReusableComplexBufferListener;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.IReusableBufferDisposedListener;
+import io.github.dsheirer.sample.buffer.IReusableComplexBufferListener;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.util.ThreadPool;
import io.github.dsheirer.util.TimeStamp;
import org.slf4j.Logger;
@@ -207,14 +207,14 @@ public class ComplexBufferWaveRecorder extends Module implements IReusableComple
{
public PoisonPill()
{
- super(new IReusableBufferDisposedListener()
+ super(new IReusableBufferDisposedListener()
{
@Override
public void disposed(ReusableComplexBuffer reusableComplexBuffer)
{
//no-op
}
- }, new float[2], System.currentTimeMillis());
+ }, new float[2]);
}
}
}
diff --git a/src/main/java/io/github/dsheirer/sample/ConversionUtils.java b/src/main/java/io/github/dsheirer/sample/ConversionUtils.java
index 7ad5c27c..9cc988ff 100644
--- a/src/main/java/io/github/dsheirer/sample/ConversionUtils.java
+++ b/src/main/java/io/github/dsheirer/sample/ConversionUtils.java
@@ -1,5 +1,6 @@
package io.github.dsheirer.sample;
+import io.github.dsheirer.sample.buffer.ReusableBuffer;
import io.github.dsheirer.sample.real.RealBuffer;
import java.nio.ByteBuffer;
@@ -11,61 +12,71 @@ import java.nio.ShortBuffer;
*/
public class ConversionUtils
{
- public static float[] convertFromSigned16BitSamples( byte[] bytes )
+ public static float[] convertFromSigned16BitSamples(byte[] bytes)
{
- return convertFromSigned16BitSamples( ByteBuffer.wrap( bytes ) );
+ return convertFromSigned16BitSamples(ByteBuffer.wrap(bytes));
}
/**
* Converts the byte buffer containing 16-bit samples into a float array
*/
- public static float[] convertFromSigned16BitSamples( ByteBuffer buffer )
+ public static float[] convertFromSigned16BitSamples(ByteBuffer buffer)
{
- ShortBuffer byteBuffer = buffer.order( ByteOrder.LITTLE_ENDIAN ).asShortBuffer();
-
- float[] samples = new float[ buffer.limit() / 2 ];
-
- for( int x = 0; x < samples.length; x++ )
- {
- samples[ x ] = (float)byteBuffer.get() / (float)Short.MAX_VALUE;
- }
+ ShortBuffer byteBuffer = buffer.order(ByteOrder.LITTLE_ENDIAN).asShortBuffer();
- return samples;
+ float[] samples = new float[buffer.limit() / 2];
+
+ for(int x = 0; x < samples.length; x++)
+ {
+ samples[x] = (float)byteBuffer.get() / (float)Short.MAX_VALUE;
+ }
+
+ return samples;
}
/**
* Converts the float samples into a little-endian 16-bit sample byte buffer.
+ *
* @param samples - float array of sample data
* @return - little-endian 16-bit sample byte buffer
*/
- public static ByteBuffer convertToSigned16BitSamples( float[] samples )
+ public static ByteBuffer convertToSigned16BitSamples(float[] samples)
{
- ByteBuffer converted = ByteBuffer.allocate( samples.length * 2 );
- converted.order( ByteOrder.LITTLE_ENDIAN );
+ ByteBuffer converted = ByteBuffer.allocate(samples.length * 2);
+ converted.order(ByteOrder.LITTLE_ENDIAN);
- for( float sample: samples )
- {
- converted.putShort( (short)( sample * Short.MAX_VALUE ) );
- }
-
- return converted;
+ for(float sample : samples)
+ {
+ converted.putShort((short)(sample * Short.MAX_VALUE));
+ }
+
+ return converted;
}
-
- /**
- * Converts the float samples in a complex buffer to a little endian 16-bit
- * buffer
- */
- public static ByteBuffer convertToSigned16BitSamples( Buffer buffer )
- {
- return convertToSigned16BitSamples( buffer.getSamples() );
- }
- /**
- * Converts the float samples in a complex buffer to a little endian 16-bit
- * buffer
- */
- public static ByteBuffer convertToSigned16BitSamples( RealBuffer buffer )
- {
- return convertToSigned16BitSamples( buffer.getSamples() );
- }
+ /**
+ * Converts the float samples in a complex buffer to a little endian 16-bit
+ * buffer
+ */
+ public static ByteBuffer convertToSigned16BitSamples(Buffer buffer)
+ {
+ return convertToSigned16BitSamples(buffer.getSamples());
+ }
+
+ /**
+ * Converts the float samples in a complex buffer to a little endian 16-bit
+ * buffer
+ */
+ public static ByteBuffer convertToSigned16BitSamples(RealBuffer buffer)
+ {
+ return convertToSigned16BitSamples(buffer.getSamples());
+ }
+
+ /**
+ * Converts the float samples in a complex buffer to a little endian 16-bit
+ * buffer
+ */
+ public static ByteBuffer convertToSigned16BitSamples(ReusableBuffer buffer)
+ {
+ return convertToSigned16BitSamples(buffer.getSamples());
+ }
}
diff --git a/src/main/java/io/github/dsheirer/sample/adapter/ComplexShortAdapter.java b/src/main/java/io/github/dsheirer/sample/adapter/ComplexShortAdapter.java
index 705a5448..6a3c80ac 100644
--- a/src/main/java/io/github/dsheirer/sample/adapter/ComplexShortAdapter.java
+++ b/src/main/java/io/github/dsheirer/sample/adapter/ComplexShortAdapter.java
@@ -15,7 +15,7 @@
******************************************************************************/
package io.github.dsheirer.sample.adapter;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
diff --git a/src/main/java/io/github/dsheirer/sample/adapter/IComplexSampleAdapter.java b/src/main/java/io/github/dsheirer/sample/adapter/IComplexSampleAdapter.java
index 471ee032..99d07eeb 100644
--- a/src/main/java/io/github/dsheirer/sample/adapter/IComplexSampleAdapter.java
+++ b/src/main/java/io/github/dsheirer/sample/adapter/IComplexSampleAdapter.java
@@ -15,7 +15,7 @@
******************************************************************************/
package io.github.dsheirer.sample.adapter;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
public interface IComplexSampleAdapter
{
diff --git a/src/main/java/io/github/dsheirer/sample/complex/reusable/ReusableBufferQueue.java b/src/main/java/io/github/dsheirer/sample/buffer/AbstractReusableBufferQueue.java
similarity index 50%
rename from src/main/java/io/github/dsheirer/sample/complex/reusable/ReusableBufferQueue.java
rename to src/main/java/io/github/dsheirer/sample/buffer/AbstractReusableBufferQueue.java
index 89f7e81b..0959b060 100644
--- a/src/main/java/io/github/dsheirer/sample/complex/reusable/ReusableBufferQueue.java
+++ b/src/main/java/io/github/dsheirer/sample/buffer/AbstractReusableBufferQueue.java
@@ -13,7 +13,7 @@
* If not, see
*
******************************************************************************/
-package io.github.dsheirer.sample.complex.reusable;
+package io.github.dsheirer.sample.buffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -21,21 +21,22 @@ import org.slf4j.LoggerFactory;
import java.util.Queue;
import java.util.concurrent.LinkedTransferQueue;
-public class ReusableBufferQueue implements IReusableBufferDisposedListener
+public abstract class AbstractReusableBufferQueue implements IReusableBufferDisposedListener
{
- private final static Logger mLog = LoggerFactory.getLogger(ReusableBufferQueue.class);
- private Queue mReusableBufferQueue = new LinkedTransferQueue<>();
+ private final static Logger mLog = LoggerFactory.getLogger(AbstractReusableBufferQueue.class);
+
+ private Queue mReusableBufferQueue = new LinkedTransferQueue<>();
private int mBufferCount = 0;
private String mDebugName;
+ private int mBufferUserCounter;
- public ReusableBufferQueue(String debugName)
+ public AbstractReusableBufferQueue(String debugName)
{
mDebugName = debugName;
}
- public ReusableBufferQueue()
+ public AbstractReusableBufferQueue()
{
-
}
public void dispose()
@@ -47,12 +48,17 @@ public class ReusableBufferQueue implements IReusableBufferDisposedListener
* Implements buffer disposed listener interface. Disposed (ie user count = 0) buffers will automatically callback
* to this method to indicate when they are disposed.
*
- * @param reusableComplexBuffer that has been disposed
+ * @param reusableBuffer that has been disposed
*/
@Override
- public void disposed(ReusableComplexBuffer reusableComplexBuffer)
+ public void disposed(T reusableBuffer)
{
- mReusableBufferQueue.offer(reusableComplexBuffer);
+ mReusableBufferQueue.offer(reusableBuffer);
+
+// if(mDebugName != null && mDebugName.contentEquals("NativeBufferConverter"))
+// {
+// mLog.debug("Reclaimed: " + reusableBuffer.name());
+// }
}
/**
@@ -62,18 +68,37 @@ public class ReusableBufferQueue implements IReusableBufferDisposedListener
* @param size of the samples that will be loaded into the buffer
* @return a reusable buffer
*/
- public ReusableComplexBuffer getBuffer(int size)
+ public T getBuffer(int size)
{
- ReusableComplexBuffer buffer = mReusableBufferQueue.poll();
+ T buffer = mReusableBufferQueue.poll();
- //Create a new buffer if we currently don't have any buffers to reuse
if(buffer == null)
{
- buffer = new ReusableComplexBuffer(this, new float[size]);
+ buffer = createBuffer(size);
mBufferCount++;
- mLog.debug("Buffer Created - Count:" + mBufferCount + (mDebugName != null ? " [" + mDebugName + "]" : ""));
+ buffer.setDebugName("Owner:" + mDebugName + " Number:" + mBufferUserCounter++ + " NEW BUFFER");
+
+// if(mDebugName != null && mDebugName.contentEquals("NativeBufferConverter"))
+// {
+// mLog.debug("Buffer Created - Count:" + mBufferCount + (mDebugName != null ? " [" + mDebugName + "]" : ""));
+// }
+ }
+ else
+ {
+ String previous = buffer.name();
+ buffer.setDebugName("Owner:" + mDebugName + " Number:" + mBufferUserCounter++);
+
+// if(mDebugName != null && mDebugName.contentEquals("NativeBufferConverter"))
+// {
+// mLog.debug("Buffer Reused: " + previous + " New Name:" + buffer.name());
+// }
}
return buffer;
}
+
+ /**
+ * Create a new buffer of the specified size
+ */
+ protected abstract T createBuffer(int size);
}
diff --git a/src/main/java/io/github/dsheirer/sample/complex/reusable/IReusableBufferDisposedListener.java b/src/main/java/io/github/dsheirer/sample/buffer/IReusableBufferDisposedListener.java
similarity index 81%
rename from src/main/java/io/github/dsheirer/sample/complex/reusable/IReusableBufferDisposedListener.java
rename to src/main/java/io/github/dsheirer/sample/buffer/IReusableBufferDisposedListener.java
index fd261e23..b3baaffb 100644
--- a/src/main/java/io/github/dsheirer/sample/complex/reusable/IReusableBufferDisposedListener.java
+++ b/src/main/java/io/github/dsheirer/sample/buffer/IReusableBufferDisposedListener.java
@@ -13,13 +13,13 @@
* If not, see
*
******************************************************************************/
-package io.github.dsheirer.sample.complex.reusable;
+package io.github.dsheirer.sample.buffer;
-public interface IReusableBufferDisposedListener
+public interface IReusableBufferDisposedListener
{
/**
* Notifies the listener that the timestamped buffer has been disposed and can now be reused.
- * @param reusableComplexBuffer that has been disposed
+ * @param t reusableBuffer that has been disposed
*/
- void disposed(ReusableComplexBuffer reusableComplexBuffer);
+ void disposed(T t);
}
diff --git a/src/main/java/io/github/dsheirer/sample/complex/reusable/IReusableComplexBufferProvider.java b/src/main/java/io/github/dsheirer/sample/buffer/IReusableBufferProvider.java
similarity index 83%
rename from src/main/java/io/github/dsheirer/sample/complex/reusable/IReusableComplexBufferProvider.java
rename to src/main/java/io/github/dsheirer/sample/buffer/IReusableBufferProvider.java
index 96ad66dd..afacda85 100644
--- a/src/main/java/io/github/dsheirer/sample/complex/reusable/IReusableComplexBufferProvider.java
+++ b/src/main/java/io/github/dsheirer/sample/buffer/IReusableBufferProvider.java
@@ -13,21 +13,21 @@
* If not, see
*
******************************************************************************/
-package io.github.dsheirer.sample.complex.reusable;
+package io.github.dsheirer.sample.buffer;
import io.github.dsheirer.sample.Listener;
-public interface IReusableComplexBufferProvider
+public interface IReusableBufferProvider
{
/**
* Adds the listener to receive complex buffer samples
*/
- void addBufferListener(Listener listener);
+ void addBufferListener(Listener listener);
/**
* Removes the listener from receiving complex buffer samples
*/
- void removeBufferListener(Listener listener);
+ void removeBufferListener(Listener listener);
/**
* Indicates if there are any complex buffer listeners registered
diff --git a/src/main/java/io/github/dsheirer/sample/complex/reusable/IReusableComplexBufferListener.java b/src/main/java/io/github/dsheirer/sample/buffer/IReusableComplexBufferListener.java
similarity index 84%
rename from src/main/java/io/github/dsheirer/sample/complex/reusable/IReusableComplexBufferListener.java
rename to src/main/java/io/github/dsheirer/sample/buffer/IReusableComplexBufferListener.java
index 2f7a7306..47eada60 100644
--- a/src/main/java/io/github/dsheirer/sample/complex/reusable/IReusableComplexBufferListener.java
+++ b/src/main/java/io/github/dsheirer/sample/buffer/IReusableComplexBufferListener.java
@@ -13,11 +13,11 @@
* If not, see
*
******************************************************************************/
-package io.github.dsheirer.sample.complex.reusable;
+package io.github.dsheirer.sample.buffer;
import io.github.dsheirer.sample.Listener;
-public interface IReusableComplexBufferListener
+public interface IReusableComplexBufferListener
{
- Listener getReusableComplexBufferListener();
+ Listener getReusableComplexBufferListener();
}
diff --git a/src/main/java/io/github/dsheirer/sample/complex/reusable/OverflowableReusableBufferTransferQueue.java b/src/main/java/io/github/dsheirer/sample/buffer/OverflowableReusableBufferTransferQueue.java
similarity index 85%
rename from src/main/java/io/github/dsheirer/sample/complex/reusable/OverflowableReusableBufferTransferQueue.java
rename to src/main/java/io/github/dsheirer/sample/buffer/OverflowableReusableBufferTransferQueue.java
index 05486981..914833bb 100644
--- a/src/main/java/io/github/dsheirer/sample/complex/reusable/OverflowableReusableBufferTransferQueue.java
+++ b/src/main/java/io/github/dsheirer/sample/buffer/OverflowableReusableBufferTransferQueue.java
@@ -13,11 +13,11 @@
* If not, see
*
******************************************************************************/
-package io.github.dsheirer.sample.complex.reusable;
+package io.github.dsheirer.sample.buffer;
import io.github.dsheirer.sample.OverflowableTransferQueue;
-public class OverflowableReusableBufferTransferQueue extends OverflowableTransferQueue
+public class OverflowableReusableBufferTransferQueue extends OverflowableTransferQueue
{
/**
* Concurrent transfer queue that couples a higher-throughput linked transfer queue with an atomic integer for
@@ -38,12 +38,12 @@ public class OverflowableReusableBufferTransferQueue extends OverflowableTransfe
* Overrides the overflow method to decrement the user count on any buffers that are being discarded when the queue
* is in an overflow state.
*
- * @param reusableComplexBuffer that will be discarded
+ * @param t reusableBuffer that will be discarded
*/
@Override
- protected void overflow(ReusableComplexBuffer reusableComplexBuffer)
+ protected void overflow(T t)
{
- reusableComplexBuffer.decrementUserCount();
+ t.decrementUserCount();
}
/**
@@ -54,7 +54,7 @@ public class OverflowableReusableBufferTransferQueue extends OverflowableTransfe
{
synchronized(mQueue)
{
- ReusableComplexBuffer buffer = mQueue.poll();
+ T buffer = mQueue.poll();
while(buffer != null)
{
diff --git a/src/main/java/io/github/dsheirer/sample/complex/reusable/ReusableComplexBuffer.java b/src/main/java/io/github/dsheirer/sample/buffer/ReusableBuffer.java
similarity index 80%
rename from src/main/java/io/github/dsheirer/sample/complex/reusable/ReusableComplexBuffer.java
rename to src/main/java/io/github/dsheirer/sample/buffer/ReusableBuffer.java
index 151852af..d9434004 100644
--- a/src/main/java/io/github/dsheirer/sample/complex/reusable/ReusableComplexBuffer.java
+++ b/src/main/java/io/github/dsheirer/sample/buffer/ReusableBuffer.java
@@ -13,19 +13,20 @@
* If not, see
*
******************************************************************************/
-package io.github.dsheirer.sample.complex.reusable;
+package io.github.dsheirer.sample.buffer;
-import io.github.dsheirer.sample.complex.ComplexBuffer;
import org.apache.commons.lang3.Validate;
import java.nio.FloatBuffer;
import java.util.concurrent.atomic.AtomicInteger;
-public class ReusableComplexBuffer extends ComplexBuffer
+public class ReusableBuffer
{
- private IReusableBufferDisposedListener mDisposalListener;
+ private float[] mSamples;
+ private IReusableBufferDisposedListener mBufferDisposedListener;
private long mTimestamp;
private AtomicInteger mUserCount = new AtomicInteger();
+ private String mDebugName;
/**
* Creates a reusable, timestamped complex buffer using the specified time in milliseconds.
@@ -34,32 +35,40 @@ public class ReusableComplexBuffer extends ComplexBuffer
* 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 disposalListener to be notified when all consumers/users are finished using the buffer
+ * @param bufferDisposedListener to be notified when all consumers/users are finished using the buffer
* @param samples of data
* @param timestamp in millis for the buffer
*/
- public ReusableComplexBuffer(IReusableBufferDisposedListener disposalListener, float[] samples, long timestamp)
+ ReusableBuffer(IReusableBufferDisposedListener bufferDisposedListener, float[] samples, long timestamp)
{
- super(samples);
+ mSamples = samples;
- Validate.notNull(disposalListener, "Timestamped Buffer Listener cannot be null");
- mDisposalListener = disposalListener;
+ Validate.notNull(bufferDisposedListener, "Reusable Buffer Listener cannot be null");
+ mBufferDisposedListener = bufferDisposedListener;
mTimestamp = timestamp;
}
- /**
- * Constructs a timestamped complex 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 disposalListener to be notified when all consumers are finished using the buffer
- * @param samples of data
- */
- public ReusableComplexBuffer(IReusableBufferDisposedListener disposalListener, float[] samples)
+ public void setDebugName(String debugName)
{
- this(disposalListener, samples, System.currentTimeMillis());
+ mDebugName = debugName;
+ }
+
+ public String name()
+ {
+ return (mDebugName != null ? mDebugName : "(null)") + " User Count:" + getUserCount();
+ }
+
+ public String toString()
+ {
+ return name();
+ }
+
+ /**
+ * Samples for this buffer
+ */
+ public float[] getSamples()
+ {
+ return mSamples;
}
/**
@@ -74,11 +83,26 @@ public class ReusableComplexBuffer extends ComplexBuffer
}
/**
- * Number of complex samples contained in this buffer
+ * Number of samples contained in this buffer
*/
- public int getSampleLength()
+ public int getSampleCount()
{
- return getSamples().length / 2;
+ return getSamples().length;
+ }
+
+ /**
+ * Constructs a timestamped complex 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 samples of data
+ */
+ public ReusableBuffer(IReusableBufferDisposedListener bufferDisposedListener, float[] samples)
+ {
+ this(bufferDisposedListener, samples, System.currentTimeMillis());
}
/**
@@ -173,21 +197,19 @@ public class ReusableComplexBuffer extends ComplexBuffer
*
* This method is thread-safe.
*/
- public ReusableComplexBuffer decrementUserCount()
+ public void decrementUserCount()
{
int currentCount = mUserCount.decrementAndGet();
if(currentCount == 0)
{
- mDisposalListener.disposed(this);
+ mBufferDisposedListener.disposed(this);
}
else if(currentCount < 0)
{
throw new IllegalStateException("User count is below zero. This indicates that this buffer's decrement" +
" user count was invoked by more than the expected user count");
}
-
- return this;
}
/**
@@ -199,10 +221,9 @@ public class ReusableComplexBuffer extends ComplexBuffer
*
* This method is thread-safe.
*/
- public ReusableComplexBuffer incrementUserCount()
+ public void incrementUserCount()
{
mUserCount.incrementAndGet();
- return this;
}
/**
@@ -216,9 +237,16 @@ public class ReusableComplexBuffer extends ComplexBuffer
*
* @param additionalUserCount to add to the current user count
*/
- public ReusableComplexBuffer incrementUserCount(int additionalUserCount)
+ public void incrementUserCount(int additionalUserCount)
{
mUserCount.addAndGet(additionalUserCount);
- return this;
+ }
+
+ /**
+ * Number of users currently registered for this buffer
+ */
+ public int getUserCount()
+ {
+ return mUserCount.get();
}
}
diff --git a/src/main/java/io/github/dsheirer/sample/complex/reusable/ReusableBufferAssembler.java b/src/main/java/io/github/dsheirer/sample/buffer/ReusableBufferAssembler.java
similarity index 95%
rename from src/main/java/io/github/dsheirer/sample/complex/reusable/ReusableBufferAssembler.java
rename to src/main/java/io/github/dsheirer/sample/buffer/ReusableBufferAssembler.java
index a58b62f3..d1f2847d 100644
--- a/src/main/java/io/github/dsheirer/sample/complex/reusable/ReusableBufferAssembler.java
+++ b/src/main/java/io/github/dsheirer/sample/buffer/ReusableBufferAssembler.java
@@ -13,7 +13,7 @@
* If not, see
*
******************************************************************************/
-package io.github.dsheirer.sample.complex.reusable;
+package io.github.dsheirer.sample.buffer;
import io.github.dsheirer.dsp.filter.channelizer.SampleTimestampManager;
import io.github.dsheirer.sample.Listener;
@@ -27,7 +27,7 @@ import java.nio.FloatBuffer;
*/
public class ReusableBufferAssembler
{
- private ReusableBufferQueue mReusableBufferQueue = new ReusableBufferQueue();
+ private ReusableComplexBufferQueue mReusableComplexBufferQueue = new ReusableComplexBufferQueue("ReusableBufferAssembler");
private SampleTimestampManager mTimestampManager;
private FloatBuffer mBuffer;
private int mBufferSize;
@@ -115,7 +115,7 @@ public class ReusableBufferAssembler
if(mListener != null && mBuffer.position() > 0)
{
mBuffer.rewind();
- ReusableComplexBuffer reusableComplexBuffer = mReusableBufferQueue.getBuffer(mBufferSize);
+ ReusableComplexBuffer reusableComplexBuffer = mReusableComplexBufferQueue.getBuffer(mBufferSize);
reusableComplexBuffer.reloadFrom(mBuffer, mCurrentBufferTimestamp);
reusableComplexBuffer.setUserCount(1);
mListener.receive(reusableComplexBuffer);
diff --git a/src/main/java/io/github/dsheirer/sample/complex/reusable/ReusableBufferBroadcaster.java b/src/main/java/io/github/dsheirer/sample/buffer/ReusableBufferBroadcaster.java
similarity index 66%
rename from src/main/java/io/github/dsheirer/sample/complex/reusable/ReusableBufferBroadcaster.java
rename to src/main/java/io/github/dsheirer/sample/buffer/ReusableBufferBroadcaster.java
index e2ac0f80..2df8493c 100644
--- a/src/main/java/io/github/dsheirer/sample/complex/reusable/ReusableBufferBroadcaster.java
+++ b/src/main/java/io/github/dsheirer/sample/buffer/ReusableBufferBroadcaster.java
@@ -13,7 +13,7 @@
* If not, see
*
******************************************************************************/
-package io.github.dsheirer.sample.complex.reusable;
+package io.github.dsheirer.sample.buffer;
import io.github.dsheirer.sample.Broadcaster;
import io.github.dsheirer.sample.Listener;
@@ -36,29 +36,10 @@ public class ReusableBufferBroadcaster extends Broadcaster listener : mListeners)
{
- if(listenerCount > 0)
- {
- listener.receive(reusableComplexBuffer);
- }
-
- listenerCount--;
- }
-
- while(listenerCount > 0)
- {
- reusableComplexBuffer.decrementUserCount();
- listenerCount--;
+ reusableComplexBuffer.incrementUserCount();
+ listener.receive(reusableComplexBuffer);
}
//Decrement user counter for this broadcaster
diff --git a/src/main/java/io/github/dsheirer/sample/buffer/ReusableBufferQueue.java b/src/main/java/io/github/dsheirer/sample/buffer/ReusableBufferQueue.java
new file mode 100644
index 00000000..85bb5efc
--- /dev/null
+++ b/src/main/java/io/github/dsheirer/sample/buffer/ReusableBufferQueue.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * 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
+ *
+ ******************************************************************************/
+package io.github.dsheirer.sample.buffer;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ReusableBufferQueue extends AbstractReusableBufferQueue
+{
+ private final static Logger mLog = LoggerFactory.getLogger(ReusableBufferQueue.class);
+
+ public ReusableBufferQueue(String debugName)
+ {
+ super(debugName);
+ }
+
+ public ReusableBufferQueue()
+ {
+ }
+
+ @Override
+ protected ReusableBuffer createBuffer(int size)
+ {
+ return new ReusableBuffer(this, new float[size]);
+ }
+}
diff --git a/src/main/java/io/github/dsheirer/sample/buffer/ReusableComplexBuffer.java b/src/main/java/io/github/dsheirer/sample/buffer/ReusableComplexBuffer.java
new file mode 100644
index 00000000..bc768d7c
--- /dev/null
+++ b/src/main/java/io/github/dsheirer/sample/buffer/ReusableComplexBuffer.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * 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
+ *
+ ******************************************************************************/
+package io.github.dsheirer.sample.buffer;
+
+public class ReusableComplexBuffer extends ReusableBuffer
+{
+ /**
+ * Creates a reusable, timestamped complex 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 disposalListener to be notified when all consumers/users are finished using the buffer
+ * @param samples of data
+ * @param timestamp in millis for the buffer
+ */
+ ReusableComplexBuffer(IReusableBufferDisposedListener disposalListener, float[] samples, long timestamp)
+ {
+ super(disposalListener, samples, timestamp);
+ }
+
+ /**
+ * Constructs a timestamped complex 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 disposalListener to be notified when all consumers are finished using the buffer
+ * @param samples of data
+ */
+ protected ReusableComplexBuffer(IReusableBufferDisposedListener disposalListener, float[] samples)
+ {
+ this(disposalListener, samples, System.currentTimeMillis());
+ }
+
+ /**
+ * Number of complex samples contained in this buffer
+ */
+ @Override
+ public int getSampleCount()
+ {
+ return getSamples().length / 2;
+ }
+}
diff --git a/src/main/java/io/github/dsheirer/sample/buffer/ReusableComplexBufferQueue.java b/src/main/java/io/github/dsheirer/sample/buffer/ReusableComplexBufferQueue.java
new file mode 100644
index 00000000..0c52454e
--- /dev/null
+++ b/src/main/java/io/github/dsheirer/sample/buffer/ReusableComplexBufferQueue.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * 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
+ *
+ ******************************************************************************/
+package io.github.dsheirer.sample.buffer;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ReusableComplexBufferQueue extends AbstractReusableBufferQueue
+{
+ private final static Logger mLog = LoggerFactory.getLogger(ReusableComplexBufferQueue.class);
+
+ public ReusableComplexBufferQueue(String debugName)
+ {
+ super(debugName);
+ }
+
+ public ReusableComplexBufferQueue()
+ {
+ }
+
+ @Override
+ protected ReusableComplexBuffer createBuffer(int size)
+ {
+ return new ReusableComplexBuffer(this, new float[size]);
+ }
+}
diff --git a/src/main/java/io/github/dsheirer/source/ComplexSource.java b/src/main/java/io/github/dsheirer/source/ComplexSource.java
index a06be2dc..098641d5 100644
--- a/src/main/java/io/github/dsheirer/source/ComplexSource.java
+++ b/src/main/java/io/github/dsheirer/source/ComplexSource.java
@@ -17,7 +17,7 @@ package io.github.dsheirer.source;
import io.github.dsheirer.sample.Provider;
import io.github.dsheirer.sample.SampleType;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
public abstract class ComplexSource extends Source implements Provider
{
diff --git a/src/main/java/io/github/dsheirer/source/mixer/ComplexMixer.java b/src/main/java/io/github/dsheirer/source/mixer/ComplexMixer.java
index fc117def..9d83fdac 100644
--- a/src/main/java/io/github/dsheirer/source/mixer/ComplexMixer.java
+++ b/src/main/java/io/github/dsheirer/source/mixer/ComplexMixer.java
@@ -17,8 +17,8 @@ package io.github.dsheirer.source.mixer;
import io.github.dsheirer.sample.Listener;
import io.github.dsheirer.sample.adapter.IComplexSampleAdapter;
-import io.github.dsheirer.sample.complex.reusable.ReusableBufferQueue;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBufferQueue;
import io.github.dsheirer.source.SourceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -42,7 +42,7 @@ public class ComplexMixer
private int mBytesPerFrame = 0;
private IComplexSampleAdapter mSampleAdapter;
private Listener mListener;
- private ReusableBufferQueue mReusableBufferQueue = new ReusableBufferQueue();
+ private ReusableComplexBufferQueue mReusableComplexBufferQueue = new ReusableComplexBufferQueue("ComplexMixer");
/**
* Complex Mixer - constructs a reader on the mixer/sound card target data line using the specified audio
@@ -173,7 +173,7 @@ public class ComplexMixer
/* Dispatch samples to registered listeners */
if(mListener != null)
{
- ReusableComplexBuffer reusableComplexBuffer = mReusableBufferQueue.getBuffer(sampleCount);
+ ReusableComplexBuffer reusableComplexBuffer = mReusableComplexBufferQueue.getBuffer(sampleCount);
//Convert samples and load into reusable buffer
mSampleAdapter.convertAndLoad(buffer, reusableComplexBuffer);
diff --git a/src/main/java/io/github/dsheirer/source/tuner/TunerController.java b/src/main/java/io/github/dsheirer/source/tuner/TunerController.java
index ebd1c516..4d4b3377 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/TunerController.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/TunerController.java
@@ -18,9 +18,9 @@
package io.github.dsheirer.source.tuner;
import io.github.dsheirer.sample.Listener;
-import io.github.dsheirer.sample.complex.reusable.IReusableComplexBufferProvider;
-import io.github.dsheirer.sample.complex.reusable.ReusableBufferBroadcaster;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.IReusableBufferProvider;
+import io.github.dsheirer.sample.buffer.ReusableBufferBroadcaster;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.source.ISourceEventListener;
import io.github.dsheirer.source.ISourceEventProcessor;
import io.github.dsheirer.source.SourceEvent;
@@ -33,10 +33,10 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class TunerController implements Tunable, ISourceEventProcessor, ISourceEventListener,
- IReusableComplexBufferProvider, Listener
+ IReusableBufferProvider, Listener
{
private final static Logger mLog = LoggerFactory.getLogger(TunerController.class);
- protected ReusableBufferBroadcaster mSampleBroadcaster = new ReusableBufferBroadcaster();
+ protected ReusableBufferBroadcaster mReusableBufferBroadcaster = new ReusableBufferBroadcaster();
protected FrequencyController mFrequencyController;
private int mMiddleUnusableHalfBandwidth;
private double mUsableBandwidthPercentage;
@@ -263,7 +263,7 @@ public abstract class TunerController implements Tunable, ISourceEventProcessor,
@Override
public void addBufferListener(Listener listener)
{
- mSampleBroadcaster.addListener(listener);
+ mReusableBufferBroadcaster.addListener(listener);
}
/**
@@ -272,7 +272,7 @@ public abstract class TunerController implements Tunable, ISourceEventProcessor,
@Override
public void removeBufferListener(Listener listener)
{
- mSampleBroadcaster.removeListener(listener);
+ mReusableBufferBroadcaster.removeListener(listener);
}
/**
@@ -281,7 +281,7 @@ public abstract class TunerController implements Tunable, ISourceEventProcessor,
@Override
public boolean hasBufferListeners()
{
- return mSampleBroadcaster.hasListeners();
+ return mReusableBufferBroadcaster.hasListeners();
}
/**
@@ -289,7 +289,7 @@ public abstract class TunerController implements Tunable, ISourceEventProcessor,
*/
protected void broadcast(ReusableComplexBuffer reusableComplexBuffer)
{
- mSampleBroadcaster.broadcast(reusableComplexBuffer.incrementUserCount());
+ mReusableBufferBroadcaster.broadcast(reusableComplexBuffer);
}
/**
diff --git a/src/main/java/io/github/dsheirer/source/tuner/channel/TunerChannelSource.java b/src/main/java/io/github/dsheirer/source/tuner/channel/TunerChannelSource.java
index b195afac..914458ab 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/channel/TunerChannelSource.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/channel/TunerChannelSource.java
@@ -19,7 +19,7 @@
package io.github.dsheirer.source.tuner.channel;
import io.github.dsheirer.sample.Listener;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.source.ComplexSource;
import io.github.dsheirer.source.ISourceEventProcessor;
import io.github.dsheirer.source.SourceEvent;
diff --git a/src/main/java/io/github/dsheirer/source/tuner/fcd/FCDTunerController.java b/src/main/java/io/github/dsheirer/source/tuner/fcd/FCDTunerController.java
index 9e77661e..002bcc63 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/fcd/FCDTunerController.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/fcd/FCDTunerController.java
@@ -20,7 +20,7 @@ package io.github.dsheirer.source.tuner.fcd;
import io.github.dsheirer.sample.Listener;
import io.github.dsheirer.sample.adapter.ComplexShortAdapter;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.source.SourceException;
import io.github.dsheirer.source.mixer.ComplexMixer;
import io.github.dsheirer.source.tuner.MixerTunerDataLine;
@@ -88,7 +88,7 @@ public abstract class FCDTunerController extends TunerController
}
mComplexMixer = new ComplexMixer( mixerTDL.getTargetDataLine(), audioFormat, tunerName,
- new ComplexShortAdapter(), mSampleBroadcaster);
+ new ComplexShortAdapter(), mReusableBufferBroadcaster);
}
/**
diff --git a/src/main/java/io/github/dsheirer/source/tuner/manager/ChannelSourceManager.java b/src/main/java/io/github/dsheirer/source/tuner/manager/ChannelSourceManager.java
index 9280ac4b..1b113313 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/manager/ChannelSourceManager.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/manager/ChannelSourceManager.java
@@ -54,7 +54,8 @@ public abstract class ChannelSourceManager implements ISourceEventProcessor
*/
public abstract TunerChannelSource getSource(TunerChannel tunerChannel);
- public abstract TunerChannelSource getSpecialSource(int index);
+ //TODO: remove this testing method when finished with polyphase channel manager
+ public abstract TunerChannelSource getTestingSource(int index);
/**
* Adds a listener to receive source events
diff --git a/src/main/java/io/github/dsheirer/source/tuner/manager/TunerChannelSourceManager.java b/src/main/java/io/github/dsheirer/source/tuner/manager/TunerChannelSourceManager.java
index d3f2e7d8..0390fa40 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/manager/TunerChannelSourceManager.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/manager/TunerChannelSourceManager.java
@@ -50,10 +50,10 @@ public class TunerChannelSourceManager extends ChannelSourceManager
}
@Override
- public TunerChannelSource getSpecialSource(int index)
+ public TunerChannelSource getTestingSource(int index)
{
//TODO: remove this debug method
- return mPolyphaseChannelManager.getSpecialChannel(index);
+ return mPolyphaseChannelManager.getTestChannel(index);
}
/**
diff --git a/src/main/java/io/github/dsheirer/source/tuner/rtl/RTL2832TunerController.java b/src/main/java/io/github/dsheirer/source/tuner/rtl/RTL2832TunerController.java
index a6c8c138..95fe2445 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/rtl/RTL2832TunerController.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/rtl/RTL2832TunerController.java
@@ -22,7 +22,7 @@
package io.github.dsheirer.source.tuner.rtl;
import io.github.dsheirer.sample.Listener;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.source.SourceException;
import io.github.dsheirer.source.tuner.TunerManager;
import io.github.dsheirer.source.tuner.TunerType;
diff --git a/src/main/java/io/github/dsheirer/source/tuner/test/SampleGenerator.java b/src/main/java/io/github/dsheirer/source/tuner/test/SampleGenerator.java
index 123fde8f..5c34cdb1 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/test/SampleGenerator.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/test/SampleGenerator.java
@@ -18,9 +18,9 @@ package io.github.dsheirer.source.tuner.test;
import io.github.dsheirer.dsp.mixer.IOscillator;
import io.github.dsheirer.dsp.mixer.LowPhaseNoiseOscillator;
import io.github.dsheirer.sample.Listener;
-import io.github.dsheirer.sample.complex.reusable.ReusableBufferBroadcaster;
-import io.github.dsheirer.sample.complex.reusable.ReusableBufferQueue;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableBufferBroadcaster;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBufferQueue;
import io.github.dsheirer.util.ThreadPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -185,18 +185,19 @@ public class SampleGenerator
public class Generator implements Runnable
{
private int mTriggerInterval = 0;
- private ReusableBufferQueue mReusableBufferQueue = new ReusableBufferQueue("** Sample Generator **");
+ private ReusableComplexBufferQueue mReusableComplexBufferQueue = new ReusableComplexBufferQueue("SampleGenerator");
@Override
public void run()
{
if(mComplexBufferBroadcaster.hasListeners())
{
- ReusableComplexBuffer reusableComplexBuffer = mReusableBufferQueue.getBuffer(mSamplesPerInterval);
+ ReusableComplexBuffer reusableComplexBuffer = mReusableComplexBufferQueue.getBuffer(mSamplesPerInterval);
mOscillator.generateComplex(reusableComplexBuffer);
- mComplexBufferBroadcaster.broadcast(reusableComplexBuffer.incrementUserCount());
+ reusableComplexBuffer.incrementUserCount();
+ mComplexBufferBroadcaster.broadcast(reusableComplexBuffer);
if(mSweepUpdateInterval != 0)
{
diff --git a/src/main/java/io/github/dsheirer/source/tuner/test/TestTunerController.java b/src/main/java/io/github/dsheirer/source/tuner/test/TestTunerController.java
index 0638232b..fc2489f2 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/test/TestTunerController.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/test/TestTunerController.java
@@ -19,7 +19,7 @@
package io.github.dsheirer.source.tuner.test;
import io.github.dsheirer.sample.Listener;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.source.SourceException;
import io.github.dsheirer.source.tuner.TunerController;
import io.github.dsheirer.source.tuner.configuration.TunerConfiguration;
diff --git a/src/main/java/io/github/dsheirer/source/tuner/usb/USBTransferProcessor.java b/src/main/java/io/github/dsheirer/source/tuner/usb/USBTransferProcessor.java
index 129f228e..55a09d1c 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/usb/USBTransferProcessor.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/usb/USBTransferProcessor.java
@@ -16,7 +16,7 @@
package io.github.dsheirer.source.tuner.usb;
import io.github.dsheirer.sample.Listener;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.source.tuner.TunerManager;
import io.github.dsheirer.source.tuner.usb.converter.NativeBufferConverter;
import io.github.dsheirer.util.ThreadPool;
@@ -394,9 +394,10 @@ public class USBTransferProcessor implements TransferCallback
{
ByteBuffer nativeBuffer = transfer.buffer();
- ReusableComplexBuffer sampleBuffer = mNativeBufferConverter.convert(nativeBuffer, transfer.actualLength());
+ ReusableComplexBuffer reusableComplexBuffer =
+ mNativeBufferConverter.convert(nativeBuffer, transfer.actualLength());
- mComplexBufferListener.receive(sampleBuffer);
+ mComplexBufferListener.receive(reusableComplexBuffer);
}
transfer.buffer().rewind();
diff --git a/src/main/java/io/github/dsheirer/source/tuner/usb/USBTunerController.java b/src/main/java/io/github/dsheirer/source/tuner/usb/USBTunerController.java
index db114e7d..185f901a 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/usb/USBTunerController.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/usb/USBTunerController.java
@@ -19,7 +19,7 @@
package io.github.dsheirer.source.tuner.usb;
import io.github.dsheirer.sample.Listener;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.source.tuner.TunerController;
public abstract class USBTunerController extends TunerController
diff --git a/src/main/java/io/github/dsheirer/source/tuner/usb/converter/NativeBufferConverter.java b/src/main/java/io/github/dsheirer/source/tuner/usb/converter/NativeBufferConverter.java
index 9d9dfcbf..cbe86064 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/usb/converter/NativeBufferConverter.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/usb/converter/NativeBufferConverter.java
@@ -15,15 +15,15 @@
******************************************************************************/
package io.github.dsheirer.source.tuner.usb.converter;
-import io.github.dsheirer.sample.complex.reusable.ReusableBufferQueue;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBufferQueue;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
public abstract class NativeBufferConverter
{
- private ReusableBufferQueue mReusableBufferQueue = new ReusableBufferQueue();
+ private ReusableComplexBufferQueue mReusableComplexBufferQueue = new ReusableComplexBufferQueue("NativeBufferConverter");
/**
* Converts native byte buffers into complex float samples and produces reusable complex sample buffers. Tracks
@@ -45,10 +45,11 @@ public abstract class NativeBufferConverter
{
FloatBuffer floatBuffer = convertSamples(byteBuffer, length);
- ReusableComplexBuffer reusableComplexBuffer = mReusableBufferQueue.getBuffer(floatBuffer.capacity());
+ ReusableComplexBuffer reusableComplexBuffer = mReusableComplexBufferQueue.getBuffer(floatBuffer.capacity());
//The reusable buffer will rewind the float buffer to the beginning
reusableComplexBuffer.reloadFrom(floatBuffer, System.currentTimeMillis());
+ reusableComplexBuffer.incrementUserCount();
return reusableComplexBuffer;
}
diff --git a/src/main/java/io/github/dsheirer/source/wave/ComplexWaveSource.java b/src/main/java/io/github/dsheirer/source/wave/ComplexWaveSource.java
index 256a53f3..219a5e1b 100644
--- a/src/main/java/io/github/dsheirer/source/wave/ComplexWaveSource.java
+++ b/src/main/java/io/github/dsheirer/source/wave/ComplexWaveSource.java
@@ -17,8 +17,8 @@ package io.github.dsheirer.source.wave;
import io.github.dsheirer.sample.ConversionUtils;
import io.github.dsheirer.sample.Listener;
-import io.github.dsheirer.sample.complex.reusable.ReusableBufferQueue;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBufferQueue;
import io.github.dsheirer.source.ComplexSource;
import io.github.dsheirer.source.IControllableFileSource;
import io.github.dsheirer.source.IFrameLocationListener;
@@ -45,7 +45,7 @@ public class ComplexWaveSource extends ComplexSource implements IControllableFil
private Listener mListener;
private AudioInputStream mInputStream;
private File mFile;
- private ReusableBufferQueue mReusableBufferQueue = new ReusableBufferQueue("Complex Wave Source");
+ private ReusableComplexBufferQueue mReusableComplexBufferQueue = new ReusableComplexBufferQueue("ComplexWaveSource");
public ComplexWaveSource(File file) throws IOException
{
@@ -216,7 +216,7 @@ public class ComplexWaveSource extends ComplexSource implements IControllableFil
float[] samples = ConversionUtils.convertFromSigned16BitSamples(buffer);
- ReusableComplexBuffer reusableBuffer = mReusableBufferQueue.getBuffer(samples.length);
+ ReusableComplexBuffer reusableBuffer = mReusableComplexBufferQueue.getBuffer(samples.length);
reusableBuffer.reloadFrom(samples, System.currentTimeMillis());
reusableBuffer.incrementUserCount();
mListener.receive(reusableBuffer);
diff --git a/src/main/java/io/github/dsheirer/spectrum/ChannelSpectrumPanel.java b/src/main/java/io/github/dsheirer/spectrum/ChannelSpectrumPanel.java
index 0431ff26..4cc781df 100644
--- a/src/main/java/io/github/dsheirer/spectrum/ChannelSpectrumPanel.java
+++ b/src/main/java/io/github/dsheirer/spectrum/ChannelSpectrumPanel.java
@@ -26,8 +26,8 @@ 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.complex.reusable.ReusableBufferQueue;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBufferQueue;
import io.github.dsheirer.sample.real.RealBuffer;
import io.github.dsheirer.settings.ColorSetting.ColorSettingName;
import io.github.dsheirer.settings.ColorSettingMenuItem;
@@ -69,435 +69,450 @@ public class ChannelSpectrumPanel extends JPanel implements ChannelEventListener
private JLayeredPane mLayeredPane;
private SpectrumPanel mSpectrumPanel;
private ChannelOverlayPanel mOverlayPanel;
- private ReusableBufferQueue mReusableBufferQueue = new ReusableBufferQueue();
+ private ReusableComplexBufferQueue mReusableComplexBufferQueue = new ReusableComplexBufferQueue("ChannelSpectrumPanel");
private Channel mCurrentChannel;
private int mSampleBufferSize = 2400;
- private HalfBandFilter_RB_RB mDecimatingFilter = new HalfBandFilter_RB_RB(
- Filters.FIR_HALF_BAND_31T_ONE_EIGHTH_FCO.getCoefficients(), 1.0f, true );
-
+ private HalfBandFilter_RB_RB mDecimatingFilter = new HalfBandFilter_RB_RB(
+ Filters.FIR_HALF_BAND_31T_ONE_EIGHTH_FCO.getCoefficients(), 1.0f, true);
+
private AtomicBoolean mEnabled = new AtomicBoolean();
-
+
private SettingsManager mSettingsManager;
private ChannelProcessingManager mChannelProcessingManager;
- public ChannelSpectrumPanel( SettingsManager settingsManager,
- ChannelProcessingManager channelProcessingManager )
+ public ChannelSpectrumPanel(SettingsManager settingsManager,
+ ChannelProcessingManager channelProcessingManager)
{
- mSettingsManager = settingsManager;
- mChannelProcessingManager = channelProcessingManager;
-
- if( mSettingsManager != null )
- {
- mSettingsManager.addListener( this );
- }
-
- mSpectrumPanel = new SpectrumPanel( mSettingsManager );
- mSpectrumPanel.setAveraging( 1 );
+ mSettingsManager = settingsManager;
+ mChannelProcessingManager = channelProcessingManager;
- mOverlayPanel = new ChannelOverlayPanel( mSettingsManager );
- mDFTProcessor.addConverter( mDFTConverter );
- mDFTConverter.addListener( mSpectrumPanel );
+ if(mSettingsManager != null)
+ {
+ mSettingsManager.addListener(this);
+ }
+
+ mSpectrumPanel = new SpectrumPanel(mSettingsManager);
+ mSpectrumPanel.setAveraging(1);
+
+ mOverlayPanel = new ChannelOverlayPanel(mSettingsManager);
+ mDFTProcessor.addConverter(mDFTConverter);
+ mDFTConverter.addListener(mSpectrumPanel);
/* Set the DFTProcessor to the decimated 24kHz sample rate */
mDFTProcessor.process(SourceEvent.sampleRateChange(24000.0));
initGui();
}
-
+
public void dispose()
{
- setEnabled( false );
-
- mDFTProcessor.dispose();
+ setEnabled(false);
- if( mSettingsManager != null )
- {
- mSettingsManager.removeListener( this );
- }
-
- mSettingsManager = null;
- mCurrentChannel = null;
- mDFTProcessor = null;
- mSpectrumPanel = null;
+ mDFTProcessor.dispose();
+
+ if(mSettingsManager != null)
+ {
+ mSettingsManager.removeListener(this);
+ }
+
+ mSettingsManager = null;
+ mCurrentChannel = null;
+ mDFTProcessor = null;
+ mSpectrumPanel = null;
}
-
- public void setFrameRate( int framesPerSecond )
+
+ public void setFrameRate(int framesPerSecond)
{
- mSampleBufferSize = (int)( 48000 / framesPerSecond );
-
- mDFTProcessor.setFrameRate( framesPerSecond );
+ mSampleBufferSize = (int)(48000 / framesPerSecond);
+
+ mDFTProcessor.setFrameRate(framesPerSecond);
}
-
+
private void initGui()
{
- setLayout( new MigLayout( "insets 0 0 0 0 ",
- "[grow,fill]",
- "[grow,fill]") );
-
- mLayeredPane = new JLayeredPane();
- mLayeredPane.addComponentListener( new ResizeListener() );
-
- MouseEventProcessor mouser = new MouseEventProcessor();
-
- mOverlayPanel.addMouseListener( mouser );
- mOverlayPanel.addMouseMotionListener( mouser );
-
- mLayeredPane.add( mSpectrumPanel, new Integer( 0 ), 0 );
- mLayeredPane.add( mOverlayPanel, new Integer( 1 ), 0 );
+ setLayout(new MigLayout("insets 0 0 0 0 ",
+ "[grow,fill]",
+ "[grow,fill]"));
- add( mLayeredPane );
+ mLayeredPane = new JLayeredPane();
+ mLayeredPane.addComponentListener(new ResizeListener());
+
+ MouseEventProcessor mouser = new MouseEventProcessor();
+
+ mOverlayPanel.addMouseListener(mouser);
+ mOverlayPanel.addMouseMotionListener(mouser);
+
+ mLayeredPane.add(mSpectrumPanel, new Integer(0), 0);
+ mLayeredPane.add(mOverlayPanel, new Integer(1), 0);
+
+ add(mLayeredPane);
}
-
- public void setEnabled( boolean enabled )
+
+ public void setEnabled(boolean enabled)
{
- if( enabled && mEnabled.compareAndSet( false, true ) )
- {
- start();
- }
- else if( !enabled && mEnabled.compareAndSet( true, false ) )
- {
- stop();
- }
+ if(enabled && mEnabled.compareAndSet(false, true))
+ {
+ start();
+ }
+ else if(!enabled && mEnabled.compareAndSet(true, false))
+ {
+ stop();
+ }
}
@Override
- @SuppressWarnings( "incomplete-switch" )
- public void channelChanged( ChannelEvent event )
+ @SuppressWarnings("incomplete-switch")
+ public void channelChanged(ChannelEvent event)
{
- switch( event.getEvent() )
- {
- case NOTIFICATION_SELECTION_CHANGE:
- //ChannelSelectionManager ensures that only 1 channel can be
- //selected and any previously selected channel will be first
- //deselected before we get a new selection event
- if( event.getChannel().isSelected() )
- {
- if( mCurrentChannel != null )
- {
- stop();
- mCurrentChannel = null;
- }
-
- mCurrentChannel = event.getChannel();
-
- if( mEnabled.get() )
- {
- start();
- }
- }
- else
- {
- stop();
- mCurrentChannel = null;
- }
- break;
- case NOTIFICATION_PROCESSING_STOP:
- if( event.getChannel() == mCurrentChannel )
- {
- if( mEnabled.get() )
- {
- stop();
- }
+ switch(event.getEvent())
+ {
+ case NOTIFICATION_SELECTION_CHANGE:
+ //ChannelSelectionManager ensures that only 1 channel can be
+ //selected and any previously selected channel will be first
+ //deselected before we get a new selection event
+ if(event.getChannel().isSelected())
+ {
+ if(mCurrentChannel != null)
+ {
+ stop();
+ mCurrentChannel = null;
+ }
- mCurrentChannel = null;
- }
- break;
- }
- }
-
- private void start()
- {
- if( mEnabled.get() && mCurrentChannel != null && mCurrentChannel.isProcessing() )
- {
- ProcessingChain processingChain = mChannelProcessingManager
- .getProcessingChain( mCurrentChannel );
+ mCurrentChannel = event.getChannel();
- if( processingChain != null )
- {
- processingChain.addRealBufferListener( this );
-
- mDFTProcessor.start();
- }
- }
- }
-
- private void stop()
- {
- if( mCurrentChannel != null && mCurrentChannel.isProcessing() )
- {
- ProcessingChain processingChain = mChannelProcessingManager
- .getProcessingChain( mCurrentChannel );
+ if(mEnabled.get())
+ {
+ start();
+ }
+ }
+ else
+ {
+ stop();
+ mCurrentChannel = null;
+ }
+ break;
+ case NOTIFICATION_PROCESSING_STOP:
+ if(event.getChannel() == mCurrentChannel)
+ {
+ if(mEnabled.get())
+ {
+ stop();
+ }
- if( processingChain != null )
- {
- processingChain.removeRealBufferListener( this );
- }
- }
-
- mDFTProcessor.stop();
-
- mSpectrumPanel.clearSpectrum();
- }
-
- @Override
- public void settingChanged( Setting setting )
- {
- if( mSpectrumPanel != null )
- {
- mSpectrumPanel.settingChanged( setting );
- }
- if( mOverlayPanel != null )
- {
- mOverlayPanel.settingChanged( setting );
- }
+ mCurrentChannel = null;
+ }
+ break;
+ }
}
- @Override
- public void settingDeleted( Setting setting )
+ private void start()
{
- if( mSpectrumPanel != null )
- {
- mSpectrumPanel.settingDeleted( setting );
- }
+ if(mEnabled.get() && mCurrentChannel != null && mCurrentChannel.isProcessing())
+ {
+ ProcessingChain processingChain = mChannelProcessingManager
+ .getProcessingChain(mCurrentChannel);
- if( mOverlayPanel != null )
- {
- mOverlayPanel.settingDeleted( setting );
- }
+ if(processingChain != null)
+ {
+ processingChain.addRealBufferListener(this);
+
+ mDFTProcessor.start();
+ }
+ }
}
- @Override
- public void receive( RealBuffer buffer )
+ private void stop()
{
- RealBuffer decimated = mDecimatingFilter.filter( buffer );
+ if(mCurrentChannel != null && mCurrentChannel.isProcessing())
+ {
+ ProcessingChain processingChain = mChannelProcessingManager
+ .getProcessingChain(mCurrentChannel);
+
+ if(processingChain != null)
+ {
+ processingChain.removeRealBufferListener(this);
+ }
+ }
+
+ mDFTProcessor.stop();
+
+ mSpectrumPanel.clearSpectrum();
+ }
+
+ @Override
+ public void settingChanged(Setting setting)
+ {
+ if(mSpectrumPanel != null)
+ {
+ mSpectrumPanel.settingChanged(setting);
+ }
+ if(mOverlayPanel != null)
+ {
+ mOverlayPanel.settingChanged(setting);
+ }
+ }
+
+ @Override
+ public void settingDeleted(Setting setting)
+ {
+ if(mSpectrumPanel != null)
+ {
+ mSpectrumPanel.settingDeleted(setting);
+ }
+
+ if(mOverlayPanel != null)
+ {
+ mOverlayPanel.settingDeleted(setting);
+ }
+ }
+
+ @Override
+ public void receive(RealBuffer buffer)
+ {
+ RealBuffer decimated = mDecimatingFilter.filter(buffer);
//Hack: we're placing real samples in a complex buffer that the DFT
//processor is expecting.
- ReusableComplexBuffer reusableComplexBuffer = mReusableBufferQueue.getBuffer(decimated.getSamples().length);
+ ReusableComplexBuffer reusableComplexBuffer = mReusableComplexBufferQueue.getBuffer(decimated.getSamples().length);
reusableComplexBuffer.reloadFrom(decimated.getSamples(), System.currentTimeMillis());
- mDFTProcessor.receive(reusableComplexBuffer.incrementUserCount());
+ reusableComplexBuffer.incrementUserCount();
+ mDFTProcessor.receive(reusableComplexBuffer);
}
- /**
- * Monitors the sizing of the layered pane and resizes the spectrum and
- * channel panels whenever the layered pane is resized
- */
- public class ResizeListener implements ComponentListener
- {
- @Override
- public void componentResized( ComponentEvent e )
+ /**
+ * Monitors the sizing of the layered pane and resizes the spectrum and
+ * channel panels whenever the layered pane is resized
+ */
+ public class ResizeListener implements ComponentListener
+ {
+ @Override
+ public void componentResized(ComponentEvent e)
{
- Component c = e.getComponent();
-
- mSpectrumPanel.setBounds( 0, 0, c.getWidth(), c.getHeight() );
- mOverlayPanel.setBounds( 0, 0, c.getWidth(), c.getHeight() );
+ Component c = e.getComponent();
+
+ mSpectrumPanel.setBounds(0, 0, c.getWidth(), c.getHeight());
+ mOverlayPanel.setBounds(0, 0, c.getWidth(), c.getHeight());
}
- @Override
- public void componentHidden( ComponentEvent arg0 ) {}
- @Override
- public void componentMoved( ComponentEvent arg0 ) {}
- @Override
- public void componentShown( ComponentEvent arg0 ) {}
- }
-
- /**
- * Mouse event handler for the channel panel.
- */
- public class MouseEventProcessor implements MouseMotionListener, MouseListener
- {
- @Override
- public void mouseMoved( MouseEvent event )
+ @Override
+ public void componentHidden(ComponentEvent arg0)
{
- update( event );
- }
- @Override
- public void mouseDragged( MouseEvent event )
- {
- update( event );
- }
-
- private void update( MouseEvent event )
- {
- if( event.getComponent() == mOverlayPanel )
- {
- mOverlayPanel.setCursorLocation( event.getPoint() );
- }
- }
-
- @Override
- public void mouseEntered( MouseEvent e )
- {
- if( e.getComponent() == mOverlayPanel )
- {
- mOverlayPanel.setCursorVisible( true );
- }
- }
-
- @Override
- public void mouseExited( MouseEvent e )
- {
- mOverlayPanel.setCursorVisible( false );
- }
-
- /**
- * Displays the context menu.
- */
- @Override
- public void mouseClicked( MouseEvent event )
- {
- if( SwingUtilities.isRightMouseButton( event ) )
- {
- JPopupMenu contextMenu = new JPopupMenu();
-
- /**
- * Color Menus
- */
- JMenu colorMenu = new JMenu( "Color" );
-
- colorMenu.add( new ColorSettingMenuItem( mSettingsManager,
- ColorSettingName.SPECTRUM_CURSOR ) );
-
- colorMenu.add( new ColorSettingMenuItem( mSettingsManager,
- ColorSettingName.SPECTRUM_LINE ) );
-
- colorMenu.add( new ColorSettingMenuItem( mSettingsManager,
- ColorSettingName.SPECTRUM_BACKGROUND ) );
-
- colorMenu.add( new ColorSettingMenuItem( mSettingsManager,
- ColorSettingName.SPECTRUM_GRADIENT_BOTTOM ) );
-
- colorMenu.add( new ColorSettingMenuItem( mSettingsManager,
- ColorSettingName.SPECTRUM_GRADIENT_TOP ) );
-
- contextMenu.add( colorMenu );
-
- /**
- * Display items: fft and frame rate
- */
- JMenu displayMenu = new JMenu( "Display" );
- contextMenu.add( displayMenu );
-
- /**
- * Averaging menu
- */
- JMenu averagingMenu = new JMenu( "Averaging" );
- averagingMenu.add(
- new AveragingItem( ChannelSpectrumPanel.this, 2 ) );
- displayMenu.add( averagingMenu );
-
- /**
- * FFT width
- */
- JMenu fftWidthMenu = new JMenu( "FFT Width" );
- displayMenu.add( fftWidthMenu );
-
- for( DFTSize width: DFTSize.values() )
- {
- fftWidthMenu.add( new DFTSizeItem( mDFTProcessor, width ) );
- }
-
- /**
- * DFT Processor Frame Rate
- */
- JMenu frameRateMenu = new JMenu( "Frame Rate" );
- displayMenu.add( frameRateMenu );
-
- frameRateMenu.add( new FrameRateItem( mDFTProcessor, 14 ) );
- frameRateMenu.add( new FrameRateItem( mDFTProcessor, 16 ) );
- frameRateMenu.add( new FrameRateItem( mDFTProcessor, 18 ) );
- frameRateMenu.add( new FrameRateItem( mDFTProcessor, 20 ) );
- frameRateMenu.add( new FrameRateItem( mDFTProcessor, 25 ) );
- frameRateMenu.add( new FrameRateItem( mDFTProcessor, 30 ) );
- frameRateMenu.add( new FrameRateItem( mDFTProcessor, 40 ) );
- frameRateMenu.add( new FrameRateItem( mDFTProcessor, 50 ) );
-
- /**
- * FFT Window Type
- */
- JMenu fftWindowType = new JMenu( "Window Type" );
- displayMenu.add( fftWindowType );
-
- for( WindowType type: WindowType.values() )
- {
- fftWindowType.add(
- new FFTWindowTypeItem( mDFTProcessor, type ) );
- }
-
- /**
- * Smoothing menu
- */
- JMenu smoothingMenu = new JMenu( "Smoothing" );
-
- if( mSpectrumPanel.getSmoothingType() != SmoothingType.NONE )
- {
- smoothingMenu.add( new SmoothingItem( ChannelSpectrumPanel.this, 5 ) );
- smoothingMenu.add( new JSeparator() );
- }
-
- smoothingMenu.add( new SmoothingTypeItem( ChannelSpectrumPanel.this, SmoothingType.GAUSSIAN ) );
- smoothingMenu.add( new SmoothingTypeItem( ChannelSpectrumPanel.this, SmoothingType.TRIANGLE ) );
- smoothingMenu.add( new SmoothingTypeItem( ChannelSpectrumPanel.this, SmoothingType.RECTANGLE ) );
- smoothingMenu.add( new SmoothingTypeItem( ChannelSpectrumPanel.this, SmoothingType.NONE ) );
-
- displayMenu.add( smoothingMenu );
-
- if( contextMenu != null )
- {
- contextMenu.show( mOverlayPanel,
- event.getX(),
- event.getY() );
- }
- }
}
- @Override
- public void mousePressed( MouseEvent e ) {}
- @Override
- public void mouseReleased( MouseEvent e ) {}
- }
+ @Override
+ public void componentMoved(ComponentEvent arg0)
+ {
+ }
- @Override
+ @Override
+ public void componentShown(ComponentEvent arg0)
+ {
+ }
+ }
+
+ /**
+ * Mouse event handler for the channel panel.
+ */
+ public class MouseEventProcessor implements MouseMotionListener, MouseListener
+ {
+ @Override
+ public void mouseMoved(MouseEvent event)
+ {
+ update(event);
+ }
+
+ @Override
+ public void mouseDragged(MouseEvent event)
+ {
+ update(event);
+ }
+
+ private void update(MouseEvent event)
+ {
+ if(event.getComponent() == mOverlayPanel)
+ {
+ mOverlayPanel.setCursorLocation(event.getPoint());
+ }
+ }
+
+ @Override
+ public void mouseEntered(MouseEvent e)
+ {
+ if(e.getComponent() == mOverlayPanel)
+ {
+ mOverlayPanel.setCursorVisible(true);
+ }
+ }
+
+ @Override
+ public void mouseExited(MouseEvent e)
+ {
+ mOverlayPanel.setCursorVisible(false);
+ }
+
+ /**
+ * Displays the context menu.
+ */
+ @Override
+ public void mouseClicked(MouseEvent event)
+ {
+ if(SwingUtilities.isRightMouseButton(event))
+ {
+ JPopupMenu contextMenu = new JPopupMenu();
+
+ /**
+ * Color Menus
+ */
+ JMenu colorMenu = new JMenu("Color");
+
+ colorMenu.add(new ColorSettingMenuItem(mSettingsManager,
+ ColorSettingName.SPECTRUM_CURSOR));
+
+ colorMenu.add(new ColorSettingMenuItem(mSettingsManager,
+ ColorSettingName.SPECTRUM_LINE));
+
+ colorMenu.add(new ColorSettingMenuItem(mSettingsManager,
+ ColorSettingName.SPECTRUM_BACKGROUND));
+
+ colorMenu.add(new ColorSettingMenuItem(mSettingsManager,
+ ColorSettingName.SPECTRUM_GRADIENT_BOTTOM));
+
+ colorMenu.add(new ColorSettingMenuItem(mSettingsManager,
+ ColorSettingName.SPECTRUM_GRADIENT_TOP));
+
+ contextMenu.add(colorMenu);
+
+ /**
+ * Display items: fft and frame rate
+ */
+ JMenu displayMenu = new JMenu("Display");
+ contextMenu.add(displayMenu);
+
+ /**
+ * Averaging menu
+ */
+ JMenu averagingMenu = new JMenu("Averaging");
+ averagingMenu.add(
+ new AveragingItem(ChannelSpectrumPanel.this, 2));
+ displayMenu.add(averagingMenu);
+
+ /**
+ * FFT width
+ */
+ JMenu fftWidthMenu = new JMenu("FFT Width");
+ displayMenu.add(fftWidthMenu);
+
+ for(DFTSize width : DFTSize.values())
+ {
+ fftWidthMenu.add(new DFTSizeItem(mDFTProcessor, width));
+ }
+
+ /**
+ * DFT Processor Frame Rate
+ */
+ JMenu frameRateMenu = new JMenu("Frame Rate");
+ displayMenu.add(frameRateMenu);
+
+ frameRateMenu.add(new FrameRateItem(mDFTProcessor, 14));
+ frameRateMenu.add(new FrameRateItem(mDFTProcessor, 16));
+ frameRateMenu.add(new FrameRateItem(mDFTProcessor, 18));
+ frameRateMenu.add(new FrameRateItem(mDFTProcessor, 20));
+ frameRateMenu.add(new FrameRateItem(mDFTProcessor, 25));
+ frameRateMenu.add(new FrameRateItem(mDFTProcessor, 30));
+ frameRateMenu.add(new FrameRateItem(mDFTProcessor, 40));
+ frameRateMenu.add(new FrameRateItem(mDFTProcessor, 50));
+
+ /**
+ * FFT Window Type
+ */
+ JMenu fftWindowType = new JMenu("Window Type");
+ displayMenu.add(fftWindowType);
+
+ for(WindowType type : WindowType.values())
+ {
+ fftWindowType.add(
+ new FFTWindowTypeItem(mDFTProcessor, type));
+ }
+
+ /**
+ * Smoothing menu
+ */
+ JMenu smoothingMenu = new JMenu("Smoothing");
+
+ if(mSpectrumPanel.getSmoothingType() != SmoothingType.NONE)
+ {
+ smoothingMenu.add(new SmoothingItem(ChannelSpectrumPanel.this, 5));
+ smoothingMenu.add(new JSeparator());
+ }
+
+ smoothingMenu.add(new SmoothingTypeItem(ChannelSpectrumPanel.this, SmoothingType.GAUSSIAN));
+ smoothingMenu.add(new SmoothingTypeItem(ChannelSpectrumPanel.this, SmoothingType.TRIANGLE));
+ smoothingMenu.add(new SmoothingTypeItem(ChannelSpectrumPanel.this, SmoothingType.RECTANGLE));
+ smoothingMenu.add(new SmoothingTypeItem(ChannelSpectrumPanel.this, SmoothingType.NONE));
+
+ displayMenu.add(smoothingMenu);
+
+ if(contextMenu != null)
+ {
+ contextMenu.show(mOverlayPanel,
+ event.getX(),
+ event.getY());
+ }
+ }
+ }
+
+ @Override
+ public void mousePressed(MouseEvent e)
+ {
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent e)
+ {
+ }
+ }
+
+ @Override
public int getAveraging()
{
- return mSpectrumPanel.getAveraging();
+ return mSpectrumPanel.getAveraging();
}
- @Override
- public void setAveraging( int averaging )
+ @Override
+ public void setAveraging(int averaging)
{
- mSpectrumPanel.setAveraging( averaging );
+ mSpectrumPanel.setAveraging(averaging);
}
- public void setSampleSize( double sampleSize )
- {
- mSpectrumPanel.setSampleSize( sampleSize );
- }
+ public void setSampleSize(double sampleSize)
+ {
+ mSpectrumPanel.setSampleSize(sampleSize);
+ }
- @Override
- public int getSmoothing()
- {
- return mSpectrumPanel.getSmoothing();
- }
+ @Override
+ public int getSmoothing()
+ {
+ return mSpectrumPanel.getSmoothing();
+ }
- @Override
- public void setSmoothing( int smoothing )
- {
- mSpectrumPanel.setSmoothing( smoothing );
- }
+ @Override
+ public void setSmoothing(int smoothing)
+ {
+ mSpectrumPanel.setSmoothing(smoothing);
+ }
- @Override
- public SmoothingType getSmoothingType()
- {
- return mSpectrumPanel.getSmoothingType();
- }
+ @Override
+ public SmoothingType getSmoothingType()
+ {
+ return mSpectrumPanel.getSmoothingType();
+ }
- @Override
- public void setSmoothingType( SmoothingType type )
- {
- mSpectrumPanel.setSmoothingType( type );
- }
+ @Override
+ public void setSmoothingType(SmoothingType type)
+ {
+ mSpectrumPanel.setSmoothingType(type);
+ }
}
diff --git a/src/main/java/io/github/dsheirer/spectrum/DFTProcessor.java b/src/main/java/io/github/dsheirer/spectrum/DFTProcessor.java
index 172a278f..4a281381 100644
--- a/src/main/java/io/github/dsheirer/spectrum/DFTProcessor.java
+++ b/src/main/java/io/github/dsheirer/spectrum/DFTProcessor.java
@@ -20,7 +20,7 @@ import io.github.dsheirer.dsp.filter.Window.WindowType;
import io.github.dsheirer.properties.SystemProperties;
import io.github.dsheirer.sample.Listener;
import io.github.dsheirer.sample.SampleType;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.sample.real.IOverflowListener;
import io.github.dsheirer.source.ISourceEventProcessor;
import io.github.dsheirer.source.SourceEvent;
diff --git a/src/main/java/io/github/dsheirer/spectrum/OverflowableBufferStream.java b/src/main/java/io/github/dsheirer/spectrum/OverflowableBufferStream.java
index 1525d8e4..af6077d2 100644
--- a/src/main/java/io/github/dsheirer/spectrum/OverflowableBufferStream.java
+++ b/src/main/java/io/github/dsheirer/spectrum/OverflowableBufferStream.java
@@ -17,7 +17,7 @@ package io.github.dsheirer.spectrum;
import io.github.dsheirer.sample.OverflowableTransferQueue;
-import io.github.dsheirer.sample.complex.reusable.ReusableComplexBuffer;
+import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -206,6 +206,13 @@ public class OverflowableBufferStream extends OverflowableTransferQueue