mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 16:47:31 -05:00
#1351 Restores semi-accurate timestamps of sample buffers to ensure P25 & DMR decoded messages have accurate timestamps and MBE recording voice frames have accurate timestamps. (#1357)
Co-authored-by: Dennis Sheirer <dsheirer@github.com>
This commit is contained in:
@@ -26,6 +26,12 @@ import io.github.dsheirer.source.tuner.ITunerErrorListener;
|
||||
import io.github.dsheirer.source.tuner.TunerType;
|
||||
import io.github.dsheirer.source.tuner.configuration.TunerConfiguration;
|
||||
import io.github.dsheirer.source.tuner.usb.USBTunerController;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import org.apache.commons.io.EndianUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -33,12 +39,6 @@ import org.usb4java.LibUsb;
|
||||
import org.usb4java.LibUsbException;
|
||||
|
||||
import javax.usb.UsbException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Airspy tuner controller
|
||||
@@ -272,6 +272,7 @@ public class AirspyTunerController extends USBTunerController
|
||||
*/
|
||||
public void setSampleRate(AirspySampleRate rate) throws LibUsbException, UsbException, SourceException
|
||||
{
|
||||
getNativeBufferFactory().setSamplesPerMillisecond((float)rate.getRate() / 1000.0f);
|
||||
if(rate.getRate() != mSampleRate)
|
||||
{
|
||||
int result = readByte(Command.SET_SAMPLE_RATE, 0, rate.getIndex(), true);
|
||||
|
||||
@@ -29,11 +29,10 @@ import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.complex.ComplexSamples;
|
||||
import io.github.dsheirer.source.SourceEvent;
|
||||
import io.github.dsheirer.util.Dispatcher;
|
||||
import java.util.Iterator;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* Complex sample source that provides a frequency-translated and decimated sample buffer stream. Uses a
|
||||
* CIC decimation filter that requires the decimation rate to be an integer multiple. Sample buffer processing
|
||||
@@ -229,7 +228,7 @@ public class HalfBandTunerChannelSource<T extends INativeBuffer> extends TunerCh
|
||||
ComplexSamples basebanded = mFrequencyCorrectionMixer.mix(iterator.next());
|
||||
float[] i = mIDecimationFilter.decimateReal(basebanded.i());
|
||||
float[] q = mQDecimationFilter.decimateReal(basebanded.q());
|
||||
mStreamHeartbeatProcessor.receive(new ComplexSamples(i, q));
|
||||
mStreamHeartbeatProcessor.receive(new ComplexSamples(i, q, basebanded.timestamp()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,10 @@ import io.github.dsheirer.source.tuner.ITunerErrorListener;
|
||||
import io.github.dsheirer.source.tuner.TunerType;
|
||||
import io.github.dsheirer.source.tuner.configuration.TunerConfiguration;
|
||||
import io.github.dsheirer.source.tuner.usb.USBTunerController;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import org.apache.commons.io.EndianUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -32,10 +36,6 @@ import org.usb4java.LibUsb;
|
||||
import org.usb4java.LibUsbException;
|
||||
|
||||
import javax.usb.UsbException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
|
||||
public class HackRFTunerController extends USBTunerController
|
||||
{
|
||||
@@ -404,6 +404,7 @@ public class HackRFTunerController extends USBTunerController
|
||||
mFrequencyController.setSampleRate(rate.getRate());
|
||||
setBasebandFilter(rate.getFilter());
|
||||
mSampleRate = rate;
|
||||
getNativeBufferFactory().setSamplesPerMillisecond((float)getSampleRate() / 1000.0f);
|
||||
}
|
||||
|
||||
public void setSampleRateManual(int frequency, int divider) throws UsbException
|
||||
|
||||
@@ -27,6 +27,12 @@ import io.github.dsheirer.source.tuner.TunerFactory;
|
||||
import io.github.dsheirer.source.tuner.TunerType;
|
||||
import io.github.dsheirer.source.tuner.configuration.TunerConfiguration;
|
||||
import io.github.dsheirer.source.tuner.usb.USBTunerController;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.usb4java.DeviceHandle;
|
||||
@@ -35,12 +41,6 @@ import org.usb4java.LibUsbException;
|
||||
|
||||
import javax.usb.UsbDisconnectedException;
|
||||
import javax.usb.UsbException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
/**
|
||||
* RTL-2832 tuner controller implementation.
|
||||
@@ -953,6 +953,9 @@ public class RTL2832TunerController extends USBTunerController
|
||||
setSampleRateFilters(sampleRate.getRate());
|
||||
mSampleRate = sampleRate;
|
||||
mFrequencyController.setSampleRate(sampleRate.getRate());
|
||||
|
||||
//Updates native buffer factory so that sample buffers can be accurately timestamped
|
||||
getNativeBufferFactory().setSamplesPerMillisecond(sampleRate.getRate() / 1000.0f);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -25,13 +25,12 @@ import io.github.dsheirer.dsp.oscillator.OscillatorFactory;
|
||||
import io.github.dsheirer.sample.Broadcaster;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.util.ThreadPool;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class SampleGenerator
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(SampleGenerator.class);
|
||||
@@ -189,7 +188,7 @@ public class SampleGenerator
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
FloatNativeBuffer buffer = new FloatNativeBuffer(samples, now);
|
||||
FloatNativeBuffer buffer = new FloatNativeBuffer(samples, now, 0.0f);
|
||||
|
||||
mNativeBufferBroadcaster.broadcast(buffer);
|
||||
|
||||
|
||||
@@ -28,6 +28,11 @@ import io.github.dsheirer.source.IFrameLocationListener;
|
||||
import io.github.dsheirer.source.Source;
|
||||
import io.github.dsheirer.source.SourceEvent;
|
||||
import io.github.dsheirer.util.ThreadPool;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -36,11 +41,6 @@ import javax.sound.sampled.AudioFormat;
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
import javax.sound.sampled.AudioSystem;
|
||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class ComplexWaveSource extends Source implements IControllableFileSource, AutoCloseable
|
||||
{
|
||||
@@ -276,7 +276,8 @@ public class ComplexWaveSource extends Source implements IControllableFileSource
|
||||
}
|
||||
|
||||
float[] samples = ConversionUtils.convertFromSigned16BitSamples(buffer);
|
||||
mListener.receive(new FloatNativeBuffer(samples, System.currentTimeMillis()));
|
||||
mListener.receive(new FloatNativeBuffer(samples, System.currentTimeMillis(),
|
||||
mInputStream.getFormat().getSampleRate() / 1000.0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user