#39 WIP - adds support for timestamped complex buffers so that decoded

messages and events can be accurately timestamped, and more importantly,
allocated traffic channels can request to be pre-loaded with buffered
samples to ensure that traffic channels don't miss any samples that
are currently missed due processing latency inherent in current buffer
sizing.  This should reduce the clipping of starting messages or voice
on the traffic channels.

Restructures processing path for tuner frequency and sample rate change
events.  The tuner now embeds these events in the sequence of buffers
that are generated immediately after the event occurs since those are
the buffers that will be impacted by the change.  Previously, the change
event would be broadcast throughout the system and would impact any
buffered/cached buffers.  This also reduces the number of source event
change listeners that have to be managed.  Note: this change is not yet
implemented in all tuners ... only in the TestTuner implementation.

Updates the polyphase channelizer to now buffer channel results and then
dispatch the buffer to the channel output processors to improve efficiency
of using float arrays versus single value complex float processing.
This commit is contained in:
Denny
2018-01-13 09:10:57 -05:00
parent d2e7f008c8
commit 05fa5c25fd
25 changed files with 962 additions and 277 deletions

View File

@@ -21,10 +21,14 @@ package io.github.dsheirer.source.tuner.test;
import io.github.dsheirer.dsp.mixer.LowPhaseNoiseOscillator;
import io.github.dsheirer.sample.Listener;
import io.github.dsheirer.sample.complex.ComplexBuffer;
import io.github.dsheirer.sample.complex.TimestampedComplexBuffer;
import io.github.dsheirer.source.SourceEvent;
import io.github.dsheirer.util.ThreadPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
@@ -38,6 +42,7 @@ public class SampleGenerator
private long mInterval;
private int mSamplesPerInterval;
private ScheduledFuture<?> mScheduledFuture;
private Queue<SourceEvent> mSourceEventQueue = new ConcurrentLinkedQueue();
/**
* Generates complex sample buffers at the specified sample rate with a unity gain tone at the specified
@@ -79,6 +84,16 @@ public class SampleGenerator
this(sampleRate, frequency, interval, 0);
}
/**
* Queues the source event for inclusion in the complex buffers generated by this sample generator. Source events
* are queued FIFO and embedded one at a time in the subsequent buffers produced by this generator.
* @param sourceEvent to queue
*/
public void queue(SourceEvent sourceEvent)
{
mSourceEventQueue.offer(sourceEvent);
}
/**
* Updates the number of complex samples generated per interval
*/
@@ -170,7 +185,7 @@ public class SampleGenerator
if(mListener != null)
{
float[] samples = mOscillator.generate(mSamplesPerInterval);
mListener.receive(new ComplexBuffer(samples));
mListener.receive(new TimestampedComplexBuffer(samples, mSourceEventQueue.poll()));
if(mSweepUpdateInterval != 0)
{

View File

@@ -47,7 +47,7 @@ public class TestTuner extends Tuner
*/
public TestTunerController getTunerController()
{
return (TestTunerController)getTunerController();
return (TestTunerController)super.getTunerController();
}
@Override

View File

@@ -20,6 +20,7 @@ package io.github.dsheirer.source.tuner.test;
import io.github.dsheirer.sample.Listener;
import io.github.dsheirer.sample.complex.ComplexBuffer;
import io.github.dsheirer.source.SourceEvent;
import io.github.dsheirer.source.SourceException;
import io.github.dsheirer.source.tuner.TunerController;
import io.github.dsheirer.source.tuner.configuration.TunerConfiguration;
@@ -33,9 +34,9 @@ public class TestTunerController extends TunerController
public static final long MINIMUM_FREQUENCY = 1000000l; //1 MHz
public static final long MAXIMUM_FREQUENCY = 10000000000l; //10 GHz
public static final long DEFAULT_CENTER_FREQUENCY = 100000000; //100 MHz
public static final int DEFAULT_SAMPLE_RATE = 50000; //25 kHz
public static final int DC_NOISE_BANDWIDTH = 5000; // +/-5 kHz
public static final double USABLE_BANDWIDTH = 0.90; //90% usable bandwidth - 5% unusable on either end
public static final int DEFAULT_SAMPLE_RATE = 100000; //25 kHz
public static final int DC_NOISE_BANDWIDTH = 0; // +/-5 kHz
public static final double USABLE_BANDWIDTH = 1.00; //100% usable bandwidth
public static final int SPECTRAL_FRAME_RATE = 20;
public static final long SAMPLE_GENERATION_INTERVAL = 1000 / SPECTRAL_FRAME_RATE;
@@ -129,6 +130,7 @@ public class TestTunerController extends TunerController
{
long frequency = toneFrequency - mReferenceFrequency;
mSampleGenerator.setFrequency(frequency);
mSampleGenerator.queue(SourceEvent.frequencyChange(frequency));
}
/**
@@ -155,5 +157,6 @@ public class TestTunerController extends TunerController
public void setSampleRate(int sampleRate) throws SourceException
{
mFrequencyController.setSampleRate(sampleRate);
mSampleGenerator.queue(SourceEvent.sampleRateChange(sampleRate));
}
}