mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-12-03 17:43:52 -05:00
Interferometer (4)
This commit is contained in:
parent
df841e47a7
commit
8c8c05653d
@ -33,35 +33,41 @@
|
||||
#include "interferometer.h"
|
||||
|
||||
MESSAGE_CLASS_DEFINITION(Interferometer::MsgConfigureInterferometer, Message)
|
||||
MESSAGE_CLASS_DEFINITION(Interferometer::MsgConfigureChannelizer, Message)
|
||||
MESSAGE_CLASS_DEFINITION(Interferometer::MsgSampleRateNotification, Message)
|
||||
MESSAGE_CLASS_DEFINITION(Interferometer::MsgBasebandNotification, Message)
|
||||
|
||||
const QString Interferometer::m_channelIdURI = "sdrangel.channel.interferometer";
|
||||
const QString Interferometer::m_channelId = "Interferometer";
|
||||
const int Interferometer::m_fftSize = 4096;
|
||||
|
||||
Interferometer::Interferometer(DeviceAPI *deviceAPI) :
|
||||
ChannelAPI(m_channelIdURI, ChannelAPI::StreamSingleSink),
|
||||
ChannelAPI(m_channelIdURI, ChannelAPI::StreamMIMO),
|
||||
m_deviceAPI(deviceAPI),
|
||||
m_spectrumSink(nullptr),
|
||||
m_scopeSink(nullptr),
|
||||
m_guiMessageQueue(nullptr),
|
||||
m_frequencyOffset(0),
|
||||
m_deviceSampleRate(48000)
|
||||
{
|
||||
m_deviceAPI->addChannelSinkAPI(this);
|
||||
setObjectName(m_channelId);
|
||||
|
||||
m_thread = new QThread(this);
|
||||
m_sink = new InterferometerSink();
|
||||
m_sink = new InterferometerSink(m_fftSize);
|
||||
m_sink->moveToThread(m_thread);
|
||||
start();
|
||||
m_deviceAPI->addMIMOChannel(this);
|
||||
m_deviceAPI->addMIMOChannelAPI(this);
|
||||
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
|
||||
|
||||
m_networkManager = new QNetworkAccessManager();
|
||||
connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*)));
|
||||
}
|
||||
|
||||
Interferometer::~Interferometer()
|
||||
{
|
||||
disconnect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*)));
|
||||
delete m_networkManager;
|
||||
|
||||
m_deviceAPI->removeChannelSinkAPI(this);
|
||||
|
||||
if (m_thread->isRunning()) {
|
||||
stop();
|
||||
}
|
||||
|
||||
m_deviceAPI->removeMIMOChannel(this);
|
||||
delete m_sink;
|
||||
delete m_thread;
|
||||
}
|
||||
@ -94,8 +100,26 @@ void Interferometer::feed(const SampleVector::const_iterator& begin, const Sampl
|
||||
m_sink->feed(begin, end, sinkIndex);
|
||||
}
|
||||
|
||||
void Interferometer::pull(Sample& sample, unsigned int sourceIndex)
|
||||
{
|
||||
(void) sample;
|
||||
(void) sourceIndex;
|
||||
}
|
||||
|
||||
void Interferometer::applySettings(const InterferometerSettings& settings, bool force)
|
||||
{
|
||||
qDebug() << "Interferometer::applySettings: "
|
||||
<< "m_correlationType: " << settings.m_correlationType
|
||||
<< "m_filterChainHash: " << settings.m_filterChainHash
|
||||
<< "m_log2Decim: " << settings.m_log2Decim
|
||||
<< "m_correlationType: " << settings.m_correlationType
|
||||
<< "m_useReverseAPI: " << settings.m_useReverseAPI
|
||||
<< "m_reverseAPIAddress: " << settings.m_reverseAPIAddress
|
||||
<< "m_reverseAPIPort: " << settings.m_reverseAPIPort
|
||||
<< "m_reverseAPIDeviceIndex: " << settings.m_reverseAPIDeviceIndex
|
||||
<< "m_reverseAPIChannelIndex: " << settings.m_reverseAPIChannelIndex
|
||||
<< "m_title: " << settings.m_title;
|
||||
|
||||
if ((m_settings.m_log2Decim != settings.m_log2Decim)
|
||||
|| (m_settings.m_filterChainHash != settings.m_filterChainHash) || force)
|
||||
{
|
||||
@ -103,6 +127,28 @@ void Interferometer::applySettings(const InterferometerSettings& settings, bool
|
||||
settings.m_log2Decim, settings.m_filterChainHash);
|
||||
m_sink->getInputMessageQueue()->push(msg);
|
||||
}
|
||||
|
||||
if ((m_settings.m_correlationType != settings.m_correlationType) || force)
|
||||
{
|
||||
InterferometerSink::MsgConfigureCorrelation *msg = InterferometerSink::MsgConfigureCorrelation::create(
|
||||
settings.m_correlationType);
|
||||
m_sink->getInputMessageQueue()->push(msg);
|
||||
}
|
||||
|
||||
m_settings = settings;
|
||||
}
|
||||
|
||||
void Interferometer::handleInputMessages()
|
||||
{
|
||||
Message* message;
|
||||
|
||||
while ((message = m_inputMessageQueue.pop()) != 0)
|
||||
{
|
||||
if (handleMessage(*message))
|
||||
{
|
||||
delete message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Interferometer::handleMessage(const Message& cmd)
|
||||
@ -114,27 +160,39 @@ bool Interferometer::handleMessage(const Message& cmd)
|
||||
applySettings(cfg.getSettings(), cfg.getForce());
|
||||
return true;
|
||||
}
|
||||
else if (DSPSignalNotification::match(cmd))
|
||||
else if (DSPMIMOSignalNotification::match(cmd))
|
||||
{
|
||||
DSPSignalNotification& notif = (DSPSignalNotification&) cmd;
|
||||
DSPMIMOSignalNotification& notif = (DSPMIMOSignalNotification&) cmd;
|
||||
|
||||
qDebug() << "Interferometer::handleMessage: DSPSignalNotification:"
|
||||
qDebug() << "Interferometer::handleMessage: DSPMIMOSignalNotification:"
|
||||
<< " inputSampleRate: " << notif.getSampleRate()
|
||||
<< " centerFrequency: " << notif.getCenterFrequency();
|
||||
<< " centerFrequency: " << notif.getCenterFrequency()
|
||||
<< " sourceElseSink: " << notif.getSourceOrSink()
|
||||
<< " streamIndex: " << notif.getIndex();
|
||||
|
||||
m_deviceSampleRate = notif.getSampleRate();
|
||||
calculateFrequencyOffset(); // This is when device sample rate changes
|
||||
|
||||
// Redo the channelizer stuff with the new sample rate to re-synchronize everything
|
||||
InterferometerSink::MsgConfigureChannelizer *msg = InterferometerSink::MsgConfigureChannelizer::create(
|
||||
m_settings.m_log2Decim,
|
||||
m_settings.m_filterChainHash);
|
||||
m_sink->getInputMessageQueue()->push(msg);
|
||||
|
||||
if (m_guiMessageQueue)
|
||||
if (notif.getSourceOrSink()) // deals with source messages only
|
||||
{
|
||||
MsgSampleRateNotification *msg = MsgSampleRateNotification::create(notif.getSampleRate());
|
||||
m_guiMessageQueue->push(msg);
|
||||
m_deviceSampleRate = notif.getSampleRate();
|
||||
calculateFrequencyOffset(); // This is when device sample rate changes
|
||||
|
||||
// Notify sink of input sample rate change
|
||||
InterferometerSink::MsgSignalNotification *sig = InterferometerSink::MsgSignalNotification::create(
|
||||
m_deviceSampleRate, notif.getCenterFrequency(), notif.getIndex()
|
||||
);
|
||||
m_sink->getInputMessageQueue()->push(sig);
|
||||
|
||||
// Redo the channelizer stuff with the new sample rate to re-synchronize everything
|
||||
InterferometerSink::MsgConfigureChannelizer *msg = InterferometerSink::MsgConfigureChannelizer::create(
|
||||
m_settings.m_log2Decim,
|
||||
m_settings.m_filterChainHash);
|
||||
m_sink->getInputMessageQueue()->push(msg);
|
||||
|
||||
if (m_guiMessageQueue)
|
||||
{
|
||||
MsgBasebandNotification *msg = MsgBasebandNotification::create(
|
||||
notif.getSampleRate(), notif.getCenterFrequency());
|
||||
m_guiMessageQueue->push(msg);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -185,6 +243,12 @@ void Interferometer::calculateFrequencyOffset()
|
||||
m_frequencyOffset = m_deviceSampleRate * shiftFactor;
|
||||
}
|
||||
|
||||
void Interferometer::applyChannelSettings(uint32_t log2Decim, uint32_t filterChainHash)
|
||||
{
|
||||
InterferometerSink::MsgConfigureChannelizer *msg = InterferometerSink::MsgConfigureChannelizer::create(log2Decim, filterChainHash);
|
||||
m_sink->getInputMessageQueue()->push(msg);
|
||||
}
|
||||
|
||||
int Interferometer::webapiSettingsGet(
|
||||
SWGSDRangel::SWGChannelSettings& response,
|
||||
QString& errorMessage)
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
#include <vector>
|
||||
#include <QNetworkRequest>
|
||||
|
||||
#include "dsp/mimosamplesink.h"
|
||||
#include "dsp/mimochannel.h"
|
||||
#include "channel/channelapi.h"
|
||||
#include "util/messagequeue.h"
|
||||
#include "util/message.h"
|
||||
@ -35,7 +35,7 @@ class QNetworkReply;
|
||||
class QNetworkAccessManager;
|
||||
class BasebandSampleSink;
|
||||
|
||||
class Interferometer: public MIMOSampleSink, public ChannelAPI
|
||||
class Interferometer: public MIMOChannel, public ChannelAPI
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
@ -62,46 +62,27 @@ public:
|
||||
{ }
|
||||
};
|
||||
|
||||
class MsgConfigureChannelizer : public Message {
|
||||
class MsgBasebandNotification : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
int getLog2Decim() const { return m_log2Decim; }
|
||||
int getFilterChainHash() const { return m_filterChainHash; }
|
||||
|
||||
static MsgConfigureChannelizer* create(unsigned int log2Decim, unsigned int filterChainHash) {
|
||||
return new MsgConfigureChannelizer(log2Decim, filterChainHash);
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned int m_log2Decim;
|
||||
unsigned int m_filterChainHash;
|
||||
|
||||
MsgConfigureChannelizer(unsigned int log2Decim, unsigned int filterChainHash) :
|
||||
Message(),
|
||||
m_log2Decim(log2Decim),
|
||||
m_filterChainHash(filterChainHash)
|
||||
{ }
|
||||
};
|
||||
|
||||
class MsgSampleRateNotification : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
static MsgSampleRateNotification* create(int sampleRate) {
|
||||
return new MsgSampleRateNotification(sampleRate);
|
||||
static MsgBasebandNotification* create(int sampleRate, qint64 centerFrequency) {
|
||||
return new MsgBasebandNotification(sampleRate, centerFrequency);
|
||||
}
|
||||
|
||||
int getSampleRate() const { return m_sampleRate; }
|
||||
qint64 getCenterFrequency() const { return m_centerFrequency; }
|
||||
|
||||
private:
|
||||
|
||||
MsgSampleRateNotification(int sampleRate) :
|
||||
MsgBasebandNotification(int sampleRate, qint64 centerFrequency) :
|
||||
Message(),
|
||||
m_sampleRate(sampleRate)
|
||||
m_sampleRate(sampleRate),
|
||||
m_centerFrequency(centerFrequency)
|
||||
{ }
|
||||
|
||||
int m_sampleRate;
|
||||
qint64 m_centerFrequency;
|
||||
};
|
||||
|
||||
Interferometer(DeviceAPI *deviceAPI);
|
||||
@ -111,6 +92,7 @@ public:
|
||||
virtual void start(); //!< thread start()
|
||||
virtual void stop(); //!< thread exit() and wait()
|
||||
virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, unsigned int sinkIndex);
|
||||
virtual void pull(Sample& sample, unsigned int sourceIndex);
|
||||
virtual bool handleMessage(const Message& cmd); //!< Processing of a message. Returns true if message has actually been processed
|
||||
|
||||
virtual void getIdentifier(QString& id) { id = objectName(); }
|
||||
@ -136,6 +118,7 @@ public:
|
||||
|
||||
void setSpectrumSink(BasebandSampleSink *spectrumSink);
|
||||
void setScopeSink(BasebandSampleSink *scopeSink);
|
||||
void applyChannelSettings(uint32_t log2Decim, uint32_t filterChainHash);
|
||||
|
||||
virtual int webapiSettingsGet(
|
||||
SWGSDRangel::SWGChannelSettings& response,
|
||||
@ -158,6 +141,7 @@ public:
|
||||
|
||||
static const QString m_channelIdURI;
|
||||
static const QString m_channelId;
|
||||
static const int m_fftSize;
|
||||
|
||||
private:
|
||||
DeviceAPI *m_deviceAPI;
|
||||
@ -181,6 +165,7 @@ private:
|
||||
void webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const InterferometerSettings& settings, bool force);
|
||||
|
||||
private slots:
|
||||
void handleInputMessages();
|
||||
void networkManagerFinished(QNetworkReply *reply);
|
||||
void handleData(int start, int stop);
|
||||
};
|
||||
|
||||
@ -25,7 +25,10 @@ Sample sAdd(const Sample& a, const Sample& b) { //!< Sample addition
|
||||
}
|
||||
|
||||
Sample sMulConj(const Sample& a, const Sample& b) { //!< Sample multiply with conjugate
|
||||
return Sample{a.real()*b.real() + a.imag()*b.imag(), a.imag()*b.real() - a.real()*b.imag()};
|
||||
Sample s;
|
||||
s.setReal((a.real()*b.real() + a.imag()*b.imag()) / (1<<(SDR_RX_SAMP_SZ - 16 + 1)));
|
||||
s.setImag((a.imag()*b.real() - a.real()*b.imag()) / (1<<(SDR_RX_SAMP_SZ - 16 + 1)));
|
||||
return s;
|
||||
}
|
||||
|
||||
Sample cf2s(const std::complex<float>& a) { //!< Complex float to Sample
|
||||
@ -35,6 +38,13 @@ Sample cf2s(const std::complex<float>& a) { //!< Complex float to Sample
|
||||
return s;
|
||||
}
|
||||
|
||||
Sample invfft2s(const std::complex<float>& a) { //!< Complex float to Sample
|
||||
Sample s;
|
||||
s.setReal(a.real());
|
||||
s.setImag(a.imag());
|
||||
return s;
|
||||
}
|
||||
|
||||
InterferometerCorrelator::InterferometerCorrelator(int fftSize) :
|
||||
m_corrType(InterferometerSettings::CorrelationAdd),
|
||||
m_fftSize(fftSize)
|
||||
@ -55,35 +65,50 @@ InterferometerCorrelator::InterferometerCorrelator(int fftSize) :
|
||||
|
||||
InterferometerCorrelator::~InterferometerCorrelator()
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
delete[] m_fft[i];
|
||||
}
|
||||
|
||||
delete[] m_dataj;
|
||||
delete m_invFFT;
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
delete m_fft[i];
|
||||
}
|
||||
}
|
||||
|
||||
void InterferometerCorrelator::performCorr(const SampleVector& data0, const SampleVector& data1)
|
||||
bool InterferometerCorrelator::performCorr(
|
||||
const SampleVector& data0,
|
||||
int size0,
|
||||
const SampleVector& data1,
|
||||
int size1
|
||||
)
|
||||
{
|
||||
bool results = false;
|
||||
|
||||
switch (m_corrType)
|
||||
{
|
||||
case InterferometerSettings::CorrelationAdd:
|
||||
performOpCorr(data0, data1, sAdd);
|
||||
results = performOpCorr(data0, size0, data1, size1, sAdd);
|
||||
break;
|
||||
case InterferometerSettings::CorrelationMultiply:
|
||||
performOpCorr(data0, data1, sMulConj);
|
||||
results = performOpCorr(data0, size0, data1, size1, sMulConj);
|
||||
break;
|
||||
case InterferometerSettings::CorrelationCorrelation:
|
||||
performFFTCorr(data0, data1);
|
||||
case InterferometerSettings::CorrelationFFT:
|
||||
results = performFFTCorr(data0, size0, data1, size1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
void InterferometerCorrelator::performOpCorr(const SampleVector& data0, const SampleVector& data1, Sample sampleOp(const Sample& a, const Sample& b))
|
||||
bool InterferometerCorrelator::performOpCorr(
|
||||
const SampleVector& data0,
|
||||
int size0,
|
||||
const SampleVector& data1,
|
||||
int size1,
|
||||
Sample sampleOp(const Sample& a, const Sample& b)
|
||||
)
|
||||
{
|
||||
unsigned int size = std::min(data0.size(), data1.size());
|
||||
unsigned int size = std::min(size0, size1);
|
||||
adjustTCorrSize(size);
|
||||
|
||||
std::transform(
|
||||
@ -95,12 +120,20 @@ void InterferometerCorrelator::performOpCorr(const SampleVector& data0, const Sa
|
||||
);
|
||||
|
||||
m_processed = size;
|
||||
m_remaining = 0;
|
||||
m_remaining[0] = size0 - size;
|
||||
m_remaining[1] = size1 - size;
|
||||
return true;
|
||||
}
|
||||
|
||||
void InterferometerCorrelator::performFFTCorr(const SampleVector& data0, const SampleVector& data1)
|
||||
bool InterferometerCorrelator::performFFTCorr(
|
||||
const SampleVector& data0,
|
||||
int size0,
|
||||
const SampleVector& data1,
|
||||
int size1
|
||||
)
|
||||
{
|
||||
unsigned int size = std::min(data0.size(), data1.size());
|
||||
unsigned int size = std::min(size0, size1);
|
||||
int nfft = 0;
|
||||
SampleVector::const_iterator begin0 = data0.begin();
|
||||
SampleVector::const_iterator begin1 = data1.begin();
|
||||
adjustSCorrSize(size);
|
||||
@ -167,18 +200,21 @@ void InterferometerCorrelator::performFFTCorr(const SampleVector& data0, const S
|
||||
m_invFFT->out(),
|
||||
m_invFFT->out() + 2*m_fftSize,
|
||||
m_tcorr.begin(),
|
||||
cf2s
|
||||
invfft2s
|
||||
);
|
||||
|
||||
// TODO: do something with the result
|
||||
size -= m_fftSize;
|
||||
begin0 += m_fftSize;
|
||||
begin1 += m_fftSize;
|
||||
nfft++;
|
||||
}
|
||||
|
||||
// update the samples counters
|
||||
m_processed = begin0 - data0.begin();
|
||||
m_remaining = size - m_fftSize;
|
||||
m_processed = nfft*m_fftSize;
|
||||
m_remaining[0] = size0 - nfft*m_fftSize;
|
||||
m_remaining[1] = size1 - nfft*m_fftSize;
|
||||
|
||||
return nfft > 0;
|
||||
}
|
||||
|
||||
void InterferometerCorrelator::adjustSCorrSize(int size)
|
||||
|
||||
@ -37,20 +37,36 @@ public:
|
||||
|
||||
void setCorrType(InterferometerSettings::CorrelationType corrType) { m_corrType = corrType; }
|
||||
InterferometerSettings::CorrelationType getCorrType() const { return m_corrType; }
|
||||
void performCorr(const SampleVector& data0, const SampleVector& data1);
|
||||
bool performCorr( //!< Returns true if results were produced
|
||||
const SampleVector& data0,
|
||||
int size0,
|
||||
const SampleVector& data1,
|
||||
int size1
|
||||
);
|
||||
int getFullFFTSize() const { return 2*m_fftSize; }
|
||||
|
||||
SampleVector m_scorr; //!< raw correlation result (spectrum) - Sample vector expected
|
||||
SampleVector m_tcorr; //!< correlation result (time or spectrum inverse FFT) - Sample vector expected
|
||||
int m_processed; //!< number of samples processed at the end of correlation
|
||||
int m_remaining; //!< number of samples remaining at the end of correlation
|
||||
int m_remaining[2]; //!< number of samples remaining per member at the end of correlation
|
||||
|
||||
signals:
|
||||
void dataReady(int start, int stop);
|
||||
|
||||
private:
|
||||
void performOpCorr(const SampleVector& data0, const SampleVector& data1, Sample sampleOp(const Sample& a, const Sample& b));
|
||||
void performFFTCorr(const SampleVector& data0, const SampleVector& data1);
|
||||
bool performOpCorr( //!< Returns true if results were produced
|
||||
const SampleVector& data0,
|
||||
int size0,
|
||||
const SampleVector& data1,
|
||||
int size1,
|
||||
Sample sampleOp(const Sample& a, const Sample& b)
|
||||
);
|
||||
bool performFFTCorr( //!< Returns true if results were produced
|
||||
const SampleVector& data0,
|
||||
int size0,
|
||||
const SampleVector& data1,
|
||||
int size1
|
||||
);
|
||||
void adjustSCorrSize(int size);
|
||||
void adjustTCorrSize(int size);
|
||||
|
||||
|
||||
@ -20,12 +20,15 @@
|
||||
#include "device/deviceuiset.h"
|
||||
#include "gui/basicchannelsettingsdialog.h"
|
||||
#include "dsp/hbfilterchainconverter.h"
|
||||
#include "dsp/scopevis.h"
|
||||
#include "dsp/spectrumvis.h"
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include "interferometergui.h"
|
||||
#include "interferometer.h"
|
||||
#include "ui_interferometergui.h"
|
||||
|
||||
InterferometerGUI* InterferometerGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, MIMOSampleSink *channelMIMO)
|
||||
InterferometerGUI* InterferometerGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, MIMOChannel *channelMIMO)
|
||||
{
|
||||
InterferometerGUI* gui = new InterferometerGUI(pluginAPI, deviceUISet, channelMIMO);
|
||||
return gui;
|
||||
@ -47,7 +50,7 @@ QString InterferometerGUI::getName() const
|
||||
}
|
||||
|
||||
qint64 InterferometerGUI::getCenterFrequency() const {
|
||||
return 0;
|
||||
return m_centerFrequency;
|
||||
}
|
||||
|
||||
void InterferometerGUI::setCenterFrequency(qint64 centerFrequency)
|
||||
@ -79,13 +82,18 @@ bool InterferometerGUI::deserialize(const QByteArray& data)
|
||||
}
|
||||
}
|
||||
|
||||
MessageQueue* InterferometerGUI::getInputMessageQueue()
|
||||
{
|
||||
return &m_inputMessageQueue;
|
||||
}
|
||||
|
||||
bool InterferometerGUI::handleMessage(const Message& message)
|
||||
{
|
||||
if (Interferometer::MsgSampleRateNotification::match(message))
|
||||
if (Interferometer::MsgBasebandNotification::match(message))
|
||||
{
|
||||
Interferometer::MsgSampleRateNotification& notif = (Interferometer::MsgSampleRateNotification&) message;
|
||||
m_channelMarker.setBandwidth(notif.getSampleRate());
|
||||
Interferometer::MsgBasebandNotification& notif = (Interferometer::MsgBasebandNotification&) message;
|
||||
m_sampleRate = notif.getSampleRate();
|
||||
m_centerFrequency = notif.getCenterFrequency();
|
||||
displayRateAndShift();
|
||||
return true;
|
||||
}
|
||||
@ -95,23 +103,42 @@ bool InterferometerGUI::handleMessage(const Message& message)
|
||||
}
|
||||
}
|
||||
|
||||
InterferometerGUI::InterferometerGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, MIMOSampleSink *channelMIMO, QWidget* parent) :
|
||||
InterferometerGUI::InterferometerGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, MIMOChannel *channelMIMO, QWidget* parent) :
|
||||
RollupWidget(parent),
|
||||
ui(new Ui::InterferometerGUI),
|
||||
m_pluginAPI(pluginAPI),
|
||||
m_deviceUISet(deviceUISet),
|
||||
m_sampleRate(0),
|
||||
m_sampleRate(48000),
|
||||
m_centerFrequency(435000000),
|
||||
m_tickCount(0)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
setStreamIndicator("M");
|
||||
|
||||
connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool)));
|
||||
connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &)));
|
||||
|
||||
m_spectrumVis = new SpectrumVis(SDR_RX_SCALEF, ui->glSpectrum);
|
||||
m_scopeVis = new ScopeVis(ui->glScope);
|
||||
|
||||
m_interferometer = (Interferometer*) channelMIMO;
|
||||
m_interferometer->setScopeSink(m_scopeVis);
|
||||
m_interferometer->setSpectrumSink(m_spectrumVis);
|
||||
m_interferometer->setMessageQueueToGUI(getInputMessageQueue());
|
||||
|
||||
ui->glSpectrum->setDisplayWaterfall(true);
|
||||
ui->glSpectrum->setDisplayMaxHold(true);
|
||||
ui->glSpectrum->setCenterFrequency(0);
|
||||
ui->glSpectrum->setSsbSpectrum(false);
|
||||
ui->glSpectrum->setLsbDisplay(false);
|
||||
|
||||
ui->glSpectrum->connectTimer(MainWindow::getInstance()->getMasterTimer());
|
||||
ui->glScope->connectTimer(MainWindow::getInstance()->getMasterTimer());
|
||||
connect(&MainWindow::getInstance()->getMasterTimer(), SIGNAL(timeout()), this, SLOT(tick()));
|
||||
|
||||
m_channelMarker.blockSignals(true);
|
||||
m_channelMarker.addStreamIndex(1);
|
||||
m_channelMarker.setColor(m_settings.m_rgbColor);
|
||||
m_channelMarker.setCenterFrequency(0);
|
||||
m_channelMarker.setTitle("Interferometer");
|
||||
@ -120,21 +147,30 @@ InterferometerGUI::InterferometerGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUI
|
||||
|
||||
m_settings.setChannelMarker(&m_channelMarker);
|
||||
|
||||
// m_deviceUISet->registerRxChannelInstance(LocalSink::m_channelIdURI, this);
|
||||
m_deviceUISet->registerChannelInstance(Interferometer::m_channelIdURI, this);
|
||||
m_deviceUISet->addChannelMarker(&m_channelMarker);
|
||||
m_deviceUISet->addRollupWidget(this);
|
||||
|
||||
ui->spectrumGUI->setBuddies(m_spectrumVis->getInputMessageQueue(), m_spectrumVis, ui->glSpectrum);
|
||||
ui->scopeGUI->setBuddies(m_scopeVis->getInputMessageQueue(), m_scopeVis, ui->glScope);
|
||||
|
||||
m_scopeVis->setTraceChunkSize(Interferometer::m_fftSize); // Set scope trace length unit to FFT size
|
||||
ui->scopeGUI->traceLengthChange();
|
||||
|
||||
connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleSourceMessages()));
|
||||
//connect(&(m_deviceUISet->m_deviceSourceAPI->getMasterTimer()), SIGNAL(timeout()), this, SLOT(tick()));
|
||||
|
||||
displaySettings();
|
||||
displayRateAndShift();
|
||||
applySettings(true);
|
||||
}
|
||||
|
||||
InterferometerGUI::~InterferometerGUI()
|
||||
{
|
||||
//m_deviceUISet->removeRxChannelInstance(this);
|
||||
m_deviceUISet->removeChannelInstance(this);
|
||||
delete m_interferometer; // TODO: check this: when the GUI closes it has to delete the demodulator
|
||||
delete m_spectrumVis;
|
||||
delete m_scopeVis;
|
||||
delete ui;
|
||||
}
|
||||
|
||||
@ -154,17 +190,6 @@ void InterferometerGUI::applySettings(bool force)
|
||||
}
|
||||
}
|
||||
|
||||
void InterferometerGUI::applyChannelSettings()
|
||||
{
|
||||
if (m_doApplySettings)
|
||||
{
|
||||
Interferometer::MsgConfigureChannelizer *msgChan = Interferometer::MsgConfigureChannelizer::create(
|
||||
m_settings.m_log2Decim,
|
||||
m_settings.m_filterChainHash);
|
||||
m_interferometer->getInputMessageQueue()->push(msgChan);
|
||||
}
|
||||
}
|
||||
|
||||
void InterferometerGUI::displaySettings()
|
||||
{
|
||||
m_channelMarker.blockSignals(true);
|
||||
@ -193,6 +218,8 @@ void InterferometerGUI::displayRateAndShift()
|
||||
ui->channelRateText->setText(tr("%1k").arg(QString::number(channelSampleRate / 1000.0, 'g', 5)));
|
||||
m_channelMarker.setCenterFrequency(shift);
|
||||
m_channelMarker.setBandwidth(channelSampleRate);
|
||||
ui->glSpectrum->setSampleRate(channelSampleRate);
|
||||
m_scopeVis->setLiveRate(channelSampleRate);
|
||||
}
|
||||
|
||||
void InterferometerGUI::leaveEvent(QEvent*)
|
||||
@ -267,6 +294,12 @@ void InterferometerGUI::on_position_valueChanged(int value)
|
||||
applyPosition();
|
||||
}
|
||||
|
||||
void InterferometerGUI::on_correlationType_currentIndexChanged(int index)
|
||||
{
|
||||
m_settings.m_correlationType = (InterferometerSettings::CorrelationType) index;
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void InterferometerGUI::applyDecimation()
|
||||
{
|
||||
uint32_t maxHash = 1;
|
||||
@ -289,7 +322,7 @@ void InterferometerGUI::applyPosition()
|
||||
ui->filterChainText->setText(s);
|
||||
|
||||
displayRateAndShift();
|
||||
applyChannelSettings();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void InterferometerGUI::tick()
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
|
||||
class PluginAPI;
|
||||
class DeviceUISet;
|
||||
class MIMOSampleSink;
|
||||
class MIMOChannel;
|
||||
class Interferometer;
|
||||
class SpectrumVis;
|
||||
class ScopeVis;
|
||||
@ -40,7 +40,7 @@ namespace Ui {
|
||||
class InterferometerGUI : public RollupWidget, public PluginInstanceGUI {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static InterferometerGUI* create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, MIMOSampleSink *mimoChannel);
|
||||
static InterferometerGUI* create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, MIMOChannel *mimoChannel);
|
||||
|
||||
virtual void destroy();
|
||||
virtual void setName(const QString& name);
|
||||
@ -64,6 +64,7 @@ private:
|
||||
ChannelMarker m_channelMarker;
|
||||
InterferometerSettings m_settings;
|
||||
int m_sampleRate;
|
||||
qint64 m_centerFrequency;
|
||||
double m_shiftFrequencyFactor; //!< Channel frequency shift factor
|
||||
bool m_doApplySettings;
|
||||
MovingAverageUtil<double, double, 40> m_channelPowerAvg;
|
||||
@ -73,12 +74,11 @@ private:
|
||||
MessageQueue m_inputMessageQueue;
|
||||
uint32_t m_tickCount;
|
||||
|
||||
explicit InterferometerGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, MIMOSampleSink *rxChannel, QWidget* parent = nullptr);
|
||||
explicit InterferometerGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, MIMOChannel *rxChannel, QWidget* parent = nullptr);
|
||||
virtual ~InterferometerGUI();
|
||||
|
||||
void blockApplySettings(bool block);
|
||||
void applySettings(bool force = false);
|
||||
void applyChannelSettings();
|
||||
void applyDecimation();
|
||||
void applyPosition();
|
||||
void displaySettings();
|
||||
@ -91,6 +91,7 @@ private slots:
|
||||
void handleSourceMessages();
|
||||
void on_decimationFactor_currentIndexChanged(int index);
|
||||
void on_position_valueChanged(int value);
|
||||
void on_correlationType_currentIndexChanged(int index);
|
||||
void onWidgetRolled(QWidget* widget, bool rollDown);
|
||||
void onMenuDialogCalled(const QPoint& p);
|
||||
void handleInputMessages();
|
||||
|
||||
@ -150,6 +150,42 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Corr</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="correlationType">
|
||||
<property name="toolTip">
|
||||
<string>Correlation type</string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Mul</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>FFT</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
@ -182,28 +218,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="channelPower">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>52</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Channel power</string>
|
||||
</property>
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::LeftToRight</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>-100.0 dB</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
@ -257,61 +271,6 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="BWLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="BWLabel">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>15</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>BP</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="BW">
|
||||
<property name="toolTip">
|
||||
<string>Lowpass filter cutoff frequency</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-60</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>60</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>30</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="BWText">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>3.0k</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="spectrumContainer" native="true">
|
||||
@ -330,7 +289,7 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Channel Spectrum</string>
|
||||
<string>Frequency domain</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayoutSpectrum">
|
||||
<property name="spacing">
|
||||
@ -385,7 +344,7 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Channel Scope</string>
|
||||
<string>Time domain</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayoutScope">
|
||||
<property name="spacing">
|
||||
|
||||
@ -58,18 +58,18 @@ void InterferometerPlugin::initPlugin(PluginAPI* pluginAPI)
|
||||
#ifdef SERVER_MODE
|
||||
PluginInstanceGUI* InterferometerPlugin::createRxChannelGUI(
|
||||
DeviceUISet *deviceUISet,
|
||||
MIMOSampleSink *mimoChannel) const
|
||||
MIMOChannel *mimoChannel) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
PluginInstanceGUI* InterferometerPlugin::createMIMOChannelGUI(DeviceUISet *deviceUISet, MIMOSampleSink *mimoChannel) const
|
||||
PluginInstanceGUI* InterferometerPlugin::createMIMOChannelGUI(DeviceUISet *deviceUISet, MIMOChannel *mimoChannel) const
|
||||
{
|
||||
return InterferometerGUI::create(m_pluginAPI, deviceUISet, mimoChannel);
|
||||
}
|
||||
#endif
|
||||
|
||||
MIMOSampleSink* InterferometerPlugin::createMIMOChannelBS(DeviceAPI *deviceAPI) const
|
||||
MIMOChannel* InterferometerPlugin::createMIMOChannelBS(DeviceAPI *deviceAPI) const
|
||||
{
|
||||
return new Interferometer(deviceAPI);
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
#include "plugin/plugininterface.h"
|
||||
|
||||
class DeviceUISet;
|
||||
class MIMOSampleSink;
|
||||
class MIMOChannel;
|
||||
|
||||
class InterferometerPlugin : public QObject, PluginInterface {
|
||||
Q_OBJECT
|
||||
@ -36,8 +36,8 @@ public:
|
||||
const PluginDescriptor& getPluginDescriptor() const;
|
||||
void initPlugin(PluginAPI* pluginAPI);
|
||||
|
||||
virtual PluginInstanceGUI* createMIMOChannelGUI(DeviceUISet *deviceUISet, MIMOSampleSink *mimoChannel) const;
|
||||
virtual MIMOSampleSink* createMIMOChannelBS(DeviceAPI *deviceAPI) const;
|
||||
virtual PluginInstanceGUI* createMIMOChannelGUI(DeviceUISet *deviceUISet, MIMOChannel *mimoChannel) const;
|
||||
virtual MIMOChannel* createMIMOChannelBS(DeviceAPI *deviceAPI) const;
|
||||
virtual ChannelAPI* createMIMOChannelCS(DeviceAPI *deviceAPI) const;
|
||||
virtual ChannelWebAPIAdapter* createChannelWebAPIAdapter() const;
|
||||
|
||||
|
||||
@ -29,7 +29,7 @@ struct InterferometerSettings
|
||||
{
|
||||
CorrelationAdd,
|
||||
CorrelationMultiply,
|
||||
CorrelationCorrelation
|
||||
CorrelationFFT
|
||||
};
|
||||
|
||||
CorrelationType m_correlationType;
|
||||
|
||||
@ -18,25 +18,37 @@
|
||||
#include <QDebug>
|
||||
|
||||
#include "dsp/downchannelizer.h"
|
||||
#include "dsp/dspcommands.h"
|
||||
|
||||
#include "interferometersink.h"
|
||||
|
||||
|
||||
MESSAGE_CLASS_DEFINITION(InterferometerSink::MsgConfigureChannelizer, Message)
|
||||
MESSAGE_CLASS_DEFINITION(InterferometerSink::MsgSignalNotification, Message)
|
||||
MESSAGE_CLASS_DEFINITION(InterferometerSink::MsgConfigureCorrelation, Message)
|
||||
|
||||
InterferometerSink::InterferometerSink() :
|
||||
m_correlator(4096),
|
||||
InterferometerSink::InterferometerSink(int fftSize) :
|
||||
m_correlator(fftSize),
|
||||
m_spectrumSink(nullptr),
|
||||
m_scopeSink(nullptr)
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
m_sinkFifos[i].setSize(96000 * 4);
|
||||
m_sinks[i].setStreamIndex(i);
|
||||
m_channelizers[i] = new DownChannelizer(&m_sinks[i]);
|
||||
// QObject::connect(
|
||||
// &m_sinkBuffers[i],
|
||||
// &SampleSinkVector::dataReady,
|
||||
// this,
|
||||
// [=](){ this->handleSinkBuffer(i); },
|
||||
// Qt::QueuedConnection
|
||||
// );
|
||||
QObject::connect(
|
||||
&m_sinkBuffers[i],
|
||||
&SampleSinkVector::dataReady,
|
||||
&m_sinkFifos[i],
|
||||
&SampleSinkFifo::dataReady,
|
||||
this,
|
||||
[=](){ this->handleSinkBuffer(i); },
|
||||
[=](){ this->handleSinkFifo(i); },
|
||||
Qt::QueuedConnection
|
||||
);
|
||||
}
|
||||
@ -58,14 +70,55 @@ void InterferometerSink::feed(const SampleVector::const_iterator& begin, const S
|
||||
return;
|
||||
}
|
||||
|
||||
m_sinkBuffers[streamIndex].write(begin, end);
|
||||
m_sinkFifos[streamIndex].write(begin, end);
|
||||
//m_sinkBuffers[streamIndex].write(begin, end);
|
||||
}
|
||||
|
||||
void InterferometerSink::handleSinkBuffer(unsigned int sinkIndex)
|
||||
// void InterferometerSink::handleSinkBuffer(unsigned int sinkIndex)
|
||||
// {
|
||||
// SampleVector::iterator vbegin;
|
||||
// SampleVector::iterator vend;
|
||||
// m_sinkBuffers[sinkIndex].read(vbegin, vend);
|
||||
// m_channelizers[sinkIndex]->feed(vbegin, vend, false);
|
||||
// //qDebug("InterferometerSink::handleSinkBuffer: stream: %u samples: %ld", sinkIndex, vend - vbegin);
|
||||
|
||||
// if (sinkIndex == 1) {
|
||||
// run();
|
||||
// }
|
||||
// }
|
||||
|
||||
void InterferometerSink::handleSinkFifo(unsigned int sinkIndex)
|
||||
{
|
||||
int samplesDone = 0;
|
||||
|
||||
while ((m_sinkFifos[sinkIndex].fill() > 0) && (m_inputMessageQueue.size() == 0) && (samplesDone < m_channelizers[sinkIndex]->getInputSampleRate()))
|
||||
{
|
||||
SampleVector::iterator part1begin;
|
||||
SampleVector::iterator part1end;
|
||||
SampleVector::iterator part2begin;
|
||||
SampleVector::iterator part2end;
|
||||
|
||||
unsigned int count = m_sinkFifos[sinkIndex].readBegin(m_sinkFifos[sinkIndex].fill(), &part1begin, &part1end, &part2begin, &part2end);
|
||||
|
||||
if (part1begin != part1end) { // first part of FIFO data
|
||||
//qDebug("InterferometerSink::handleSinkFifo: part1-stream: %u count: %u", sinkIndex, count);
|
||||
processFifo(part1begin, part1end, sinkIndex);
|
||||
}
|
||||
|
||||
if (part2begin != part2end) { // second part of FIFO data (used when block wraps around)
|
||||
//qDebug("InterferometerSink::handleSinkFifo: part2-stream: %u count: %u", sinkIndex, count);
|
||||
processFifo(part2begin, part2end, sinkIndex);
|
||||
}
|
||||
|
||||
m_sinkFifos[sinkIndex].readCommit((unsigned int) count); // adjust FIFO pointers
|
||||
samplesDone += count;
|
||||
}
|
||||
|
||||
//qDebug("InterferometerSink::handleSinkFifo: done");
|
||||
}
|
||||
|
||||
void InterferometerSink::processFifo(const SampleVector::iterator& vbegin, const SampleVector::iterator& vend, unsigned int sinkIndex)
|
||||
{
|
||||
SampleVector::iterator vbegin;
|
||||
SampleVector::iterator vend;
|
||||
m_sinkBuffers[sinkIndex].read(vbegin, vend);
|
||||
m_channelizers[sinkIndex]->feed(vbegin, vend, false);
|
||||
|
||||
if (sinkIndex == 1) {
|
||||
@ -75,35 +128,32 @@ void InterferometerSink::handleSinkBuffer(unsigned int sinkIndex)
|
||||
|
||||
void InterferometerSink::run()
|
||||
{
|
||||
m_correlator.performCorr(m_sinks[0].getData(), m_sinks[1].getData());
|
||||
|
||||
if (m_scopeSink) {
|
||||
m_scopeSink->feed(m_correlator.m_tcorr.begin(), m_correlator.m_tcorr.begin() + m_correlator.m_processed, false);
|
||||
}
|
||||
|
||||
if (m_spectrumSink)
|
||||
if (m_correlator.performCorr(m_sinks[0].getData(), m_sinks[0].getSize(), m_sinks[1].getData(), m_sinks[1].getSize()))
|
||||
{
|
||||
if (m_correlator.getCorrType() == InterferometerSettings::CorrelationCorrelation) {
|
||||
m_spectrumSink->feed(m_correlator.m_scorr.begin(), m_correlator.m_scorr.begin() + m_correlator.m_processed, false);
|
||||
} else {
|
||||
m_spectrumSink->feed(m_correlator.m_tcorr.begin(), m_correlator.m_tcorr.begin() + m_correlator.m_processed, false);
|
||||
if (m_scopeSink) {
|
||||
m_scopeSink->feed(m_correlator.m_tcorr.begin(), m_correlator.m_tcorr.begin() + m_correlator.m_processed, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_correlator.m_remaining != 0)
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
if (m_spectrumSink)
|
||||
{
|
||||
std::copy(
|
||||
m_sinks[i].getData().begin() + m_correlator.m_processed,
|
||||
m_sinks[i].getData().begin() + m_correlator.m_processed + m_correlator.m_remaining,
|
||||
m_sinks[i].getData().begin()
|
||||
);
|
||||
if (m_correlator.getCorrType() == InterferometerSettings::CorrelationFFT) {
|
||||
m_spectrumSink->feed(m_correlator.m_scorr.begin(), m_correlator.m_scorr.begin() + m_correlator.m_processed, false);
|
||||
} else {
|
||||
m_spectrumSink->feed(m_correlator.m_tcorr.begin(), m_correlator.m_tcorr.begin() + m_correlator.m_processed, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_sinks[0].setDataStart(m_correlator.m_remaining);
|
||||
m_sinks[1].setDataStart(m_correlator.m_remaining);
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
std::copy(
|
||||
m_sinks[i].getData().begin() + m_correlator.m_processed,
|
||||
m_sinks[i].getData().begin() + m_correlator.m_processed + m_correlator.m_remaining[i],
|
||||
m_sinks[i].getData().begin()
|
||||
);
|
||||
|
||||
m_sinks[i].setDataStart(m_correlator.m_remaining[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void InterferometerSink::handleInputMessages()
|
||||
@ -140,6 +190,38 @@ bool InterferometerSink::handleMessage(const Message& cmd)
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (MsgSignalNotification::match(cmd))
|
||||
{
|
||||
MsgSignalNotification& cfg = (MsgSignalNotification&) cmd;
|
||||
int inputSampleRate = cfg.getInputSampleRate();
|
||||
qint64 centerFrequency = cfg.getCenterFrequency();
|
||||
int streamIndex = cfg.getStreamIndex();
|
||||
|
||||
qDebug() << "InterferometerSink::handleMessage: MsgSignalNotification:"
|
||||
<< " inputSampleRate: " << inputSampleRate
|
||||
<< " centerFrequency: " << centerFrequency
|
||||
<< " streamIndex: " << streamIndex;
|
||||
|
||||
if (streamIndex < 2)
|
||||
{
|
||||
DSPSignalNotification *notif = new DSPSignalNotification(inputSampleRate, centerFrequency);
|
||||
m_channelizers[streamIndex]->getInputMessageQueue()->push(notif);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (MsgConfigureCorrelation::match(cmd))
|
||||
{
|
||||
MsgConfigureCorrelation& cfg = (MsgConfigureCorrelation&) cmd;
|
||||
InterferometerSettings::CorrelationType correlationType = cfg.getCorrelationType();
|
||||
|
||||
qDebug() << "InterferometerSink::handleMessage: MsgConfigureCorrelation:"
|
||||
<< " correlationType: " << correlationType;
|
||||
|
||||
m_correlator.setCorrType(correlationType);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
|
||||
@ -20,8 +20,8 @@
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "dsp/mimosamplesink.h"
|
||||
#include "dsp/samplesinkvector.h"
|
||||
//#include "dsp/samplesinkvector.h"
|
||||
#include "dsp/samplesinkfifo.h"
|
||||
#include "interferometerstreamsink.h"
|
||||
#include "interferometercorr.h"
|
||||
|
||||
@ -54,7 +54,50 @@ public:
|
||||
{ }
|
||||
};
|
||||
|
||||
InterferometerSink();
|
||||
class MsgConfigureCorrelation : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
InterferometerSettings::CorrelationType getCorrelationType() const { return m_correlationType; }
|
||||
|
||||
static MsgConfigureCorrelation *create(InterferometerSettings::CorrelationType correlationType) {
|
||||
return new MsgConfigureCorrelation(correlationType);
|
||||
}
|
||||
|
||||
private:
|
||||
InterferometerSettings::CorrelationType m_correlationType;
|
||||
|
||||
MsgConfigureCorrelation(InterferometerSettings::CorrelationType correlationType) :
|
||||
Message(),
|
||||
m_correlationType(correlationType)
|
||||
{}
|
||||
};
|
||||
|
||||
class MsgSignalNotification : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
int getInputSampleRate() const { return m_inputSampleRate; }
|
||||
qint64 getCenterFrequency() const { return m_centerFrequency; }
|
||||
int getStreamIndex() const { return m_streamIndex; }
|
||||
|
||||
static MsgSignalNotification* create(int inputSampleRate, qint64 centerFrequency, int streamIndex) {
|
||||
return new MsgSignalNotification(inputSampleRate, centerFrequency, streamIndex);
|
||||
}
|
||||
private:
|
||||
int m_inputSampleRate;
|
||||
qint64 m_centerFrequency;
|
||||
int m_streamIndex;
|
||||
|
||||
MsgSignalNotification(int inputSampleRate, qint64 centerFrequency, int streamIndex) :
|
||||
Message(),
|
||||
m_inputSampleRate(inputSampleRate),
|
||||
m_centerFrequency(centerFrequency),
|
||||
m_streamIndex(streamIndex)
|
||||
{ }
|
||||
};
|
||||
|
||||
InterferometerSink(int fftSize);
|
||||
~InterferometerSink();
|
||||
MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } //!< Get the queue for asynchronous inbound communication
|
||||
|
||||
@ -64,11 +107,13 @@ public:
|
||||
void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, unsigned int streamIndex);
|
||||
|
||||
private:
|
||||
void processFifo(const SampleVector::iterator& vbegin, const SampleVector::iterator& vend, unsigned int sinkIndex);
|
||||
void run();
|
||||
bool handleMessage(const Message& cmd);
|
||||
|
||||
InterferometerCorrelator m_correlator;
|
||||
SampleSinkVector m_sinkBuffers[2];
|
||||
//SampleSinkVector m_sinkBuffers[2];
|
||||
SampleSinkFifo m_sinkFifos[2];
|
||||
InterferometerStreamSink m_sinks[2];
|
||||
DownChannelizer *m_channelizers[2];
|
||||
BasebandSampleSink *m_spectrumSink;
|
||||
@ -76,7 +121,8 @@ private:
|
||||
MessageQueue m_inputMessageQueue; //!< Queue for asynchronous inbound communication
|
||||
|
||||
private slots:
|
||||
void handleSinkBuffer(unsigned int sinkIndex); //!< Handle data when samples have to be processed
|
||||
//void handleSinkBuffer(unsigned int sinkIndex); //!< Handle data when samples have to be processed
|
||||
void handleSinkFifo(unsigned int sinkIndex); //!< Handle data when samples have to be processed
|
||||
void handleInputMessages();
|
||||
};
|
||||
|
||||
|
||||
@ -24,6 +24,7 @@ InterferometerStreamSink::InterferometerStreamSink() :
|
||||
m_streamIndex(0),
|
||||
m_dataSize(0),
|
||||
m_bufferSize(0),
|
||||
m_dataStart(0),
|
||||
m_sampleRate(48000),
|
||||
m_settingsMutex(QMutex::Recursive)
|
||||
{}
|
||||
@ -42,8 +43,10 @@ void InterferometerStreamSink::feed(const SampleVector::const_iterator& begin, c
|
||||
m_settingsMutex.lock();
|
||||
m_dataSize = (end - begin) + m_dataStart;
|
||||
|
||||
if (m_dataSize > m_bufferSize) {
|
||||
if (m_dataSize > m_bufferSize)
|
||||
{
|
||||
m_data.resize(m_dataSize);
|
||||
m_bufferSize = m_dataSize;
|
||||
}
|
||||
|
||||
std::copy(begin, end, m_data.begin() + m_dataStart);
|
||||
@ -57,6 +60,7 @@ bool InterferometerStreamSink::handleMessage(const Message& cmd)
|
||||
DownChannelizer::MsgChannelizerNotification& notif = (DownChannelizer::MsgChannelizerNotification&) cmd;
|
||||
|
||||
qDebug() << "InterferometerStreamSink::handleMessage: MsgChannelizerNotification:"
|
||||
<< " streamIndex: " << m_streamIndex
|
||||
<< " inputSampleRate: " << notif.getSampleRate()
|
||||
<< " inputFrequencyOffset: " << notif.getFrequencyOffset();
|
||||
m_sampleRate = notif.getSampleRate();
|
||||
|
||||
@ -39,6 +39,7 @@ public:
|
||||
unsigned int getStreamIndex() const { return m_streamIndex; }
|
||||
void setStreamIndex(unsigned int streamIndex) { m_streamIndex = streamIndex; }
|
||||
SampleVector& getData() { return m_data; }
|
||||
int getSize() const { return m_dataSize; }
|
||||
void setDataStart(int dataStart) { m_dataStart = dataStart; }
|
||||
|
||||
private:
|
||||
|
||||
@ -454,6 +454,12 @@ void MainWindow::addMIMODevice()
|
||||
m_deviceUIs.back()->m_deviceAPI = deviceAPI;
|
||||
m_deviceUIs.back()->m_samplingDeviceControl->setPluginManager(m_pluginManager);
|
||||
QComboBox *channelSelector = m_deviceUIs.back()->m_samplingDeviceControl->getChannelSelector();
|
||||
// add MIMO channels
|
||||
QList<QString> mimoChannelNames;
|
||||
m_pluginManager->listMIMOChannels(mimoChannelNames);
|
||||
QStringList mimoChannelNamesList(mimoChannelNames);
|
||||
channelSelector->addItems(mimoChannelNamesList);
|
||||
m_deviceUIs.back()->setNumberOfAvailableMIMOChannels(mimoChannelNamesList.size());
|
||||
// Add Rx channels
|
||||
QList<QString> rxChannelNames;
|
||||
m_pluginManager->listRxChannels(rxChannelNames);
|
||||
@ -1952,18 +1958,22 @@ void MainWindow::channelAddClicked(bool checked)
|
||||
}
|
||||
else if (deviceUI->m_deviceMIMOEngine) // MIMO device => all possible channels. Depends on index range
|
||||
{
|
||||
int nbMIMOChannels = deviceUI->getNumberOfAvailableMIMOChannels();
|
||||
int nbRxChannels = deviceUI->getNumberOfAvailableRxChannels();
|
||||
int nbTxChannels = deviceUI->getNumberOfAvailableTxChannels();
|
||||
int selectedIndex = deviceUI->m_samplingDeviceControl->getChannelSelector()->currentIndex();
|
||||
qDebug("MainWindow::channelAddClicked: MIMO: tab: %d nbRx: %d nbTx: %d selected: %d",
|
||||
currentSourceTabIndex, nbRxChannels, nbTxChannels, selectedIndex);
|
||||
qDebug("MainWindow::channelAddClicked: MIMO: tab: %d nbMIMO: %d nbRx: %d nbTx: %d selected: %d",
|
||||
currentSourceTabIndex, nbMIMOChannels, nbRxChannels, nbTxChannels, selectedIndex);
|
||||
|
||||
if (selectedIndex < nbRxChannels) {
|
||||
m_pluginManager->createRxChannelInstance(
|
||||
if (selectedIndex < nbMIMOChannels) {
|
||||
m_pluginManager->createMIMOChannelInstance(
|
||||
selectedIndex, deviceUI, deviceUI->m_deviceAPI);
|
||||
} else if (selectedIndex < nbRxChannels + nbTxChannels) {
|
||||
} else if (selectedIndex < nbMIMOChannels + nbRxChannels) {
|
||||
m_pluginManager->createRxChannelInstance(
|
||||
selectedIndex - nbMIMOChannels, deviceUI, deviceUI->m_deviceAPI);
|
||||
} else if (selectedIndex < nbMIMOChannels + nbRxChannels + nbTxChannels) {
|
||||
m_pluginManager->createTxChannelInstance(
|
||||
selectedIndex - nbRxChannels, deviceUI, deviceUI->m_deviceAPI);
|
||||
selectedIndex - nbMIMOChannels - nbRxChannels, deviceUI, deviceUI->m_deviceAPI);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user