mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-11-03 21:20:31 -05:00 
			
		
		
		
	Remote channel sink: decimation and shift: core changes
This commit is contained in:
		
							parent
							
								
									07c5bd19b8
								
							
						
					
					
						commit
						111c035c09
					
				@ -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;
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
@ -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()
 | 
			
		||||
 | 
			
		||||
@ -78,6 +78,7 @@ private:
 | 
			
		||||
 | 
			
		||||
    void blockApplySettings(bool block);
 | 
			
		||||
    void applySettings(bool force = false);
 | 
			
		||||
    void applyChannelSettings();
 | 
			
		||||
    void displaySettings();
 | 
			
		||||
    void displayRateAndShift();
 | 
			
		||||
    void updateTxDelayTime();
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
        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()
 | 
			
		||||
 | 
			
		||||
@ -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();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user