mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-13 00:57:31 -05:00
[WIP] channelizer and 1/2 channel output processors along with the 2
channel synthesizer ... all appear to be functional.
This commit is contained in:
@@ -740,7 +740,7 @@ public class FilterFactory
|
|||||||
public static float[] getSincM2Channelizer(double channelBandwidth, int channels, int tapsPerChannel,
|
public static float[] getSincM2Channelizer(double channelBandwidth, int channels, int tapsPerChannel,
|
||||||
Window.WindowType windowType, boolean logResults) throws FilterDesignException
|
Window.WindowType windowType, boolean logResults) throws FilterDesignException
|
||||||
{
|
{
|
||||||
return getSincFilter(channelBandwidth * channels * 2.0, channelBandwidth,
|
return getSincFilter(channelBandwidth * channels, channelBandwidth,
|
||||||
channels, tapsPerChannel, windowType,logResults);
|
channels, tapsPerChannel, windowType,logResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ public class ChannelizerViewer extends JFrame
|
|||||||
private void init()
|
private void init()
|
||||||
{
|
{
|
||||||
setTitle("Polyphase Channelizer Viewer");
|
setTitle("Polyphase Channelizer Viewer");
|
||||||
setSize(1000, 800);
|
setSize(1200, 800);
|
||||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
setLayout(new MigLayout("insets 0 0 0 0", "[grow,fill]", "[grow,fill]"));
|
setLayout(new MigLayout("insets 0 0 0 0", "[grow,fill]", "[grow,fill]"));
|
||||||
setLocationRelativeTo(null);
|
setLocationRelativeTo(null);
|
||||||
@@ -119,7 +119,7 @@ public class ChannelizerViewer extends JFrame
|
|||||||
{
|
{
|
||||||
mPrimarySpectrumPanel = new PrimarySpectrumPanel(mSettingsManager,
|
mPrimarySpectrumPanel = new PrimarySpectrumPanel(mSettingsManager,
|
||||||
mTestTuner.getTunerController().getSampleRate());
|
mTestTuner.getTunerController().getSampleRate());
|
||||||
mPrimarySpectrumPanel.setPreferredSize(new Dimension(1000, 200));
|
mPrimarySpectrumPanel.setPreferredSize(new Dimension(1200, 200));
|
||||||
mPrimarySpectrumPanel.setDFTSize(mMainPanelDFTSize);
|
mPrimarySpectrumPanel.setDFTSize(mMainPanelDFTSize);
|
||||||
mTestTuner.getTunerController().addComplexBufferListener(mPrimarySpectrumPanel);
|
mTestTuner.getTunerController().addComplexBufferListener(mPrimarySpectrumPanel);
|
||||||
}
|
}
|
||||||
@@ -135,8 +135,8 @@ public class ChannelizerViewer extends JFrame
|
|||||||
mControlPanel.setLayout(new MigLayout("insets 0 0 0 0", "", ""));
|
mControlPanel.setLayout(new MigLayout("insets 0 0 0 0", "", ""));
|
||||||
|
|
||||||
mControlPanel.add(new JLabel("Tone:"), "align left");
|
mControlPanel.add(new JLabel("Tone:"), "align left");
|
||||||
long minimumFrequency = -(long)mTestTuner.getTunerController().getSampleRate() / 2;
|
long minimumFrequency = -(long)mTestTuner.getTunerController().getSampleRate() / 2 + 1;
|
||||||
long maximumFrequency = (long)mTestTuner.getTunerController().getSampleRate() / 2;
|
long maximumFrequency = (long)mTestTuner.getTunerController().getSampleRate() / 2 - 1;
|
||||||
long toneFrequency = 0;
|
long toneFrequency = 0;
|
||||||
|
|
||||||
SpinnerNumberModel model = new SpinnerNumberModel(toneFrequency, minimumFrequency, maximumFrequency,
|
SpinnerNumberModel model = new SpinnerNumberModel(toneFrequency, minimumFrequency, maximumFrequency,
|
||||||
@@ -310,7 +310,7 @@ public class ChannelizerViewer extends JFrame
|
|||||||
{
|
{
|
||||||
setLayout(new MigLayout("insets 0 0 0 0", "[grow,fill]", "[grow,fill]"));
|
setLayout(new MigLayout("insets 0 0 0 0", "[grow,fill]", "[grow,fill]"));
|
||||||
mSpectrumPanel = new SpectrumPanel(settingsManager);
|
mSpectrumPanel = new SpectrumPanel(settingsManager);
|
||||||
mSpectrumPanel.setSampleSize(26);
|
mSpectrumPanel.setSampleSize(16);
|
||||||
add(mSpectrumPanel);
|
add(mSpectrumPanel);
|
||||||
|
|
||||||
mDFTProcessor.addConverter(mComplexDecibelConverter);
|
mDFTProcessor.addConverter(mComplexDecibelConverter);
|
||||||
@@ -349,7 +349,7 @@ public class ChannelizerViewer extends JFrame
|
|||||||
{
|
{
|
||||||
setLayout(new MigLayout("insets 0 0 0 0", "[center,grow,fill][]", "[grow,fill][]"));
|
setLayout(new MigLayout("insets 0 0 0 0", "[center,grow,fill][]", "[grow,fill][]"));
|
||||||
mSpectrumPanel = new SpectrumPanel(settingsManager);
|
mSpectrumPanel = new SpectrumPanel(settingsManager);
|
||||||
mSpectrumPanel.setSampleSize(22);
|
mSpectrumPanel.setSampleSize(16);
|
||||||
add(mSpectrumPanel, "span");
|
add(mSpectrumPanel, "span");
|
||||||
add(new JLabel("Center:" + frequency));
|
add(new JLabel("Center:" + frequency));
|
||||||
|
|
||||||
@@ -362,7 +362,7 @@ public class ChannelizerViewer extends JFrame
|
|||||||
mLoggingEnabled = mLoggingButton.isSelected();
|
mLoggingEnabled = mLoggingButton.isSelected();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
add(mLoggingButton);
|
// add(mLoggingButton);
|
||||||
|
|
||||||
mDFTProcessor.addConverter(mComplexDecibelConverter);
|
mDFTProcessor.addConverter(mComplexDecibelConverter);
|
||||||
mDFTProcessor.process(SourceEvent.sampleRateChange(sampleRate));
|
mDFTProcessor.process(SourceEvent.sampleRateChange(sampleRate));
|
||||||
@@ -433,7 +433,7 @@ public class ChannelizerViewer extends JFrame
|
|||||||
mSource = source;
|
mSource = source;
|
||||||
setLayout(new MigLayout("insets 0 0 0 0", "[center,grow,fill][]", "[grow,fill][]"));
|
setLayout(new MigLayout("insets 0 0 0 0", "[center,grow,fill][]", "[grow,fill][]"));
|
||||||
mSpectrumPanel = new SpectrumPanel(settingsManager);
|
mSpectrumPanel = new SpectrumPanel(settingsManager);
|
||||||
mSpectrumPanel.setSampleSize(28);
|
mSpectrumPanel.setSampleSize(16);
|
||||||
add(mSpectrumPanel, "span");
|
add(mSpectrumPanel, "span");
|
||||||
add(new JLabel("Index:" + index));
|
add(new JLabel("Index:" + index));
|
||||||
|
|
||||||
@@ -446,7 +446,7 @@ public class ChannelizerViewer extends JFrame
|
|||||||
mLoggingEnabled = mLoggingButton.isSelected();
|
mLoggingEnabled = mLoggingButton.isSelected();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
add(mLoggingButton);
|
// add(mLoggingButton);
|
||||||
|
|
||||||
mDFTProcessor.addConverter(mComplexDecibelConverter);
|
mDFTProcessor.addConverter(mComplexDecibelConverter);
|
||||||
mDFTProcessor.process(SourceEvent.sampleRateChange(25000.0));
|
mDFTProcessor.process(SourceEvent.sampleRateChange(25000.0));
|
||||||
@@ -507,7 +507,7 @@ public class ChannelizerViewer extends JFrame
|
|||||||
|
|
||||||
if(useGUI)
|
if(useGUI)
|
||||||
{
|
{
|
||||||
int channelsPerRow = 8;
|
int channelsPerRow = 16;
|
||||||
|
|
||||||
final ChannelizerViewer frame = new ChannelizerViewer(channelsPerRow);
|
final ChannelizerViewer frame = new ChannelizerViewer(channelsPerRow);
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ public class PolyphaseChannelManager implements ISourceEventProcessor
|
|||||||
private final static Logger mLog = LoggerFactory.getLogger(PolyphaseChannelManager.class);
|
private final static Logger mLog = LoggerFactory.getLogger(PolyphaseChannelManager.class);
|
||||||
private static final double MINIMUM_CHANNEL_BANDWIDTH = 12500.0;
|
private static final double MINIMUM_CHANNEL_BANDWIDTH = 12500.0;
|
||||||
private static final double CHANNEL_OVERSAMPLING = 2.0;
|
private static final double CHANNEL_OVERSAMPLING = 2.0;
|
||||||
private static final int POLYPHASE_FILTER_TAPS_PER_CHANNEL = 19;
|
private static final int POLYPHASE_FILTER_TAPS_PER_CHANNEL = 17;
|
||||||
|
|
||||||
private Broadcaster<SourceEvent> mSourceEventBroadcaster = new Broadcaster<>();
|
private Broadcaster<SourceEvent> mSourceEventBroadcaster = new Broadcaster<>();
|
||||||
private IComplexBufferProvider mComplexBufferProvider;
|
private IComplexBufferProvider mComplexBufferProvider;
|
||||||
|
|||||||
@@ -15,10 +15,8 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package io.github.dsheirer.dsp.filter.channelizer.output;
|
package io.github.dsheirer.dsp.filter.channelizer.output;
|
||||||
|
|
||||||
import io.github.dsheirer.dsp.filter.Filters;
|
|
||||||
import io.github.dsheirer.dsp.filter.channelizer.PolyphaseChannelResultsBuffer;
|
import io.github.dsheirer.dsp.filter.channelizer.PolyphaseChannelResultsBuffer;
|
||||||
import io.github.dsheirer.dsp.filter.channelizer.TwoChannelSynthesizerM2;
|
import io.github.dsheirer.dsp.filter.channelizer.TwoChannelSynthesizerM2;
|
||||||
import io.github.dsheirer.dsp.filter.fir.complex.ComplexFIRFilter;
|
|
||||||
import io.github.dsheirer.dsp.mixer.FS4DownConverter;
|
import io.github.dsheirer.dsp.mixer.FS4DownConverter;
|
||||||
import io.github.dsheirer.sample.complex.TimestampedBufferAssembler;
|
import io.github.dsheirer.sample.complex.TimestampedBufferAssembler;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -28,8 +26,6 @@ import java.util.List;
|
|||||||
|
|
||||||
public class TwoChannelOutputProcessor extends ChannelOutputProcessor
|
public class TwoChannelOutputProcessor extends ChannelOutputProcessor
|
||||||
{
|
{
|
||||||
private ComplexFIRFilter mLowPassFilter =
|
|
||||||
new ComplexFIRFilter(Filters.HALF_BAND_FILTER_47T.getCoefficients(), 1.0f);
|
|
||||||
private TwoChannelSynthesizerM2 mSynthesizer;
|
private TwoChannelSynthesizerM2 mSynthesizer;
|
||||||
private FS4DownConverter mFS4DownConverter = new FS4DownConverter();
|
private FS4DownConverter mFS4DownConverter = new FS4DownConverter();
|
||||||
|
|
||||||
@@ -113,13 +109,9 @@ public class TwoChannelOutputProcessor extends ChannelOutputProcessor
|
|||||||
//The synthesized channels are centered at +FS/4 ... downconvert to center the spectrum
|
//The synthesized channels are centered at +FS/4 ... downconvert to center the spectrum
|
||||||
mFS4DownConverter.mixComplex(synthesized);
|
mFS4DownConverter.mixComplex(synthesized);
|
||||||
|
|
||||||
//Apply frequency correction to center the signal of interest within the synthesized channel
|
//Apply offset and frequency correction to center the signal of interest within the synthesized channel
|
||||||
// getFrequencyCorrectionMixer().mixComplex(synthesized);
|
getFrequencyCorrectionMixer().mixComplex(synthesized);
|
||||||
|
|
||||||
//Apply low-pass filtering to attenuate neighboring channel(s)
|
|
||||||
// synthesized = mLowPassFilter.filter(synthesized);
|
|
||||||
|
|
||||||
//Send it on its merry way ...
|
|
||||||
timestampedBufferAssembler.receive(synthesized);
|
timestampedBufferAssembler.receive(synthesized);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ public class LowPhaseNoiseOscillator extends AbstractOscillator
|
|||||||
private double mCosineAngle;
|
private double mCosineAngle;
|
||||||
private double mSineAngle;
|
private double mSineAngle;
|
||||||
private double mGain = 1.0;
|
private double mGain = 1.0;
|
||||||
private boolean mReset;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ultra-low phase noise complex oscillator as described in Digital Signal Processing 3e, Lyons, p.786
|
* Ultra-low phase noise complex oscillator as described in Digital Signal Processing 3e, Lyons, p.786
|
||||||
@@ -46,19 +45,6 @@ public class LowPhaseNoiseOscillator extends AbstractOscillator
|
|||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the frequency of the tone generated by this oscillator.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void setFrequency(double frequency)
|
|
||||||
{
|
|
||||||
//This oscillator does not recover when the current frequency is equal to exactly half the sample rate, so we
|
|
||||||
//have to set a flag to reset the I/Q structures when changing the frequency from exactly half the sample rate.
|
|
||||||
mReset = getFrequency() < 0.01 || Math.abs(getFrequency()) - (getSampleRate() / 2) < 1.0;
|
|
||||||
|
|
||||||
super.setFrequency(frequency);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float quadrature()
|
public float quadrature()
|
||||||
{
|
{
|
||||||
@@ -80,15 +66,6 @@ public class LowPhaseNoiseOscillator extends AbstractOscillator
|
|||||||
|
|
||||||
mCosineAngle = Math.cos(anglePerSample);
|
mCosineAngle = Math.cos(anglePerSample);
|
||||||
mSineAngle = Math.sin(anglePerSample);
|
mSineAngle = Math.sin(anglePerSample);
|
||||||
|
|
||||||
if(mReset)
|
|
||||||
{
|
|
||||||
mInphase = 1.0;
|
|
||||||
mQuadrature = 0.0;
|
|
||||||
mPreviousInphase = 1.0;
|
|
||||||
mPreviousQuadrature = 0.0;
|
|
||||||
mReset = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ 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 = 50000;
|
public static final int SAMPLE_RATE = 800000;
|
||||||
public static final int DC_NOISE_BANDWIDTH = 0;
|
public static final int DC_NOISE_BANDWIDTH = 0;
|
||||||
public static final double USABLE_BANDWIDTH = 1.00;
|
public static final double USABLE_BANDWIDTH = 1.00;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user