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::MsgSampleRateNotification, Message)
MESSAGE_CLASS_DEFINITION(RemoteSink::MsgConfigureChannelizer, Message)
const QString RemoteSink::m_channelIdURI = "sdrangel.channel.remotesink";
const QString RemoteSink::m_channelId = "RemoteSink";
@ -58,6 +59,7 @@ RemoteSink::RemoteSink(DeviceSourceAPI *deviceAPI) :
m_sampleIndex(0),
m_dataBlock(0),
m_centerFrequency(0),
m_frequencyOffset(0),
m_sampleRate(48000),
m_nbBlocksFEC(0),
m_txDelay(35),
@ -127,7 +129,7 @@ void RemoteSink::feed(const SampleVector::const_iterator& begin, const SampleVec
RemoteMetaDataFEC metaData;
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_sampleBytes = (SDR_RX_SAMP_SZ <= 16 ? 2 : 4);
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);
if (m_guiMessageQueue)
{
MsgSampleRateNotification *msg = MsgSampleRateNotification::create(notif.getSampleRate());
m_guiMessageQueue->push(msg);
}
m_frequencyOffset = notif.getFrequencyOffset();
return true;
}
@ -290,6 +287,12 @@ bool RemoteSink::handleMessage(const Message& cmd)
setCenterFrequency(notif.getCenterFrequency());
if (m_guiMessageQueue)
{
MsgSampleRateNotification *msg = MsgSampleRateNotification::create(notif.getSampleRate());
m_guiMessageQueue->push(msg);
}
return true;
}
else if (MsgConfigureRemoteSink::match(cmd))
@ -300,6 +303,22 @@ bool RemoteSink::handleMessage(const Message& cmd)
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
{
return false;

View File

@ -31,7 +31,7 @@
#include "dsp/basebandsamplesink.h"
#include "channel/channelsinkapi.h"
#include "../remotesink/remotesinksettings.h"
#include "remotesinksettings.h"
class QNetworkAccessManager;
class QNetworkReply;
@ -86,6 +86,29 @@ public:
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);
virtual ~RemoteSink();
virtual void destroy() { delete this; }
@ -122,6 +145,7 @@ public:
void setTxDelay(int txDelay, int nbBlocksFEC);
void setDataAddress(const QString& address) { m_dataAddress = address; }
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_channelId;
@ -147,6 +171,7 @@ private:
QMutex m_dataBlockMutex;
uint64_t m_centerFrequency;
int64_t m_frequencyOffset;
uint32_t m_sampleRate;
int m_nbBlocksFEC;
int m_txDelay;

View File

@ -86,7 +86,7 @@ bool RemoteSinkGUI::handleMessage(const Message& message)
if (RemoteSink::MsgSampleRateNotification::match(message))
{
RemoteSink::MsgSampleRateNotification& notif = (RemoteSink::MsgSampleRateNotification&) message;
m_channelMarker.setBandwidth(notif.getSampleRate());
//m_channelMarker.setBandwidth(notif.getSampleRate());
m_sampleRate = notif.getSampleRate();
updateTxDelayTime();
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()
{
m_channelMarker.blockSignals(true);
@ -363,6 +374,7 @@ void RemoteSinkGUI::applyPosition()
ui->filterChainText->setText(s);
displayRateAndShift();
applyChannelSettings();
}
void RemoteSinkGUI::tick()

View File

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

View File

@ -19,6 +19,7 @@
#include <dsp/downchannelizer.h>
#include "dsp/inthalfbandfilter.h"
#include "dsp/dspcommands.h"
#include "dsp/hbfilterchainconverter.h"
#include <QString>
#include <QDebug>
@ -27,6 +28,7 @@ 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),
@ -49,6 +51,12 @@ void DownChannelizer::configure(MessageQueue* messageQueue, int sampleRate, int
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) {
@ -119,7 +127,10 @@ bool DownChannelizer::handleMessage(const Message& cmd)
DSPSignalNotification& notif = (DSPSignalNotification&) cmd;
m_inputSampleRate = notif.getSampleRate();
qDebug() << "DownChannelizer::handleMessage: DSPSignalNotification: m_inputSampleRate: " << m_inputSampleRate;
applyConfiguration();
if (!m_filterChainSetMode) {
applyConfiguration();
}
if (m_sampleSink != 0)
{
@ -148,7 +159,7 @@ bool DownChannelizer::handleMessage(const Message& cmd)
{
MsgSetChannelizer& chan = (MsgSetChannelizer&) cmd;
qDebug() << "DownChannelizer::handleMessage: MsgSetChannelizer";
applySetting(chan.getStageIndexes());
applySetting(chan.getLog2Decim(), chan.getFilterChainHash());
return true;
}
@ -166,6 +177,8 @@ bool DownChannelizer::handleMessage(const Message& cmd)
void DownChannelizer::applyConfiguration()
{
m_filterChainSetMode = false;
if (m_inputSampleRate == 0)
{
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();
freeFilterChain();
m_currentCenterFrequency = m_inputSampleRate * setFilterChain(stageIndexes);
setFilterChain(stageIndexes);
m_mutex.unlock();
m_currentOutputSampleRate = m_inputSampleRate / (1 << m_filterStages.size());
m_requestedOutputSampleRate = m_currentOutputSampleRate;
qDebug() << "DownChannelizer::applySetting in=" << m_inputSampleRate
<< ", out=" << m_currentOutputSampleRate
<< ", fc=" << m_currentCenterFrequency;
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)
{
@ -317,36 +334,24 @@ Real DownChannelizer::createFilterChain(Real sigStart, Real sigEnd, Real chanSta
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
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
// 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)
{
if (*rit == 0) {
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));
}
else if (*rit == 2)
{
} else if (*rit == 2) {
m_filterStages.push_back(new FilterStage(FilterStage::ModeUpperHalf));
ofs += ofs_stage;
}
ofs_stage /= 2;
}
return ofs;
}
void DownChannelizer::freeFilterChain()

View File

@ -61,20 +61,25 @@ public:
MESSAGE_CLASS_DECLARATION
public:
MsgSetChannelizer() :
Message()
MsgSetChannelizer(unsigned int log2Decim, unsigned int filterChainHash) :
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:
std::vector<unsigned int> m_stageIndexes;
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; }
@ -113,6 +118,7 @@ protected:
};
typedef std::list<FilterStage*> FilterStages;
FilterStages m_filterStages;
bool m_filterChainSetMode;
BasebandSampleSink* m_sampleSink; //!< Demodulator
int m_inputSampleRate;
int m_requestedOutputSampleRate;
@ -123,10 +129,10 @@ protected:
QMutex m_mutex;
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;
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 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.
for (unsigned int i = 0; i < ix; i++)
{
chainIndexes.push_back(0);
shift -= shift_stage;
shift_stage *= 2;
}