diff --git a/sdrbase/CMakeLists.txt b/sdrbase/CMakeLists.txt
index 6c67935fb..a01825a9d 100644
--- a/sdrbase/CMakeLists.txt
+++ b/sdrbase/CMakeLists.txt
@@ -62,7 +62,6 @@ set(sdrbase_SOURCES
dsp/afsquelch.cpp
dsp/agc.cpp
- dsp/downchannelizer.cpp
dsp/downsamplechannelizer.cpp
dsp/upchannelizer.cpp
dsp/channelmarker.cpp
@@ -178,7 +177,6 @@ set(sdrbase_HEADERS
dsp/afsquelch.h
dsp/autocorrector.h
- dsp/downchannelizer.h
dsp/downsamplechannelizer.h
dsp/upchannelizer.h
dsp/channelmarker.h
diff --git a/sdrbase/dsp/downchannelizer.cpp b/sdrbase/dsp/downchannelizer.cpp
deleted file mode 100644
index e82403032..000000000
--- a/sdrbase/dsp/downchannelizer.cpp
+++ /dev/null
@@ -1,392 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////
-// Copyright (C) 2016-2019 F4EXB //
-// written by Edouard Griffiths //
-// //
-// 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 as 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 V3 for more details. //
-// //
-// You should have received a copy of the GNU General Public License //
-// along with this program. If not, see . //
-///////////////////////////////////////////////////////////////////////////////////
-
-#include
-#include "dsp/inthalfbandfilter.h"
-#include "dsp/dspcommands.h"
-#include "dsp/hbfilterchainconverter.h"
-
-#include
-#include
-
-MESSAGE_CLASS_DEFINITION(DownChannelizer::MsgChannelizerNotification, Message)
-MESSAGE_CLASS_DEFINITION(DownChannelizer::MsgSetChannelizer, Message)
-
-DownChannelizer::DownChannelizer(BasebandSampleSink* sampleSink) :
- m_filterChainSetMode(false),
- m_sampleSink(sampleSink),
- m_inputSampleRate(0),
- m_requestedOutputSampleRate(0),
- m_requestedCenterFrequency(0),
- m_currentOutputSampleRate(0),
- m_currentCenterFrequency(0)
-{
- QString name = "DownChannelizer(" + m_sampleSink->objectName() + ")";
- setObjectName(name);
-}
-
-DownChannelizer::~DownChannelizer()
-{
- freeFilterChain();
-}
-
-void DownChannelizer::configure(MessageQueue* messageQueue, int sampleRate, int centerFrequency)
-{
- Message* cmd = new DSPConfigureChannelizer(sampleRate, centerFrequency);
- messageQueue->push(cmd);
-}
-
-void DownChannelizer::set(MessageQueue* messageQueue, unsigned int log2Decim, unsigned int filterChainHash)
-{
- Message* cmd = new MsgSetChannelizer(log2Decim, filterChainHash);
- messageQueue->push(cmd);
-}
-
-void DownChannelizer::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly)
-{
- if(m_sampleSink == 0) {
- m_sampleBuffer.clear();
- return;
- }
-
- if (m_filterStages.size() == 0) // optimization when no downsampling is done anyway
- {
- m_sampleSink->feed(begin, end, positiveOnly);
- }
- else
- {
- m_mutex.lock();
-
- for(SampleVector::const_iterator sample = begin; sample != end; ++sample)
- {
- Sample s(*sample);
- FilterStages::iterator stage = m_filterStages.begin();
-
- for (; stage != m_filterStages.end(); ++stage)
- {
-#ifndef SDR_RX_SAMPLE_24BIT
- s.m_real /= 2; // avoid saturation on 16 bit samples
- s.m_imag /= 2;
-#endif
- if(!(*stage)->work(&s))
- {
- break;
- }
- }
-
- if(stage == m_filterStages.end())
- {
-#ifdef SDR_RX_SAMPLE_24BIT
- s.m_real /= (1<<(m_filterStages.size())); // on 32 bit samples there is enough headroom to just divide the final result
- s.m_imag /= (1<<(m_filterStages.size()));
-#endif
- m_sampleBuffer.push_back(s);
- }
- }
-
- m_mutex.unlock();
-
- m_sampleSink->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), positiveOnly);
- m_sampleBuffer.clear();
- }
-}
-
-void DownChannelizer::start()
-{
- if (m_sampleSink != 0)
- {
- qDebug() << "DownChannelizer::start: thread: " << thread()
- << " m_inputSampleRate: " << m_inputSampleRate
- << " m_requestedOutputSampleRate: " << m_requestedOutputSampleRate
- << " m_requestedCenterFrequency: " << m_requestedCenterFrequency;
- m_sampleSink->start();
- }
-}
-
-void DownChannelizer::stop()
-{
- if(m_sampleSink != 0)
- m_sampleSink->stop();
-}
-
-bool DownChannelizer::handleMessage(const Message& cmd)
-{
- // TODO: apply changes only if input sample rate or requested output sample rate change. Change of center frequency has no impact.
-
- if (DSPSignalNotification::match(cmd))
- {
- DSPSignalNotification& notif = (DSPSignalNotification&) cmd;
- m_inputSampleRate = notif.getSampleRate();
- qDebug() << "DownChannelizer::handleMessage: DSPSignalNotification: m_inputSampleRate: " << m_inputSampleRate;
-
- if (!m_filterChainSetMode) {
- applyConfiguration();
- }
-
- if (m_sampleSink != 0)
- {
- DSPSignalNotification* rep = new DSPSignalNotification(notif); // make a copy
- m_sampleSink->getInputMessageQueue()->push(rep);
- }
-
- emit inputSampleRateChanged();
- return true;
- }
- else if (DSPConfigureChannelizer::match(cmd))
- {
- DSPConfigureChannelizer& chan = (DSPConfigureChannelizer&) cmd;
- m_requestedOutputSampleRate = chan.getSampleRate();
- m_requestedCenterFrequency = chan.getCenterFrequency();
-
- // qDebug() << "DownChannelizer::handleMessage: DSPConfigureChannelizer:"
- // << " m_requestedOutputSampleRate: " << m_requestedOutputSampleRate
- // << " m_requestedCenterFrequency: " << m_requestedCenterFrequency;
-
- applyConfiguration();
-
- return true;
- }
- else if (MsgSetChannelizer::match(cmd))
- {
- MsgSetChannelizer& chan = (MsgSetChannelizer&) cmd;
- qDebug() << "DownChannelizer::handleMessage: MsgSetChannelizer";
- applySetting(chan.getLog2Decim(), chan.getFilterChainHash());
-
- return true;
- }
- else if (BasebandSampleSink::MsgThreadedSink::match(cmd))
- {
- qDebug() << "DownChannelizer::handleMessage: MsgThreadedSink: forwarded to demod";
- return m_sampleSink->handleMessage(cmd); // this message is passed to the demod
- }
- else
- {
- qDebug() << "DownChannelizer::handleMessage: " << cmd.getIdentifier() << " unhandled";
- return false;
- }
-}
-
-void DownChannelizer::applyConfiguration()
-{
- m_filterChainSetMode = false;
-
- if (m_inputSampleRate == 0)
- {
- qDebug() << "DownChannelizer::applyConfiguration: m_inputSampleRate=0 aborting";
- return;
- }
-
- m_mutex.lock();
-
- freeFilterChain();
-
- m_currentCenterFrequency = createFilterChain(
- m_inputSampleRate / -2, m_inputSampleRate / 2,
- m_requestedCenterFrequency - m_requestedOutputSampleRate / 2, m_requestedCenterFrequency + m_requestedOutputSampleRate / 2);
-
- m_mutex.unlock();
-
- //debugFilterChain();
-
- m_currentOutputSampleRate = m_inputSampleRate / (1 << m_filterStages.size());
-
- qDebug() << "DownChannelizer::applyConfiguration in=" << m_inputSampleRate
- << ", req=" << m_requestedOutputSampleRate
- << ", out=" << m_currentOutputSampleRate
- << ", fc=" << m_currentCenterFrequency;
-
- if (m_sampleSink != 0)
- {
- MsgChannelizerNotification *notif = MsgChannelizerNotification::create(m_currentOutputSampleRate, m_currentCenterFrequency);
- m_sampleSink->getInputMessageQueue()->push(notif);
- }
-}
-
-void DownChannelizer::applySetting(unsigned int log2Decim, unsigned int filterChainHash)
-{
- m_filterChainSetMode = true;
- std::vector stageIndexes;
- m_currentCenterFrequency = m_inputSampleRate * HBFilterChainConverter::convertToIndexes(log2Decim, filterChainHash, stageIndexes);
- m_requestedCenterFrequency = m_currentCenterFrequency;
-
- m_mutex.lock();
- freeFilterChain();
- setFilterChain(stageIndexes);
- m_mutex.unlock();
-
- m_currentOutputSampleRate = m_inputSampleRate / (1 << m_filterStages.size());
- m_requestedOutputSampleRate = m_currentOutputSampleRate;
-
- qDebug() << "DownChannelizer::applySetting inputSampleRate:" << m_inputSampleRate
- << " currentOutputSampleRate: " << m_currentOutputSampleRate
- << " currentCenterFrequency: " << m_currentCenterFrequency
- << " nb_filters: " << stageIndexes.size()
- << " nb_stages: " << m_filterStages.size();
-
- if (m_sampleSink != 0)
- {
- MsgChannelizerNotification *notif = MsgChannelizerNotification::create(m_currentOutputSampleRate, m_currentCenterFrequency);
- m_sampleSink->getInputMessageQueue()->push(notif);
- }
-}
-
-#ifdef SDR_RX_SAMPLE_24BIT
-DownChannelizer::FilterStage::FilterStage(Mode mode) :
- m_filter(new IntHalfbandFilterEO),
- m_workFunction(0),
- m_mode(mode),
- m_sse(true)
-{
- switch(mode) {
- case ModeCenter:
- m_workFunction = &IntHalfbandFilterEO::workDecimateCenter;
- break;
-
- case ModeLowerHalf:
- m_workFunction = &IntHalfbandFilterEO::workDecimateLowerHalf;
- break;
-
- case ModeUpperHalf:
- m_workFunction = &IntHalfbandFilterEO::workDecimateUpperHalf;
- break;
- }
-}
-#else
-DownChannelizer::FilterStage::FilterStage(Mode mode) :
- m_filter(new IntHalfbandFilterEO),
- m_workFunction(0),
- m_mode(mode),
- m_sse(true)
-{
- switch(mode) {
- case ModeCenter:
- m_workFunction = &IntHalfbandFilterEO::workDecimateCenter;
- break;
-
- case ModeLowerHalf:
- m_workFunction = &IntHalfbandFilterEO::workDecimateLowerHalf;
- break;
-
- case ModeUpperHalf:
- m_workFunction = &IntHalfbandFilterEO::workDecimateUpperHalf;
- break;
- }
-}
-#endif
-
-DownChannelizer::FilterStage::~FilterStage()
-{
- delete m_filter;
-}
-
-bool DownChannelizer::signalContainsChannel(Real sigStart, Real sigEnd, Real chanStart, Real chanEnd) const
-{
- //qDebug(" testing signal [%f, %f], channel [%f, %f]", sigStart, sigEnd, chanStart, chanEnd);
- if(sigEnd <= sigStart)
- return false;
- if(chanEnd <= chanStart)
- return false;
- return (sigStart <= chanStart) && (sigEnd >= chanEnd);
-}
-
-Real DownChannelizer::createFilterChain(Real sigStart, Real sigEnd, Real chanStart, Real chanEnd)
-{
- Real sigBw = sigEnd - sigStart;
- Real rot = sigBw / 4;
-
- //qDebug("DownChannelizer::createFilterChain: Signal [%.1f, %.1f] (BW %.1f), Channel [%.1f, %.1f], Rot %.1f", sigStart, sigEnd, sigBw, chanStart, chanEnd, rot);
-
- // check if it fits into the left half
- if(signalContainsChannel(sigStart, sigStart + sigBw / 2.0, chanStart, chanEnd))
- {
- //qDebug("DownChannelizer::createFilterChain: -> take left half (rotate by +1/4 and decimate by 2)");
- m_filterStages.push_back(new FilterStage(FilterStage::ModeLowerHalf));
- return createFilterChain(sigStart, sigStart + sigBw / 2.0, chanStart, chanEnd);
- }
-
- // check if it fits into the right half
- if(signalContainsChannel(sigEnd - sigBw / 2.0f, sigEnd, chanStart, chanEnd))
- {
- //qDebug("DownChannelizer::createFilterChain: -> take right half (rotate by -1/4 and decimate by 2)");
- m_filterStages.push_back(new FilterStage(FilterStage::ModeUpperHalf));
- return createFilterChain(sigEnd - sigBw / 2.0f, sigEnd, chanStart, chanEnd);
- }
-
- // check if it fits into the center
- if(signalContainsChannel(sigStart + rot, sigEnd - rot, chanStart, chanEnd))
- {
- //qDebug("DownChannelizer::createFilterChain: -> take center half (decimate by 2)");
- m_filterStages.push_back(new FilterStage(FilterStage::ModeCenter));
- return createFilterChain(sigStart + rot, sigEnd - rot, chanStart, chanEnd);
- }
-
- Real ofs = ((chanEnd - chanStart) / 2.0 + chanStart) - ((sigEnd - sigStart) / 2.0 + sigStart);
- //qDebug("DownChannelizer::createFilterChain: -> complete (final BW %.1f, frequency offset %.1f)", sigBw, ofs);
- return ofs;
-}
-
-void DownChannelizer::setFilterChain(const std::vector& stageIndexes)
-{
- // filters are described from lower to upper level but the chain is constructed the other way round
- std::vector::const_reverse_iterator rit = stageIndexes.rbegin();
-
- // Each index is a base 3 number with 0 = low, 1 = center, 2 = high
- // Functions at upper level will convert a number to base 3 to describe the filter chain. Common converting
- // algorithms will go from LSD to MSD. This explains the reverse order.
- for (; rit != stageIndexes.rend(); ++rit)
- {
- if (*rit == 0) {
- m_filterStages.push_back(new FilterStage(FilterStage::ModeLowerHalf));
- } else if (*rit == 1) {
- m_filterStages.push_back(new FilterStage(FilterStage::ModeCenter));
- } else if (*rit == 2) {
- m_filterStages.push_back(new FilterStage(FilterStage::ModeUpperHalf));
- }
- }
-}
-
-void DownChannelizer::freeFilterChain()
-{
- for(FilterStages::iterator it = m_filterStages.begin(); it != m_filterStages.end(); ++it)
- delete *it;
- m_filterStages.clear();
-}
-
-void DownChannelizer::debugFilterChain()
-{
- qDebug("DownChannelizer::debugFilterChain: %lu stages", m_filterStages.size());
-
- for(FilterStages::iterator it = m_filterStages.begin(); it != m_filterStages.end(); ++it)
- {
- switch ((*it)->m_mode)
- {
- case FilterStage::ModeCenter:
- qDebug("DownChannelizer::debugFilterChain: center %s", (*it)->m_sse ? "sse" : "no_sse");
- break;
- case FilterStage::ModeLowerHalf:
- qDebug("DownChannelizer::debugFilterChain: lower %s", (*it)->m_sse ? "sse" : "no_sse");
- break;
- case FilterStage::ModeUpperHalf:
- qDebug("DownChannelizer::debugFilterChain: upper %s", (*it)->m_sse ? "sse" : "no_sse");
- break;
- default:
- qDebug("DownChannelizer::debugFilterChain: none %s", (*it)->m_sse ? "sse" : "no_sse");
- break;
- }
- }
-}
diff --git a/sdrbase/dsp/downchannelizer.h b/sdrbase/dsp/downchannelizer.h
deleted file mode 100644
index d256ecf2e..000000000
--- a/sdrbase/dsp/downchannelizer.h
+++ /dev/null
@@ -1,143 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////
-// Copyright (C) 2016-2019 F4EXB //
-// written by Edouard Griffiths //
-// //
-// 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 as 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 V3 for more details. //
-// //
-// You should have received a copy of the GNU General Public License //
-// along with this program. If not, see . //
-///////////////////////////////////////////////////////////////////////////////////
-
-#ifndef SDRBASE_DSP_DOWNCHANNELIZER_H
-#define SDRBASE_DSP_DOWNCHANNELIZER_H
-
-#include
-#include
-#include
-#include
-#include "export.h"
-#include "util/message.h"
-#include "dsp/inthalfbandfiltereo.h"
-
-#define DOWNCHANNELIZER_HB_FILTER_ORDER 48
-
-class MessageQueue;
-
-class SDRBASE_API DownChannelizer : public BasebandSampleSink {
- Q_OBJECT
-public:
- class SDRBASE_API MsgChannelizerNotification : public Message {
- MESSAGE_CLASS_DECLARATION
-
- public:
- MsgChannelizerNotification(int samplerate, qint64 frequencyOffset) :
- Message(),
- m_sampleRate(samplerate),
- m_frequencyOffset(frequencyOffset)
- { }
-
- int getSampleRate() const { return m_sampleRate; }
- qint64 getFrequencyOffset() const { return m_frequencyOffset; }
-
- static MsgChannelizerNotification* create(int samplerate, qint64 frequencyOffset)
- {
- return new MsgChannelizerNotification(samplerate, frequencyOffset);
- }
-
- private:
- int m_sampleRate;
- qint64 m_frequencyOffset;
- };
-
- class SDRBASE_API MsgSetChannelizer : public Message {
- MESSAGE_CLASS_DECLARATION
-
- public:
- MsgSetChannelizer(unsigned int log2Decim, unsigned int filterChainHash) :
- Message(),
- m_log2Decim(log2Decim),
- m_filterChainHash(filterChainHash)
- { }
-
- unsigned int getLog2Decim() const { return m_log2Decim; }
- unsigned int getFilterChainHash() const { return m_filterChainHash; }
-
- private:
- unsigned int m_log2Decim;
- unsigned int m_filterChainHash;
- };
-
- DownChannelizer(BasebandSampleSink* sampleSink);
- virtual ~DownChannelizer();
-
- void configure(MessageQueue* messageQueue, int sampleRate, int centerFrequency);
- void set(MessageQueue* messageQueue, unsigned int log2Decim, unsigned int filterChainHash);
- int getInputSampleRate() const { return m_inputSampleRate; }
- int getRequestedCenterFrequency() const { return m_requestedCenterFrequency; }
-
- virtual void start();
- virtual void stop();
- virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly);
- virtual bool handleMessage(const Message& cmd);
-
-protected:
- struct FilterStage {
- enum Mode {
- ModeCenter,
- ModeLowerHalf,
- ModeUpperHalf
- };
-
-#ifdef SDR_RX_SAMPLE_24BIT
- typedef bool (IntHalfbandFilterEO::*WorkFunction)(Sample* s);
- IntHalfbandFilterEO* m_filter;
-#else
- typedef bool (IntHalfbandFilterEO::*WorkFunction)(Sample* s);
- IntHalfbandFilterEO* m_filter;
-#endif
-
- WorkFunction m_workFunction;
- Mode m_mode;
- bool m_sse;
-
- FilterStage(Mode mode);
- ~FilterStage();
-
- bool work(Sample* sample)
- {
- return (m_filter->*m_workFunction)(sample);
- }
- };
- typedef std::list FilterStages;
- FilterStages m_filterStages;
- bool m_filterChainSetMode;
- BasebandSampleSink* m_sampleSink; //!< Demodulator
- int m_inputSampleRate;
- int m_requestedOutputSampleRate;
- int m_requestedCenterFrequency;
- int m_currentOutputSampleRate;
- int m_currentCenterFrequency;
- SampleVector m_sampleBuffer;
- QMutex m_mutex;
-
- void applyConfiguration();
- void applySetting(unsigned int log2Decim, unsigned int filterChainHash);
- bool signalContainsChannel(Real sigStart, Real sigEnd, Real chanStart, Real chanEnd) const;
- Real createFilterChain(Real sigStart, Real sigEnd, Real chanStart, Real chanEnd);
- void setFilterChain(const std::vector& stageIndexes);
- void freeFilterChain();
- void debugFilterChain();
-
-signals:
- void inputSampleRateChanged();
-};
-
-#endif // SDRBASE_DSP_DOWNCHANNELIZER_H
diff --git a/sdrbase/dsp/dspdevicesourceengine.cpp b/sdrbase/dsp/dspdevicesourceengine.cpp
index 2c252f162..2808790cb 100644
--- a/sdrbase/dsp/dspdevicesourceengine.cpp
+++ b/sdrbase/dsp/dspdevicesourceengine.cpp
@@ -20,7 +20,6 @@
#include
#include
-#include
#include
#include
#include "dsp/dspcommands.h"