mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-14 09:37:36 -05:00
[WIP] Testing completed for channel manager allocating tuner channels
when the tuner controller indicates that there is a center DC spike blocked region or when the tuner has clipped outer spectral regions resulting in less than 100% usable bandwidth.
This commit is contained in:
@@ -82,7 +82,8 @@ public class ChannelizerViewer extends JFrame
|
|||||||
{
|
{
|
||||||
mTestTuner = new TestTuner();
|
mTestTuner = new TestTuner();
|
||||||
|
|
||||||
mChannelCount = (int)(mTestTuner.getTunerController().getUsableBandwidth() / CHANNEL_BANDWIDTH);
|
// mChannelCount = (int)(mTestTuner.getTunerController().getUsableBandwidth() / CHANNEL_BANDWIDTH);
|
||||||
|
mChannelCount = (int)(mTestTuner.getTunerController().getBandwidth() / CHANNEL_BANDWIDTH);
|
||||||
mChannelsPerRow = channelsPerRow;
|
mChannelsPerRow = channelsPerRow;
|
||||||
|
|
||||||
init();
|
init();
|
||||||
@@ -221,7 +222,7 @@ public class ChannelizerViewer extends JFrame
|
|||||||
{
|
{
|
||||||
long frequency = baseFrequency + (x * CHANNEL_BANDWIDTH);
|
long frequency = baseFrequency + (x * CHANNEL_BANDWIDTH);
|
||||||
|
|
||||||
mLog.debug("Channel " + x + " Frequency: " + frequency);
|
mLog.debug("Channel " + x + "/" + mChannelCount + " Frequency: " + frequency);
|
||||||
|
|
||||||
ChannelPanel channelPanel = new ChannelPanel(mSettingsManager, CHANNEL_BANDWIDTH * 2, frequency, CHANNEL_BANDWIDTH, (x == channelToLog));
|
ChannelPanel channelPanel = new ChannelPanel(mSettingsManager, CHANNEL_BANDWIDTH * 2, frequency, CHANNEL_BANDWIDTH, (x == channelToLog));
|
||||||
channelPanel.setDFTSize(mChannelPanelDFTSize);
|
channelPanel.setDFTSize(mChannelPanelDFTSize);
|
||||||
@@ -352,18 +353,6 @@ public class ChannelizerViewer extends JFrame
|
|||||||
mSpectrumPanel = new SpectrumPanel(settingsManager);
|
mSpectrumPanel = new SpectrumPanel(settingsManager);
|
||||||
mSpectrumPanel.setSampleSize(16);
|
mSpectrumPanel.setSampleSize(16);
|
||||||
add(mSpectrumPanel, "span");
|
add(mSpectrumPanel, "span");
|
||||||
add(new JLabel("Center:" + frequency));
|
|
||||||
|
|
||||||
mLoggingButton = new JToggleButton("Logging");
|
|
||||||
mLoggingButton.addActionListener(new ActionListener()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e)
|
|
||||||
{
|
|
||||||
mLoggingEnabled = mLoggingButton.isSelected();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// add(mLoggingButton);
|
|
||||||
|
|
||||||
mDFTProcessor.addConverter(mComplexDecibelConverter);
|
mDFTProcessor.addConverter(mComplexDecibelConverter);
|
||||||
mDFTProcessor.process(SourceEvent.sampleRateChange(sampleRate));
|
mDFTProcessor.process(SourceEvent.sampleRateChange(sampleRate));
|
||||||
@@ -395,6 +384,27 @@ public class ChannelizerViewer extends JFrame
|
|||||||
{
|
{
|
||||||
mLog.error("Couldn't get a source from the tuner for frequency: " + frequency);
|
mLog.error("Couldn't get a source from the tuner for frequency: " + frequency);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(mSource != null)
|
||||||
|
{
|
||||||
|
add(new JLabel("Center:" + frequency));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
add(new JLabel("NO SRC:" + frequency));
|
||||||
|
}
|
||||||
|
|
||||||
|
mLoggingButton = new JToggleButton("Logging");
|
||||||
|
mLoggingButton.addActionListener(new ActionListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
mLoggingEnabled = mLoggingButton.isSelected();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// add(mLoggingButton);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TunerChannelSource getSource()
|
public TunerChannelSource getSource()
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
package io.github.dsheirer.sample.complex;
|
|
||||||
|
|
||||||
import io.github.dsheirer.sample.Listener;
|
|
||||||
|
|
||||||
public interface IComplexBufferListener
|
|
||||||
{
|
|
||||||
public Listener<ComplexBuffer> getComplexBufferListener();
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* sdrtrunk
|
|
||||||
* Copyright (C) 2014-2017 Dennis Sheirer
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
package io.github.dsheirer.sample.complex;
|
|
||||||
|
|
||||||
import io.github.dsheirer.sample.Listener;
|
|
||||||
|
|
||||||
public interface IComplexBufferProvider
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Adds the listener to receive complex buffer samples
|
|
||||||
*/
|
|
||||||
void addComplexBufferListener(Listener<ComplexBuffer> listener);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes the listener from receiving complex buffer samples
|
|
||||||
*/
|
|
||||||
void removeComplexBufferListener(Listener<ComplexBuffer> listener);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates if there are any complex buffer listeners registered
|
|
||||||
*/
|
|
||||||
boolean hasComplexBufferListeners();
|
|
||||||
}
|
|
||||||
@@ -1,132 +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 <http://www.gnu.org/licenses/>
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
package io.github.dsheirer.sample.complex;
|
|
||||||
|
|
||||||
import io.github.dsheirer.dsp.filter.channelizer.SampleTimestampManager;
|
|
||||||
import io.github.dsheirer.sample.Listener;
|
|
||||||
import org.apache.commons.lang3.Validate;
|
|
||||||
|
|
||||||
import java.nio.FloatBuffer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assembles complex float samples into a ComplexBuffer containing an array of floats. Monitors incoming sample count
|
|
||||||
* to accurately assign a relative timestamp to each assembled buffer.
|
|
||||||
*/
|
|
||||||
public class TimestampedBufferAssembler
|
|
||||||
{
|
|
||||||
private SampleTimestampManager mTimestampManager;
|
|
||||||
private FloatBuffer mBuffer;
|
|
||||||
private long mCurrentBufferTimestamp;
|
|
||||||
private Listener<ComplexBuffer> mListener;
|
|
||||||
|
|
||||||
public TimestampedBufferAssembler(int bufferSize, double sampleRate)
|
|
||||||
{
|
|
||||||
Validate.isTrue(bufferSize % 2 == 0);
|
|
||||||
mBuffer = FloatBuffer.allocate(bufferSize);
|
|
||||||
mTimestampManager = new SampleTimestampManager(sampleRate);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the reference timestamp to use for all subsequent samples that are assembled. This timestamp should
|
|
||||||
* identify the relative timestamp of the first/next sample that is received by this assembler.
|
|
||||||
* @param timestamp to use relative to the incoming sample arrays.
|
|
||||||
*/
|
|
||||||
public void updateTimestamp(long timestamp)
|
|
||||||
{
|
|
||||||
mTimestampManager.setReferenceTimestamp(timestamp);
|
|
||||||
|
|
||||||
if(mBuffer.position() == 0)
|
|
||||||
{
|
|
||||||
mCurrentBufferTimestamp = timestamp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void dispose()
|
|
||||||
{
|
|
||||||
mListener = null;
|
|
||||||
mBuffer = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds the samples to this assembler. As each buffer is assembled, it will be dispatched to the registered
|
|
||||||
* listener.
|
|
||||||
*
|
|
||||||
* @param samples to assemble
|
|
||||||
*/
|
|
||||||
public void receive(float[] samples)
|
|
||||||
{
|
|
||||||
if(mBuffer.remaining() >= samples.length)
|
|
||||||
{
|
|
||||||
mBuffer.put(samples);
|
|
||||||
mTimestampManager.increment(samples.length / 2);
|
|
||||||
|
|
||||||
if(!mBuffer.hasRemaining())
|
|
||||||
{
|
|
||||||
flush();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int offset = 0;
|
|
||||||
|
|
||||||
while(offset < samples.length)
|
|
||||||
{
|
|
||||||
int toCopy = mBuffer.remaining();
|
|
||||||
|
|
||||||
if((samples.length - offset) < toCopy)
|
|
||||||
{
|
|
||||||
toCopy = samples.length - offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
mBuffer.put(samples, offset, toCopy);
|
|
||||||
|
|
||||||
offset += toCopy;
|
|
||||||
mTimestampManager.increment(toCopy / 2);
|
|
||||||
|
|
||||||
if(!mBuffer.hasRemaining())
|
|
||||||
{
|
|
||||||
flush();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flushes the current buffer contents to the registered listener
|
|
||||||
*/
|
|
||||||
public void flush()
|
|
||||||
{
|
|
||||||
if(mListener != null && mBuffer.position() > 0)
|
|
||||||
{
|
|
||||||
float[] samples = new float[mBuffer.position()];
|
|
||||||
mBuffer.rewind();
|
|
||||||
mBuffer.get(samples);
|
|
||||||
|
|
||||||
mListener.receive(new TimestampedComplexBuffer(samples, mCurrentBufferTimestamp));
|
|
||||||
}
|
|
||||||
|
|
||||||
mBuffer.rewind();
|
|
||||||
mCurrentBufferTimestamp = mTimestampManager.getCurrentTimestamp();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the listener to receive the output from this buffer assembler.
|
|
||||||
*/
|
|
||||||
public void setListener(Listener<ComplexBuffer> listener)
|
|
||||||
{
|
|
||||||
mListener = listener;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,63 +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 <http://www.gnu.org/licenses/>
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
package io.github.dsheirer.sample.complex;
|
|
||||||
|
|
||||||
public class TimestampedComplexBuffer extends ComplexBuffer
|
|
||||||
{
|
|
||||||
private long mTimestamp;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a timestamped complex buffer using the specified time in milliseconds.
|
|
||||||
*
|
|
||||||
* @param samples of data
|
|
||||||
*/
|
|
||||||
public TimestampedComplexBuffer(float[] samples, long timestamp)
|
|
||||||
{
|
|
||||||
super(samples);
|
|
||||||
|
|
||||||
mTimestamp = timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a timestamped complex buffer using the current system time in milliseconds.
|
|
||||||
*
|
|
||||||
* @param samples of data
|
|
||||||
*/
|
|
||||||
public TimestampedComplexBuffer(float[] samples)
|
|
||||||
{
|
|
||||||
this(samples, System.currentTimeMillis());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reference timestamp for this complex buffer. Timestamp is relative to the first sample in the buffer.
|
|
||||||
* @return timestamp as milliseconds since epoch
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public long getTimestamp()
|
|
||||||
{
|
|
||||||
return mTimestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates that this complex buffer has a reference timestamp
|
|
||||||
* @return true
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean hasTimestamp()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -412,8 +412,8 @@ public class TunerChannelSourceManager extends ChannelSourceManager
|
|||||||
catch(IllegalArgumentException iae)
|
catch(IllegalArgumentException iae)
|
||||||
{
|
{
|
||||||
//Center frequency calculation failed
|
//Center frequency calculation failed
|
||||||
mLog.error("Couldn't calculate new tuner center frequency for new tuner channel [" +
|
mLog.debug("Couldn't calculate new tuner center frequency for new tuner channel [" +
|
||||||
tunerChannel + "] unable to allocate new tuner channel", iae);
|
tunerChannel + "] unable to allocate new tuner channel");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,9 +32,9 @@ public class TestTunerController extends TunerController
|
|||||||
|
|
||||||
public static final long MINIMUM_FREQUENCY = 1l;
|
public static final long MINIMUM_FREQUENCY = 1l;
|
||||||
public static final long MAXIMUM_FREQUENCY = 1000000000l;
|
public static final long MAXIMUM_FREQUENCY = 1000000000l;
|
||||||
public static final int SAMPLE_RATE = 800000;
|
public static final int SAMPLE_RATE = 100000;
|
||||||
public static final int DC_NOISE_BANDWIDTH = 0;
|
public static final int DC_NOISE_BANDWIDTH = 5000;
|
||||||
public static final double USABLE_BANDWIDTH_PERCENTAGE = 1.00;
|
public static final double USABLE_BANDWIDTH_PERCENTAGE = .90;
|
||||||
|
|
||||||
public static final int SPECTRAL_FRAME_RATE = 20;
|
public static final int SPECTRAL_FRAME_RATE = 20;
|
||||||
public static final long SAMPLE_GENERATION_INTERVAL = 1000 / SPECTRAL_FRAME_RATE;
|
public static final long SAMPLE_GENERATION_INTERVAL = 1000 / SPECTRAL_FRAME_RATE;
|
||||||
|
|||||||
Reference in New Issue
Block a user