mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-15 12:51:49 -05:00
Channel Analyzer: fixed rational downsampler
This commit is contained in:
parent
cb3be14515
commit
bb35db0703
@ -137,7 +137,7 @@ bool ChannelAnalyzerBaseband::handleMessage(const Message& cmd)
|
|||||||
qDebug() << "ChannelAnalyzerBaseband::handleMessage: DSPSignalNotification: basebandSampleRate: " << notif.getSampleRate();
|
qDebug() << "ChannelAnalyzerBaseband::handleMessage: DSPSignalNotification: basebandSampleRate: " << notif.getSampleRate();
|
||||||
m_sampleFifo.setSize(SampleSinkFifo::getSizePolicy(notif.getSampleRate()));
|
m_sampleFifo.setSize(SampleSinkFifo::getSizePolicy(notif.getSampleRate()));
|
||||||
m_channelizer->setBasebandSampleRate(notif.getSampleRate());
|
m_channelizer->setBasebandSampleRate(notif.getSampleRate());
|
||||||
int desiredSampleRate = getSinkSampleRate(m_settings);
|
int desiredSampleRate = m_channelizer->getBasebandSampleRate() / (1<<m_settings.m_log2Decim);
|
||||||
m_channelizer->setChannelization(desiredSampleRate, m_settings.m_inputFrequencyOffset);
|
m_channelizer->setChannelization(desiredSampleRate, m_settings.m_inputFrequencyOffset);
|
||||||
m_sink.applyChannelSettings(m_channelizer->getChannelSampleRate(), desiredSampleRate, m_channelizer->getChannelFrequencyOffset());
|
m_sink.applyChannelSettings(m_channelizer->getChannelSampleRate(), desiredSampleRate, m_channelizer->getChannelFrequencyOffset());
|
||||||
|
|
||||||
@ -156,7 +156,7 @@ void ChannelAnalyzerBaseband::applySettings(const ChannelAnalyzerSettings& setti
|
|||||||
|| (settings.m_rationalDownSamplerRate != m_settings.m_rationalDownSamplerRate)
|
|| (settings.m_rationalDownSamplerRate != m_settings.m_rationalDownSamplerRate)
|
||||||
|| (settings.m_rationalDownSample != m_settings.m_rationalDownSample) || force)
|
|| (settings.m_rationalDownSample != m_settings.m_rationalDownSample) || force)
|
||||||
{
|
{
|
||||||
int desiredSampleRate = getSinkSampleRate(settings);
|
int desiredSampleRate = m_channelizer->getBasebandSampleRate() / (1<<settings.m_log2Decim);
|
||||||
m_channelizer->setChannelization(desiredSampleRate, settings.m_inputFrequencyOffset);
|
m_channelizer->setChannelization(desiredSampleRate, settings.m_inputFrequencyOffset);
|
||||||
m_sink.applyChannelSettings(m_channelizer->getChannelSampleRate(), desiredSampleRate, m_channelizer->getChannelFrequencyOffset());
|
m_sink.applyChannelSettings(m_channelizer->getChannelSampleRate(), desiredSampleRate, m_channelizer->getChannelFrequencyOffset());
|
||||||
}
|
}
|
||||||
@ -165,12 +165,6 @@ void ChannelAnalyzerBaseband::applySettings(const ChannelAnalyzerSettings& setti
|
|||||||
m_settings = settings;
|
m_settings = settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ChannelAnalyzerBaseband::getSinkSampleRate(ChannelAnalyzerSettings settings)
|
|
||||||
{
|
|
||||||
int normalSinkSampleRate = m_channelizer->getBasebandSampleRate() / (1<<settings.m_log2Decim);
|
|
||||||
return settings.m_rationalDownSample ? settings.m_rationalDownSamplerRate : normalSinkSampleRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ChannelAnalyzerBaseband::getChannelSampleRate() const
|
int ChannelAnalyzerBaseband::getChannelSampleRate() const
|
||||||
{
|
{
|
||||||
return m_channelizer->getChannelSampleRate();
|
return m_channelizer->getChannelSampleRate();
|
||||||
|
@ -84,7 +84,6 @@ private:
|
|||||||
|
|
||||||
bool handleMessage(const Message& cmd);
|
bool handleMessage(const Message& cmd);
|
||||||
void applySettings(const ChannelAnalyzerSettings& settings, bool force = false);
|
void applySettings(const ChannelAnalyzerSettings& settings, bool force = false);
|
||||||
int getSinkSampleRate(ChannelAnalyzerSettings settngs);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void handleInputMessages();
|
void handleInputMessages();
|
||||||
|
@ -274,13 +274,6 @@ void ChannelAnalyzerGUI::on_useRationalDownsampler_toggled(bool checked)
|
|||||||
applySettings();
|
applySettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
int ChannelAnalyzerGUI::getSinkSampleRate()
|
|
||||||
{
|
|
||||||
return m_settings.m_rationalDownSample ?
|
|
||||||
m_settings.m_rationalDownSamplerRate
|
|
||||||
: m_basebandSampleRate / (1<<m_settings.m_log2Decim);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChannelAnalyzerGUI::on_signalSelect_currentIndexChanged(int index)
|
void ChannelAnalyzerGUI::on_signalSelect_currentIndexChanged(int index)
|
||||||
{
|
{
|
||||||
m_settings.m_inputType = (ChannelAnalyzerSettings::InputType) index;
|
m_settings.m_inputType = (ChannelAnalyzerSettings::InputType) index;
|
||||||
@ -461,6 +454,13 @@ ChannelAnalyzerGUI::~ChannelAnalyzerGUI()
|
|||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ChannelAnalyzerGUI::getSinkSampleRate()
|
||||||
|
{
|
||||||
|
return m_settings.m_rationalDownSample ?
|
||||||
|
m_settings.m_rationalDownSamplerRate
|
||||||
|
: m_basebandSampleRate / (1<<m_settings.m_log2Decim);
|
||||||
|
}
|
||||||
|
|
||||||
void ChannelAnalyzerGUI::setSinkSampleRate()
|
void ChannelAnalyzerGUI::setSinkSampleRate()
|
||||||
{
|
{
|
||||||
unsigned int nominalSinkSampleRate = m_basebandSampleRate / (1<<m_settings.m_log2Decim);
|
unsigned int nominalSinkSampleRate = m_basebandSampleRate / (1<<m_settings.m_log2Decim);
|
||||||
|
@ -34,8 +34,6 @@ ChannelAnalyzerSink::ChannelAnalyzerSink() :
|
|||||||
{
|
{
|
||||||
m_usb = true;
|
m_usb = true;
|
||||||
m_magsq = 0;
|
m_magsq = 0;
|
||||||
m_interpolatorDistance = 1.0f;
|
|
||||||
m_interpolatorDistanceRemain = 0.0f;
|
|
||||||
SSBFilter = new fftfilt(m_settings.m_lowCutoff / m_channelSampleRate, m_settings.m_bandwidth / m_channelSampleRate, m_ssbFftLen);
|
SSBFilter = new fftfilt(m_settings.m_lowCutoff / m_channelSampleRate, m_settings.m_bandwidth / m_channelSampleRate, m_ssbFftLen);
|
||||||
DSBFilter = new fftfilt(m_settings.m_bandwidth / m_channelSampleRate, 2*m_ssbFftLen);
|
DSBFilter = new fftfilt(m_settings.m_bandwidth / m_channelSampleRate, 2*m_ssbFftLen);
|
||||||
RRCFilter = new fftfilt(m_settings.m_bandwidth / m_channelSampleRate, 2*m_ssbFftLen);
|
RRCFilter = new fftfilt(m_settings.m_bandwidth / m_channelSampleRate, 2*m_ssbFftLen);
|
||||||
@ -57,30 +55,33 @@ ChannelAnalyzerSink::~ChannelAnalyzerSink()
|
|||||||
void ChannelAnalyzerSink::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end)
|
void ChannelAnalyzerSink::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end)
|
||||||
{
|
{
|
||||||
fftfilt::cmplx *sideband = 0;
|
fftfilt::cmplx *sideband = 0;
|
||||||
Complex ci;
|
|
||||||
|
|
||||||
for (SampleVector::const_iterator it = begin; it < end; ++it)
|
for (SampleVector::const_iterator it = begin; it < end; ++it)
|
||||||
{
|
{
|
||||||
|
Complex ci;
|
||||||
Complex c(it->real(), it->imag());
|
Complex c(it->real(), it->imag());
|
||||||
c *= m_nco.nextIQ();
|
c *= m_nco.nextIQ();
|
||||||
|
|
||||||
if (m_interpolatorDistance == 1)
|
if (m_decimator.getDecim() == 1)
|
||||||
{
|
{
|
||||||
processOneSample(c, sideband);
|
processOneSample(c, sideband);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (m_decimator.decimate(c, ci))
|
||||||
{
|
{
|
||||||
if (m_settings.m_rationalDownSample)
|
if (m_settings.m_rationalDownSample)
|
||||||
{
|
{
|
||||||
if (m_interpolator.decimate(&m_interpolatorDistanceRemain, c, &ci))
|
Complex cj;
|
||||||
|
|
||||||
|
if (m_interpolator.decimate(&m_interpolatorDistanceRemain, ci, &cj))
|
||||||
{
|
{
|
||||||
processOneSample(ci, sideband);
|
processOneSample(cj, sideband);
|
||||||
m_interpolatorDistanceRemain += m_interpolatorDistance;
|
m_interpolatorDistanceRemain += m_interpolatorDistance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (m_decimator.decimate(c, ci)) {
|
|
||||||
processOneSample(ci, sideband);
|
processOneSample(ci, sideband);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -146,6 +147,7 @@ void ChannelAnalyzerSink::applyChannelSettings(int channelSampleRate, int sinkSa
|
|||||||
<< " channelSampleRate: " << channelSampleRate
|
<< " channelSampleRate: " << channelSampleRate
|
||||||
<< " sinkSampleRate: " << sinkSampleRate
|
<< " sinkSampleRate: " << sinkSampleRate
|
||||||
<< " channelFrequencyOffset: " << channelFrequencyOffset;
|
<< " channelFrequencyOffset: " << channelFrequencyOffset;
|
||||||
|
bool doApplySampleRate = false;
|
||||||
|
|
||||||
if ((m_channelFrequencyOffset != channelFrequencyOffset) ||
|
if ((m_channelFrequencyOffset != channelFrequencyOffset) ||
|
||||||
(m_channelSampleRate != channelSampleRate) || force)
|
(m_channelSampleRate != channelSampleRate) || force)
|
||||||
@ -156,13 +158,9 @@ void ChannelAnalyzerSink::applyChannelSettings(int channelSampleRate, int sinkSa
|
|||||||
if ((m_channelSampleRate != channelSampleRate)
|
if ((m_channelSampleRate != channelSampleRate)
|
||||||
|| (m_sinkSampleRate != sinkSampleRate) || force)
|
|| (m_sinkSampleRate != sinkSampleRate) || force)
|
||||||
{
|
{
|
||||||
m_interpolator.create(16, channelSampleRate, channelSampleRate / 2.2f);
|
m_interpolator.create(16, sinkSampleRate, sinkSampleRate / 4.0f);
|
||||||
m_interpolatorDistanceRemain = 0;
|
m_interpolatorDistanceRemain = 0;
|
||||||
m_interpolatorDistance = (Real) channelSampleRate / (Real) sinkSampleRate;
|
m_interpolatorDistance = (Real) sinkSampleRate / (Real) m_settings.m_rationalDownSamplerRate;
|
||||||
|
|
||||||
setFilters(sinkSampleRate, m_settings.m_bandwidth, m_settings.m_lowCutoff);
|
|
||||||
m_pll.setSampleRate(sinkSampleRate);
|
|
||||||
m_fll.setSampleRate(sinkSampleRate);
|
|
||||||
|
|
||||||
int decim = channelSampleRate / sinkSampleRate;
|
int decim = channelSampleRate / sinkSampleRate;
|
||||||
m_decimator.setLog2Decim(0);
|
m_decimator.setLog2Decim(0);
|
||||||
@ -178,11 +176,17 @@ void ChannelAnalyzerSink::applyChannelSettings(int channelSampleRate, int sinkSa
|
|||||||
|
|
||||||
decim >>= 1;
|
decim >>= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
doApplySampleRate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_channelSampleRate = channelSampleRate;
|
m_channelSampleRate = channelSampleRate;
|
||||||
m_channelFrequencyOffset = channelFrequencyOffset;
|
m_channelFrequencyOffset = channelFrequencyOffset;
|
||||||
m_sinkSampleRate = sinkSampleRate;
|
m_sinkSampleRate = sinkSampleRate;
|
||||||
|
|
||||||
|
if (doApplySampleRate) {
|
||||||
|
applySampleRate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChannelAnalyzerSink::setFilters(int sampleRate, float bandwidth, float lowCutoff)
|
void ChannelAnalyzerSink::setFilters(int sampleRate, float bandwidth, float lowCutoff)
|
||||||
@ -216,29 +220,25 @@ void ChannelAnalyzerSink::applySettings(const ChannelAnalyzerSettings& settings,
|
|||||||
{
|
{
|
||||||
qDebug() << "ChannelAnalyzerSink::applySettings:"
|
qDebug() << "ChannelAnalyzerSink::applySettings:"
|
||||||
<< " m_inputFrequencyOffset: " << settings.m_inputFrequencyOffset
|
<< " m_inputFrequencyOffset: " << settings.m_inputFrequencyOffset
|
||||||
<< " m_rationalDownSample: " << settings.m_rationalDownSample
|
|
||||||
<< " m_rationalDownSamplerRate: " << settings.m_rationalDownSamplerRate
|
|
||||||
<< " m_rcc: " << settings.m_rrc
|
<< " m_rcc: " << settings.m_rrc
|
||||||
<< " m_rrcRolloff: " << settings.m_rrcRolloff / 100.0
|
<< " m_rrcRolloff: " << settings.m_rrcRolloff / 100.0
|
||||||
<< " m_bandwidth: " << settings.m_bandwidth
|
<< " m_bandwidth: " << settings.m_bandwidth
|
||||||
<< " m_lowCutoff: " << settings.m_lowCutoff
|
<< " m_lowCutoff: " << settings.m_lowCutoff
|
||||||
<< " m_log2Decim: " << settings.m_log2Decim
|
<< " m_log2Decim: " << settings.m_log2Decim
|
||||||
|
<< " m_rationalDownSample: " << settings.m_rationalDownSample
|
||||||
|
<< " m_rationalDownSamplerRate: " << settings.m_rationalDownSamplerRate
|
||||||
<< " m_ssb: " << settings.m_ssb
|
<< " m_ssb: " << settings.m_ssb
|
||||||
<< " m_pll: " << settings.m_pll
|
<< " m_pll: " << settings.m_pll
|
||||||
<< " m_fll: " << settings.m_fll
|
<< " m_fll: " << settings.m_fll
|
||||||
<< " m_pllPskOrder: " << settings.m_pllPskOrder
|
<< " m_pllPskOrder: " << settings.m_pllPskOrder
|
||||||
<< " m_inputType: " << (int) settings.m_inputType;
|
<< " m_inputType: " << (int) settings.m_inputType;
|
||||||
|
bool doApplySampleRate = false;
|
||||||
|
|
||||||
if ((settings.m_bandwidth != m_settings.m_bandwidth) ||
|
if ((settings.m_bandwidth != m_settings.m_bandwidth) ||
|
||||||
(settings.m_lowCutoff != m_settings.m_lowCutoff)|| force)
|
(settings.m_lowCutoff != m_settings.m_lowCutoff) ||
|
||||||
|
(settings.m_rrcRolloff != m_settings.m_rrcRolloff) || force)
|
||||||
{
|
{
|
||||||
setFilters(m_sinkSampleRate, settings.m_bandwidth, settings.m_lowCutoff);
|
doApplySampleRate = true;
|
||||||
}
|
|
||||||
|
|
||||||
if ((settings.m_rrcRolloff != m_settings.m_rrcRolloff) || force)
|
|
||||||
{
|
|
||||||
float sinkSampleRate = (float) m_sinkSampleRate;
|
|
||||||
RRCFilter->create_rrc_filter(settings.m_bandwidth / sinkSampleRate, settings.m_rrcRolloff / 100.0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.m_pll != m_settings.m_pll || force)
|
if (settings.m_pll != m_settings.m_pll || force)
|
||||||
@ -264,7 +264,20 @@ void ChannelAnalyzerSink::applySettings(const ChannelAnalyzerSettings& settings,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((settings.m_rationalDownSample != m_settings.m_rationalDownSample) ||
|
||||||
|
(settings.m_rationalDownSamplerRate != m_settings.m_rationalDownSamplerRate) || force)
|
||||||
|
{
|
||||||
|
m_interpolator.create(16, m_sinkSampleRate, m_sinkSampleRate / 4.0f);
|
||||||
|
m_interpolatorDistanceRemain = 0;
|
||||||
|
m_interpolatorDistance = (Real) m_sinkSampleRate / (Real) settings.m_rationalDownSamplerRate;
|
||||||
|
doApplySampleRate = true;
|
||||||
|
}
|
||||||
|
|
||||||
m_settings = settings;
|
m_settings = settings;
|
||||||
|
|
||||||
|
if (doApplySampleRate) {
|
||||||
|
applySampleRate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Real ChannelAnalyzerSink::getPllFrequency() const
|
Real ChannelAnalyzerSink::getPllFrequency() const
|
||||||
@ -277,3 +290,22 @@ Real ChannelAnalyzerSink::getPllFrequency() const
|
|||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ChannelAnalyzerSink::getActualSampleRate()
|
||||||
|
{
|
||||||
|
if (m_settings.m_rationalDownSample) {
|
||||||
|
return m_settings.m_rationalDownSamplerRate;
|
||||||
|
} else {
|
||||||
|
return m_sinkSampleRate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChannelAnalyzerSink::applySampleRate()
|
||||||
|
{
|
||||||
|
int sampleRate = getActualSampleRate();
|
||||||
|
qDebug("ChannelAnalyzerSink::applySampleRate: sampleRate: %d m_interpolatorDistance: %f", sampleRate, m_interpolatorDistance);
|
||||||
|
setFilters(sampleRate, m_settings.m_bandwidth, m_settings.m_lowCutoff);
|
||||||
|
m_pll.setSampleRate(sampleRate);
|
||||||
|
m_fll.setSampleRate(sampleRate);
|
||||||
|
RRCFilter->create_rrc_filter(m_settings.m_bandwidth / (float) sampleRate, m_settings.m_rrcRolloff / 100.0);
|
||||||
|
}
|
@ -65,11 +65,11 @@ private:
|
|||||||
double m_magsq;
|
double m_magsq;
|
||||||
|
|
||||||
NCOF m_nco;
|
NCOF m_nco;
|
||||||
PhaseLockComplex m_pll;
|
|
||||||
FreqLockComplex m_fll;
|
|
||||||
Interpolator m_interpolator;
|
Interpolator m_interpolator;
|
||||||
Real m_interpolatorDistance;
|
Real m_interpolatorDistance;
|
||||||
Real m_interpolatorDistanceRemain;
|
Real m_interpolatorDistanceRemain;
|
||||||
|
PhaseLockComplex m_pll;
|
||||||
|
FreqLockComplex m_fll;
|
||||||
DecimatorC m_decimator;
|
DecimatorC m_decimator;
|
||||||
|
|
||||||
fftfilt* SSBFilter;
|
fftfilt* SSBFilter;
|
||||||
@ -84,6 +84,8 @@ private:
|
|||||||
|
|
||||||
void setFilters(int sampleRate, float bandwidth, float lowCutoff);
|
void setFilters(int sampleRate, float bandwidth, float lowCutoff);
|
||||||
void processOneSample(Complex& c, fftfilt::cmplx *sideband);
|
void processOneSample(Complex& c, fftfilt::cmplx *sideband);
|
||||||
|
int getActualSampleRate();
|
||||||
|
void applySampleRate();
|
||||||
|
|
||||||
inline void feedOneSample(const fftfilt::cmplx& s, const fftfilt::cmplx& pll)
|
inline void feedOneSample(const fftfilt::cmplx& s, const fftfilt::cmplx& pll)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user