1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-15 12:51:49 -05:00

Remote channel sink: decimation and shift: core changes

This commit is contained in:
f4exb 2019-04-26 01:27:36 +02:00
parent 07c5bd19b8
commit 111c035c09
7 changed files with 110 additions and 41 deletions

View File

@ -44,6 +44,7 @@
MESSAGE_CLASS_DEFINITION(RemoteSink::MsgConfigureRemoteSink, Message) MESSAGE_CLASS_DEFINITION(RemoteSink::MsgConfigureRemoteSink, Message)
MESSAGE_CLASS_DEFINITION(RemoteSink::MsgSampleRateNotification, Message) MESSAGE_CLASS_DEFINITION(RemoteSink::MsgSampleRateNotification, Message)
MESSAGE_CLASS_DEFINITION(RemoteSink::MsgConfigureChannelizer, Message)
const QString RemoteSink::m_channelIdURI = "sdrangel.channel.remotesink"; const QString RemoteSink::m_channelIdURI = "sdrangel.channel.remotesink";
const QString RemoteSink::m_channelId = "RemoteSink"; const QString RemoteSink::m_channelId = "RemoteSink";
@ -58,6 +59,7 @@ RemoteSink::RemoteSink(DeviceSourceAPI *deviceAPI) :
m_sampleIndex(0), m_sampleIndex(0),
m_dataBlock(0), m_dataBlock(0),
m_centerFrequency(0), m_centerFrequency(0),
m_frequencyOffset(0),
m_sampleRate(48000), m_sampleRate(48000),
m_nbBlocksFEC(0), m_nbBlocksFEC(0),
m_txDelay(35), m_txDelay(35),
@ -127,7 +129,7 @@ void RemoteSink::feed(const SampleVector::const_iterator& begin, const SampleVec
RemoteMetaDataFEC metaData; RemoteMetaDataFEC metaData;
gettimeofday(&tv, 0); gettimeofday(&tv, 0);
metaData.m_centerFrequency = m_centerFrequency; metaData.m_centerFrequency = m_centerFrequency + (m_frequencyOffset/1000); // FIXME: precision issue
metaData.m_sampleRate = m_sampleRate; metaData.m_sampleRate = m_sampleRate;
metaData.m_sampleBytes = (SDR_RX_SAMP_SZ <= 16 ? 2 : 4); metaData.m_sampleBytes = (SDR_RX_SAMP_SZ <= 16 ? 2 : 4);
metaData.m_sampleBits = SDR_RX_SAMP_SZ; metaData.m_sampleBits = SDR_RX_SAMP_SZ;
@ -271,12 +273,7 @@ bool RemoteSink::handleMessage(const Message& cmd)
} }
setTxDelay(m_settings.m_txDelay, m_settings.m_nbFECBlocks); setTxDelay(m_settings.m_txDelay, m_settings.m_nbFECBlocks);
m_frequencyOffset = notif.getFrequencyOffset();
if (m_guiMessageQueue)
{
MsgSampleRateNotification *msg = MsgSampleRateNotification::create(notif.getSampleRate());
m_guiMessageQueue->push(msg);
}
return true; return true;
} }
@ -290,6 +287,12 @@ bool RemoteSink::handleMessage(const Message& cmd)
setCenterFrequency(notif.getCenterFrequency()); setCenterFrequency(notif.getCenterFrequency());
if (m_guiMessageQueue)
{
MsgSampleRateNotification *msg = MsgSampleRateNotification::create(notif.getSampleRate());
m_guiMessageQueue->push(msg);
}
return true; return true;
} }
else if (MsgConfigureRemoteSink::match(cmd)) else if (MsgConfigureRemoteSink::match(cmd))
@ -300,6 +303,22 @@ bool RemoteSink::handleMessage(const Message& cmd)
return true; return true;
} }
else if (MsgConfigureChannelizer::match(cmd))
{
MsgConfigureChannelizer& cfg = (MsgConfigureChannelizer&) cmd;
m_settings.m_log2Decim = cfg.getLog2Decim();
m_settings.m_filterChainHash = cfg.getFilterChainHash();
qDebug() << "RemoteSink::handleMessage: MsgConfigureChannelizer:"
<< " log2Decim: " << m_settings.m_log2Decim
<< " filterChainHash: " << m_settings.m_filterChainHash;
m_channelizer->set(m_channelizer->getInputMessageQueue(),
m_settings.m_log2Decim,
m_settings.m_filterChainHash);
return true;
}
else else
{ {
return false; return false;

View File

@ -31,7 +31,7 @@
#include "dsp/basebandsamplesink.h" #include "dsp/basebandsamplesink.h"
#include "channel/channelsinkapi.h" #include "channel/channelsinkapi.h"
#include "../remotesink/remotesinksettings.h" #include "remotesinksettings.h"
class QNetworkAccessManager; class QNetworkAccessManager;
class QNetworkReply; class QNetworkReply;
@ -86,6 +86,29 @@ public:
int m_sampleRate; int m_sampleRate;
}; };
class MsgConfigureChannelizer : public Message {
MESSAGE_CLASS_DECLARATION
public:
int getLog2Decim() const { return m_log2Decim; }
int getFilterChainHash() const { return m_filterChainHash; }
static MsgConfigureChannelizer* create(int sampleRate, int centerFrequency)
{
return new MsgConfigureChannelizer(sampleRate, centerFrequency);
}
private:
unsigned int m_log2Decim;
unsigned int m_filterChainHash;
MsgConfigureChannelizer(unsigned int log2Decim, int filterChainHash) :
Message(),
m_log2Decim(log2Decim),
m_filterChainHash(filterChainHash)
{ }
};
RemoteSink(DeviceSourceAPI *deviceAPI); RemoteSink(DeviceSourceAPI *deviceAPI);
virtual ~RemoteSink(); virtual ~RemoteSink();
virtual void destroy() { delete this; } virtual void destroy() { delete this; }
@ -122,6 +145,7 @@ public:
void setTxDelay(int txDelay, int nbBlocksFEC); void setTxDelay(int txDelay, int nbBlocksFEC);
void setDataAddress(const QString& address) { m_dataAddress = address; } void setDataAddress(const QString& address) { m_dataAddress = address; }
void setDataPort(uint16_t port) { m_dataPort = port; } void setDataPort(uint16_t port) { m_dataPort = port; }
void setChannelizer(unsigned int log2Decim, unsigned int filterChainHash);
static const QString m_channelIdURI; static const QString m_channelIdURI;
static const QString m_channelId; static const QString m_channelId;
@ -147,6 +171,7 @@ private:
QMutex m_dataBlockMutex; QMutex m_dataBlockMutex;
uint64_t m_centerFrequency; uint64_t m_centerFrequency;
int64_t m_frequencyOffset;
uint32_t m_sampleRate; uint32_t m_sampleRate;
int m_nbBlocksFEC; int m_nbBlocksFEC;
int m_txDelay; int m_txDelay;

View File

@ -86,7 +86,7 @@ bool RemoteSinkGUI::handleMessage(const Message& message)
if (RemoteSink::MsgSampleRateNotification::match(message)) if (RemoteSink::MsgSampleRateNotification::match(message))
{ {
RemoteSink::MsgSampleRateNotification& notif = (RemoteSink::MsgSampleRateNotification&) message; RemoteSink::MsgSampleRateNotification& notif = (RemoteSink::MsgSampleRateNotification&) message;
m_channelMarker.setBandwidth(notif.getSampleRate()); //m_channelMarker.setBandwidth(notif.getSampleRate());
m_sampleRate = notif.getSampleRate(); m_sampleRate = notif.getSampleRate();
updateTxDelayTime(); updateTxDelayTime();
displayRateAndShift(); displayRateAndShift();
@ -168,6 +168,17 @@ void RemoteSinkGUI::applySettings(bool force)
} }
} }
void RemoteSinkGUI::applyChannelSettings()
{
if (m_doApplySettings)
{
RemoteSink::MsgConfigureChannelizer *msgChan = RemoteSink::MsgConfigureChannelizer::create(
m_settings.m_log2Decim,
m_settings.m_filterChainHash);
m_remoteSink->getInputMessageQueue()->push(msgChan);
}
}
void RemoteSinkGUI::displaySettings() void RemoteSinkGUI::displaySettings()
{ {
m_channelMarker.blockSignals(true); m_channelMarker.blockSignals(true);
@ -363,6 +374,7 @@ void RemoteSinkGUI::applyPosition()
ui->filterChainText->setText(s); ui->filterChainText->setText(s);
displayRateAndShift(); displayRateAndShift();
applyChannelSettings();
} }
void RemoteSinkGUI::tick() void RemoteSinkGUI::tick()

View File

@ -78,6 +78,7 @@ private:
void blockApplySettings(bool block); void blockApplySettings(bool block);
void applySettings(bool force = false); void applySettings(bool force = false);
void applyChannelSettings();
void displaySettings(); void displaySettings();
void displayRateAndShift(); void displayRateAndShift();
void updateTxDelayTime(); void updateTxDelayTime();

View File

@ -19,6 +19,7 @@
#include <dsp/downchannelizer.h> #include <dsp/downchannelizer.h>
#include "dsp/inthalfbandfilter.h" #include "dsp/inthalfbandfilter.h"
#include "dsp/dspcommands.h" #include "dsp/dspcommands.h"
#include "dsp/hbfilterchainconverter.h"
#include <QString> #include <QString>
#include <QDebug> #include <QDebug>
@ -27,6 +28,7 @@ MESSAGE_CLASS_DEFINITION(DownChannelizer::MsgChannelizerNotification, Message)
MESSAGE_CLASS_DEFINITION(DownChannelizer::MsgSetChannelizer, Message) MESSAGE_CLASS_DEFINITION(DownChannelizer::MsgSetChannelizer, Message)
DownChannelizer::DownChannelizer(BasebandSampleSink* sampleSink) : DownChannelizer::DownChannelizer(BasebandSampleSink* sampleSink) :
m_filterChainSetMode(false),
m_sampleSink(sampleSink), m_sampleSink(sampleSink),
m_inputSampleRate(0), m_inputSampleRate(0),
m_requestedOutputSampleRate(0), m_requestedOutputSampleRate(0),
@ -49,6 +51,12 @@ void DownChannelizer::configure(MessageQueue* messageQueue, int sampleRate, int
messageQueue->push(cmd); 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) void DownChannelizer::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly)
{ {
if(m_sampleSink == 0) { if(m_sampleSink == 0) {
@ -119,7 +127,10 @@ bool DownChannelizer::handleMessage(const Message& cmd)
DSPSignalNotification& notif = (DSPSignalNotification&) cmd; DSPSignalNotification& notif = (DSPSignalNotification&) cmd;
m_inputSampleRate = notif.getSampleRate(); m_inputSampleRate = notif.getSampleRate();
qDebug() << "DownChannelizer::handleMessage: DSPSignalNotification: m_inputSampleRate: " << m_inputSampleRate; qDebug() << "DownChannelizer::handleMessage: DSPSignalNotification: m_inputSampleRate: " << m_inputSampleRate;
if (!m_filterChainSetMode) {
applyConfiguration(); applyConfiguration();
}
if (m_sampleSink != 0) if (m_sampleSink != 0)
{ {
@ -148,7 +159,7 @@ bool DownChannelizer::handleMessage(const Message& cmd)
{ {
MsgSetChannelizer& chan = (MsgSetChannelizer&) cmd; MsgSetChannelizer& chan = (MsgSetChannelizer&) cmd;
qDebug() << "DownChannelizer::handleMessage: MsgSetChannelizer"; qDebug() << "DownChannelizer::handleMessage: MsgSetChannelizer";
applySetting(chan.getStageIndexes()); applySetting(chan.getLog2Decim(), chan.getFilterChainHash());
return true; return true;
} }
@ -166,6 +177,8 @@ bool DownChannelizer::handleMessage(const Message& cmd)
void DownChannelizer::applyConfiguration() void DownChannelizer::applyConfiguration()
{ {
m_filterChainSetMode = false;
if (m_inputSampleRate == 0) if (m_inputSampleRate == 0)
{ {
qDebug() << "DownChannelizer::applyConfiguration: m_inputSampleRate=0 aborting"; qDebug() << "DownChannelizer::applyConfiguration: m_inputSampleRate=0 aborting";
@ -198,22 +211,26 @@ void DownChannelizer::applyConfiguration()
} }
} }
void DownChannelizer::applySetting(const std::vector<unsigned int>& stageIndexes) void DownChannelizer::applySetting(unsigned int log2Decim, unsigned int filterChainHash)
{ {
m_filterChainSetMode = true;
std::vector<unsigned int> stageIndexes;
m_currentCenterFrequency = m_inputSampleRate * HBFilterChainConverter::convertToIndexes(log2Decim, filterChainHash, stageIndexes);
m_requestedCenterFrequency = m_currentCenterFrequency;
m_mutex.lock(); m_mutex.lock();
freeFilterChain(); freeFilterChain();
setFilterChain(stageIndexes);
m_currentCenterFrequency = m_inputSampleRate * setFilterChain(stageIndexes);
m_mutex.unlock(); m_mutex.unlock();
m_currentOutputSampleRate = m_inputSampleRate / (1 << m_filterStages.size()); m_currentOutputSampleRate = m_inputSampleRate / (1 << m_filterStages.size());
m_requestedOutputSampleRate = m_currentOutputSampleRate; m_requestedOutputSampleRate = m_currentOutputSampleRate;
qDebug() << "DownChannelizer::applySetting in=" << m_inputSampleRate qDebug() << "DownChannelizer::applySetting inputSampleRate:" << m_inputSampleRate
<< ", out=" << m_currentOutputSampleRate << " currentOutputSampleRate: " << m_currentOutputSampleRate
<< ", fc=" << m_currentCenterFrequency; << " currentCenterFrequency: " << m_currentCenterFrequency
<< " nb_filters: " << stageIndexes.size()
<< " nb_stages: " << m_filterStages.size();
if (m_sampleSink != 0) if (m_sampleSink != 0)
{ {
@ -317,36 +334,24 @@ Real DownChannelizer::createFilterChain(Real sigStart, Real sigEnd, Real chanSta
return ofs; return ofs;
} }
double DownChannelizer::setFilterChain(const std::vector<unsigned int>& stageIndexes) void DownChannelizer::setFilterChain(const std::vector<unsigned int>& stageIndexes)
{ {
// filters are described from lower to upper level but the chain is constructed the other way round // filters are described from lower to upper level but the chain is constructed the other way round
std::vector<unsigned int>::const_reverse_iterator rit = stageIndexes.rbegin(); std::vector<unsigned int>::const_reverse_iterator rit = stageIndexes.rbegin();
double ofs = 0.0, ofs_stage = 0.25;
// Each index is a base 3 number with 0 = low, 1 = center, 2 = high // 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 // 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. // algorithms will go from LSD to MSD. This explains the reverse order.
for (; rit != stageIndexes.rend(); ++rit) for (; rit != stageIndexes.rend(); ++rit)
{ {
if (*rit == 0) if (*rit == 0) {
{
m_filterStages.push_back(new FilterStage(FilterStage::ModeLowerHalf)); m_filterStages.push_back(new FilterStage(FilterStage::ModeLowerHalf));
ofs -= ofs_stage; } else if (*rit == 1) {
}
else if (*rit == 1)
{
m_filterStages.push_back(new FilterStage(FilterStage::ModeCenter)); m_filterStages.push_back(new FilterStage(FilterStage::ModeCenter));
} } else if (*rit == 2) {
else if (*rit == 2)
{
m_filterStages.push_back(new FilterStage(FilterStage::ModeUpperHalf)); m_filterStages.push_back(new FilterStage(FilterStage::ModeUpperHalf));
ofs += ofs_stage;
} }
ofs_stage /= 2;
} }
return ofs;
} }
void DownChannelizer::freeFilterChain() void DownChannelizer::freeFilterChain()

View File

@ -61,20 +61,25 @@ public:
MESSAGE_CLASS_DECLARATION MESSAGE_CLASS_DECLARATION
public: public:
MsgSetChannelizer() : MsgSetChannelizer(unsigned int log2Decim, unsigned int filterChainHash) :
Message() Message(),
m_log2Decim(log2Decim),
m_filterChainHash(filterChainHash)
{ } { }
std::vector<unsigned int>& getStageIndexes() { return m_stageIndexes; } unsigned int getLog2Decim() const { return m_log2Decim; }
unsigned int getFilterChainHash() const { return m_filterChainHash; }
private: private:
std::vector<unsigned int> m_stageIndexes; unsigned int m_log2Decim;
unsigned int m_filterChainHash;
}; };
DownChannelizer(BasebandSampleSink* sampleSink); DownChannelizer(BasebandSampleSink* sampleSink);
virtual ~DownChannelizer(); virtual ~DownChannelizer();
void configure(MessageQueue* messageQueue, int sampleRate, int centerFrequency); 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 getInputSampleRate() const { return m_inputSampleRate; }
int getRequestedCenterFrequency() const { return m_requestedCenterFrequency; } int getRequestedCenterFrequency() const { return m_requestedCenterFrequency; }
@ -113,6 +118,7 @@ protected:
}; };
typedef std::list<FilterStage*> FilterStages; typedef std::list<FilterStage*> FilterStages;
FilterStages m_filterStages; FilterStages m_filterStages;
bool m_filterChainSetMode;
BasebandSampleSink* m_sampleSink; //!< Demodulator BasebandSampleSink* m_sampleSink; //!< Demodulator
int m_inputSampleRate; int m_inputSampleRate;
int m_requestedOutputSampleRate; int m_requestedOutputSampleRate;
@ -123,10 +129,10 @@ protected:
QMutex m_mutex; QMutex m_mutex;
void applyConfiguration(); void applyConfiguration();
void applySetting(const std::vector<unsigned int>& stageIndexes); void applySetting(unsigned int log2Decim, unsigned int filterChainHash);
bool signalContainsChannel(Real sigStart, Real sigEnd, Real chanStart, Real chanEnd) const; bool signalContainsChannel(Real sigStart, Real sigEnd, Real chanStart, Real chanEnd) const;
Real createFilterChain(Real sigStart, Real sigEnd, Real chanStart, Real chanEnd); Real createFilterChain(Real sigStart, Real sigEnd, Real chanStart, Real chanEnd);
double setFilterChain(const std::vector<unsigned int>& stageIndexes); //!< returns offset in ratio of sample rate void setFilterChain(const std::vector<unsigned int>& stageIndexes);
void freeFilterChain(); void freeFilterChain();
void debugFilterChain(); void debugFilterChain();

View File

@ -56,6 +56,7 @@ double HBFilterChainConverter::convertToIndexes(unsigned int log2, unsigned int
// continue shift with leading zeroes. ix has the number of leading zeroes. // continue shift with leading zeroes. ix has the number of leading zeroes.
for (unsigned int i = 0; i < ix; i++) for (unsigned int i = 0; i < ix; i++)
{ {
chainIndexes.push_back(0);
shift -= shift_stage; shift -= shift_stage;
shift_stage *= 2; shift_stage *= 2;
} }