mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-26 17:58:43 -05:00
Removal of ChannelAnalyzer and TCPSrc plugins
This commit is contained in:
parent
c961fa368d
commit
111b3da5ce
@ -5,10 +5,8 @@ add_subdirectory(demodam)
|
||||
add_subdirectory(demodbfm)
|
||||
add_subdirectory(demodnfm)
|
||||
add_subdirectory(demodssb)
|
||||
add_subdirectory(tcpsrc)
|
||||
add_subdirectory(udpsrc)
|
||||
add_subdirectory(demodwfm)
|
||||
add_subdirectory(chanalyzer)
|
||||
add_subdirectory(chanalyzerng)
|
||||
add_subdirectory(demodatv)
|
||||
|
||||
|
@ -1,46 +0,0 @@
|
||||
project(chanalyzer)
|
||||
|
||||
set(chanalyzer_SOURCES
|
||||
chanalyzer.cpp
|
||||
chanalyzergui.cpp
|
||||
chanalyzerplugin.cpp
|
||||
)
|
||||
|
||||
set(chanalyzer_HEADERS
|
||||
chanalyzer.h
|
||||
chanalyzergui.h
|
||||
chanalyzerplugin.h
|
||||
)
|
||||
|
||||
set(chanalyzer_FORMS
|
||||
chanalyzergui.ui
|
||||
)
|
||||
|
||||
include_directories(
|
||||
.
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
#include(${QT_USE_FILE})
|
||||
add_definitions(${QT_DEFINITIONS})
|
||||
add_definitions(-DQT_PLUGIN)
|
||||
add_definitions(-DQT_SHARED)
|
||||
|
||||
#qt5_wrap_cpp(chanalyzer_HEADERS_MOC ${chanalyzer_HEADERS})
|
||||
qt5_wrap_ui(chanalyzer_FORMS_HEADERS ${chanalyzer_FORMS})
|
||||
|
||||
add_library(chanalyzer SHARED
|
||||
${chanalyzer_SOURCES}
|
||||
${chanalyzer_HEADERS_MOC}
|
||||
${chanalyzer_FORMS_HEADERS}
|
||||
)
|
||||
|
||||
target_link_libraries(chanalyzer
|
||||
${QT_LIBRARIES}
|
||||
sdrbase
|
||||
sdrgui
|
||||
)
|
||||
|
||||
qt5_use_modules(chanalyzer Core Widgets )
|
||||
|
||||
install(TARGETS chanalyzer DESTINATION lib/plugins/channelrx)
|
@ -1,242 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2015 Edouard Griffiths, F4EXB //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "chanalyzer.h"
|
||||
|
||||
#include <QTime>
|
||||
#include <QDebug>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <dsp/downchannelizer.h>
|
||||
#include "dsp/threadedbasebandsamplesink.h"
|
||||
#include "device/devicesourceapi.h"
|
||||
#include "audio/audiooutput.h"
|
||||
|
||||
MESSAGE_CLASS_DEFINITION(ChannelAnalyzer::MsgConfigureChannelAnalyzer, Message)
|
||||
MESSAGE_CLASS_DEFINITION(ChannelAnalyzer::MsgConfigureChannelizer, Message)
|
||||
MESSAGE_CLASS_DEFINITION(ChannelAnalyzer::MsgReportChannelSampleRateChanged, Message)
|
||||
|
||||
const QString ChannelAnalyzer::m_channelIdURI = "org.f4exb.sdrangelove.channel.chanalyzer";
|
||||
const QString ChannelAnalyzer::m_channelId = "ChannelAnalyzer";
|
||||
|
||||
ChannelAnalyzer::ChannelAnalyzer(DeviceSourceAPI *deviceAPI) :
|
||||
ChannelSinkAPI(m_channelIdURI),
|
||||
m_deviceAPI(deviceAPI),
|
||||
m_sampleSink(0),
|
||||
m_settingsMutex(QMutex::Recursive)
|
||||
{
|
||||
setObjectName(m_channelId);
|
||||
|
||||
m_Bandwidth = 5000;
|
||||
m_LowCutoff = 300;
|
||||
m_spanLog2 = 3;
|
||||
m_sampleRate = 96000;
|
||||
m_frequency = 0;
|
||||
m_nco.setFreq(m_frequency, m_sampleRate);
|
||||
m_undersampleCount = 0;
|
||||
m_sum = 0;
|
||||
m_usb = true;
|
||||
m_ssb = true;
|
||||
m_magsq = 0;
|
||||
SSBFilter = new fftfilt(m_LowCutoff / m_sampleRate, m_Bandwidth / m_sampleRate, ssbFftLen);
|
||||
DSBFilter = new fftfilt(m_Bandwidth / m_sampleRate, 2*ssbFftLen);
|
||||
|
||||
m_channelizer = new DownChannelizer(this);
|
||||
m_threadedChannelizer = new ThreadedBasebandSampleSink(m_channelizer, this);
|
||||
connect(m_channelizer, SIGNAL(inputSampleRateChanged()), this, SLOT(channelSampleRateChanged()));
|
||||
m_deviceAPI->addThreadedSink(m_threadedChannelizer);
|
||||
m_deviceAPI->addChannelAPI(this);
|
||||
}
|
||||
|
||||
ChannelAnalyzer::~ChannelAnalyzer()
|
||||
{
|
||||
m_deviceAPI->removeChannelAPI(this);
|
||||
m_deviceAPI->removeThreadedSink(m_threadedChannelizer);
|
||||
delete m_threadedChannelizer;
|
||||
delete m_channelizer;
|
||||
if (SSBFilter) delete SSBFilter;
|
||||
if (DSBFilter) delete DSBFilter;
|
||||
}
|
||||
|
||||
void ChannelAnalyzer::configure(MessageQueue* messageQueue,
|
||||
Real Bandwidth,
|
||||
Real LowCutoff,
|
||||
int spanLog2,
|
||||
bool ssb)
|
||||
{
|
||||
Message* cmd = MsgConfigureChannelAnalyzer::create(Bandwidth, LowCutoff, spanLog2, ssb);
|
||||
messageQueue->push(cmd);
|
||||
}
|
||||
|
||||
void ChannelAnalyzer::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly __attribute__((unused)))
|
||||
{
|
||||
fftfilt::cmplx *sideband;
|
||||
int n_out;
|
||||
int decim = 1<<m_spanLog2;
|
||||
unsigned char decim_mask = decim - 1; // counter LSB bit mask for decimation by 2^(m_scaleLog2 - 1)
|
||||
|
||||
m_settingsMutex.lock();
|
||||
|
||||
for(SampleVector::const_iterator it = begin; it < end; ++it)
|
||||
{
|
||||
Complex c(it->real(), it->imag());
|
||||
c *= m_nco.nextIQ();
|
||||
|
||||
if (m_ssb)
|
||||
{
|
||||
n_out = SSBFilter->runSSB(c, &sideband, m_usb);
|
||||
}
|
||||
else
|
||||
{
|
||||
n_out = DSBFilter->runDSB(c, &sideband);
|
||||
}
|
||||
|
||||
for (int i = 0; i < n_out; i++)
|
||||
{
|
||||
// Downsample by 2^(m_scaleLog2 - 1) for SSB band spectrum display
|
||||
// smart decimation with bit gain using float arithmetic (23 bits significand)
|
||||
|
||||
m_sum += sideband[i];
|
||||
|
||||
if (!(m_undersampleCount++ & decim_mask))
|
||||
{
|
||||
m_sum /= decim;
|
||||
Real re = m_sum.real() / SDR_RX_SCALED;
|
||||
Real im = m_sum.imag() / SDR_RX_SCALED;
|
||||
m_magsq = re*re + im*im;
|
||||
|
||||
if (m_ssb & !m_usb)
|
||||
{ // invert spectrum for LSB
|
||||
m_sampleBuffer.push_back(Sample(m_sum.imag(), m_sum.real()));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sampleBuffer.push_back(Sample(m_sum.real(), m_sum.imag()));
|
||||
}
|
||||
|
||||
m_sum = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(m_sampleSink != NULL)
|
||||
{
|
||||
m_sampleSink->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), m_ssb); // m_ssb = positive only
|
||||
}
|
||||
|
||||
m_sampleBuffer.clear();
|
||||
|
||||
m_settingsMutex.unlock();
|
||||
}
|
||||
|
||||
void ChannelAnalyzer::start()
|
||||
{
|
||||
}
|
||||
|
||||
void ChannelAnalyzer::stop()
|
||||
{
|
||||
}
|
||||
|
||||
void ChannelAnalyzer::channelSampleRateChanged()
|
||||
{
|
||||
MsgReportChannelSampleRateChanged *msg = MsgReportChannelSampleRateChanged::create();
|
||||
getMessageQueueToGUI()->push(msg);
|
||||
}
|
||||
|
||||
bool ChannelAnalyzer::handleMessage(const Message& cmd)
|
||||
{
|
||||
float band, lowCutoff;
|
||||
|
||||
qDebug() << "ChannelAnalyzer::handleMessage";
|
||||
|
||||
if (DownChannelizer::MsgChannelizerNotification::match(cmd))
|
||||
{
|
||||
DownChannelizer::MsgChannelizerNotification& notif = (DownChannelizer::MsgChannelizerNotification&) cmd;
|
||||
|
||||
m_sampleRate = notif.getSampleRate();
|
||||
m_nco.setFreq(-notif.getFrequencyOffset(), m_sampleRate);
|
||||
|
||||
qDebug() << "ChannelAnalyzer::handleMessage: MsgChannelizerNotification: m_sampleRate: " << m_sampleRate
|
||||
<< " frequencyOffset: " << notif.getFrequencyOffset();
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (MsgConfigureChannelizer::match(cmd))
|
||||
{
|
||||
MsgConfigureChannelizer& cfg = (MsgConfigureChannelizer&) cmd;
|
||||
|
||||
m_channelizer->configure(m_channelizer->getInputMessageQueue(),
|
||||
m_channelizer->getInputSampleRate(),
|
||||
cfg.getCenterFrequency());
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (MsgConfigureChannelAnalyzer::match(cmd))
|
||||
{
|
||||
MsgConfigureChannelAnalyzer& cfg = (MsgConfigureChannelAnalyzer&) cmd;
|
||||
|
||||
band = cfg.getBandwidth();
|
||||
lowCutoff = cfg.getLoCutoff();
|
||||
|
||||
if (band < 0)
|
||||
{
|
||||
band = -band;
|
||||
lowCutoff = -lowCutoff;
|
||||
m_usb = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_usb = true;
|
||||
}
|
||||
|
||||
if (band < 100.0f)
|
||||
{
|
||||
band = 100.0f;
|
||||
lowCutoff = 0;
|
||||
}
|
||||
|
||||
m_settingsMutex.lock();
|
||||
|
||||
m_Bandwidth = band;
|
||||
m_LowCutoff = lowCutoff;
|
||||
|
||||
SSBFilter->create_filter(m_LowCutoff / m_sampleRate, m_Bandwidth / m_sampleRate);
|
||||
DSBFilter->create_dsb_filter(m_Bandwidth / m_sampleRate);
|
||||
|
||||
m_spanLog2 = cfg.getSpanLog2();
|
||||
m_ssb = cfg.getSSB();
|
||||
|
||||
m_settingsMutex.unlock();
|
||||
|
||||
qDebug() << "ChannelAnalyzer::handleMessage: MsgConfigureChannelAnalyzer: m_Bandwidth: " << m_Bandwidth
|
||||
<< " m_LowCutoff: " << m_LowCutoff
|
||||
<< " m_spanLog2: " << m_spanLog2
|
||||
<< " m_ssb: " << m_ssb;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_sampleSink != 0)
|
||||
{
|
||||
return m_sampleSink->handleMessage(cmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,167 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2015 Edouard Griffiths, F4EXB //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INCLUDE_CHANALYZER_H
|
||||
#define INCLUDE_CHANALYZER_H
|
||||
|
||||
#include <QMutex>
|
||||
#include <vector>
|
||||
|
||||
#include "dsp/basebandsamplesink.h"
|
||||
#include "channel/channelsinkapi.h"
|
||||
#include "dsp/ncof.h"
|
||||
#include "dsp/fftfilt.h"
|
||||
#include "audio/audiofifo.h"
|
||||
#include "util/message.h"
|
||||
|
||||
#define ssbFftLen 1024
|
||||
|
||||
class DeviceSourceAPI;
|
||||
class ThreadedBasebandSampleSink;
|
||||
class DownChannelizer;
|
||||
|
||||
class ChannelAnalyzer : public BasebandSampleSink, public ChannelSinkAPI {
|
||||
public:
|
||||
class MsgConfigureChannelAnalyzer : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
Real getBandwidth() const { return m_Bandwidth; }
|
||||
Real getLoCutoff() const { return m_LowCutoff; }
|
||||
int getSpanLog2() const { return m_spanLog2; }
|
||||
bool getSSB() const { return m_ssb; }
|
||||
|
||||
static MsgConfigureChannelAnalyzer* create(Real Bandwidth,
|
||||
Real LowCutoff,
|
||||
int spanLog2,
|
||||
bool ssb)
|
||||
{
|
||||
return new MsgConfigureChannelAnalyzer(Bandwidth, LowCutoff, spanLog2, ssb);
|
||||
}
|
||||
|
||||
private:
|
||||
Real m_Bandwidth;
|
||||
Real m_LowCutoff;
|
||||
int m_spanLog2;
|
||||
bool m_ssb;
|
||||
|
||||
MsgConfigureChannelAnalyzer(Real Bandwidth,
|
||||
Real LowCutoff,
|
||||
int spanLog2,
|
||||
bool ssb) :
|
||||
Message(),
|
||||
m_Bandwidth(Bandwidth),
|
||||
m_LowCutoff(LowCutoff),
|
||||
m_spanLog2(spanLog2),
|
||||
m_ssb(ssb)
|
||||
{ }
|
||||
};
|
||||
|
||||
class MsgConfigureChannelizer : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
int getCenterFrequency() const { return m_centerFrequency; }
|
||||
|
||||
static MsgConfigureChannelizer* create(int centerFrequency)
|
||||
{
|
||||
return new MsgConfigureChannelizer(centerFrequency);
|
||||
}
|
||||
|
||||
private:
|
||||
int m_centerFrequency;
|
||||
|
||||
MsgConfigureChannelizer(int centerFrequency) :
|
||||
Message(),
|
||||
m_centerFrequency(centerFrequency)
|
||||
{ }
|
||||
};
|
||||
|
||||
class MsgReportChannelSampleRateChanged : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
|
||||
static MsgReportChannelSampleRateChanged* create()
|
||||
{
|
||||
return new MsgReportChannelSampleRateChanged();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
MsgReportChannelSampleRateChanged() :
|
||||
Message()
|
||||
{ }
|
||||
};
|
||||
|
||||
ChannelAnalyzer(DeviceSourceAPI *deviceAPI);
|
||||
virtual ~ChannelAnalyzer();
|
||||
virtual void destroy() { delete this; }
|
||||
void setSampleSink(BasebandSampleSink* sampleSink) { m_sampleSink = sampleSink; }
|
||||
|
||||
void configure(MessageQueue* messageQueue,
|
||||
Real Bandwidth,
|
||||
Real LowCutoff,
|
||||
int spanLog2,
|
||||
bool ssb);
|
||||
|
||||
int getSampleRate() const { return m_sampleRate; }
|
||||
Real getMagSq() const { return m_magsq; }
|
||||
|
||||
virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly);
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual bool handleMessage(const Message& cmd);
|
||||
|
||||
virtual void getIdentifier(QString& id) { id = objectName(); }
|
||||
virtual void getTitle(QString& title) { title = objectName(); }
|
||||
virtual qint64 getCenterFrequency() const { return m_frequency; }
|
||||
|
||||
virtual QByteArray serialize() const { return QByteArray(); }
|
||||
virtual bool deserialize(const QByteArray& data __attribute__((unused))) { return false; }
|
||||
|
||||
static const QString m_channelIdURI;
|
||||
static const QString m_channelId;
|
||||
|
||||
private slots:
|
||||
void channelSampleRateChanged();
|
||||
|
||||
private:
|
||||
DeviceSourceAPI *m_deviceAPI;
|
||||
ThreadedBasebandSampleSink* m_threadedChannelizer;
|
||||
DownChannelizer* m_channelizer;
|
||||
|
||||
Real m_Bandwidth;
|
||||
Real m_LowCutoff;
|
||||
int m_spanLog2;
|
||||
int m_undersampleCount;
|
||||
fftfilt::cmplx m_sum;
|
||||
int m_sampleRate;
|
||||
int m_frequency;
|
||||
bool m_usb;
|
||||
bool m_ssb;
|
||||
Real m_magsq;
|
||||
|
||||
NCOF m_nco;
|
||||
fftfilt* SSBFilter;
|
||||
fftfilt* DSBFilter;
|
||||
|
||||
BasebandSampleSink* m_sampleSink;
|
||||
SampleVector m_sampleBuffer;
|
||||
QMutex m_settingsMutex;
|
||||
};
|
||||
|
||||
#endif // INCLUDE_CHANALYZER_H
|
@ -1,46 +0,0 @@
|
||||
#--------------------------------------------------------
|
||||
#
|
||||
# Pro file for Android and Windows builds with Qt Creator
|
||||
#
|
||||
#--------------------------------------------------------
|
||||
|
||||
TEMPLATE = lib
|
||||
CONFIG += plugin
|
||||
|
||||
QT += core gui widgets multimedia opengl
|
||||
|
||||
TARGET = chanalyzer
|
||||
|
||||
DEFINES += USE_SSE2=1
|
||||
QMAKE_CXXFLAGS += -msse2
|
||||
DEFINES += USE_SSE4_1=1
|
||||
QMAKE_CXXFLAGS += -msse4.1
|
||||
QMAKE_CXXFLAGS += -std=c++11
|
||||
|
||||
INCLUDEPATH += $$PWD
|
||||
INCLUDEPATH += ../../../exports
|
||||
INCLUDEPATH += ../../../sdrbase
|
||||
INCLUDEPATH += ../../../sdrgui
|
||||
|
||||
CONFIG(ANDROID):INCLUDEPATH += /opt/softs/boost_1_60_0
|
||||
CONFIG(MINGW32):INCLUDEPATH += "D:\boost_1_58_0"
|
||||
CONFIG(MINGW64):INCLUDEPATH += "D:\boost_1_58_0"
|
||||
CONFIG(macx):INCLUDEPATH += "../../../../../boost_1_64_0"
|
||||
|
||||
CONFIG(Release):build_subdir = release
|
||||
CONFIG(Debug):build_subdir = debug
|
||||
|
||||
SOURCES += chanalyzer.cpp\
|
||||
chanalyzergui.cpp\
|
||||
chanalyzerplugin.cpp
|
||||
|
||||
HEADERS += chanalyzer.h\
|
||||
chanalyzergui.h\
|
||||
chanalyzerplugin.h
|
||||
|
||||
FORMS += chanalyzergui.ui
|
||||
|
||||
LIBS += -L../../../sdrbase/$${build_subdir} -lsdrbase
|
||||
LIBS += -L../../../sdrgui/$${build_subdir} -lsdrgui
|
||||
|
||||
RESOURCES = ../../../sdrgui/resources/res.qrc
|
@ -1,487 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2015 Edouard Griffiths, F4EXB //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "chanalyzergui.h"
|
||||
|
||||
#include <device/devicesourceapi.h>
|
||||
#include "device/deviceuiset.h"
|
||||
#include <dsp/downchannelizer.h>
|
||||
#include <QDockWidget>
|
||||
#include <QMainWindow>
|
||||
|
||||
#include "dsp/threadedbasebandsamplesink.h"
|
||||
#include "ui_chanalyzergui.h"
|
||||
#include "dsp/spectrumscopecombovis.h"
|
||||
#include "dsp/spectrumvis.h"
|
||||
#include "dsp/scopevis.h"
|
||||
#include "gui/glspectrum.h"
|
||||
#include "gui/glscope.h"
|
||||
#include "plugin/pluginapi.h"
|
||||
#include "util/simpleserializer.h"
|
||||
#include "util/db.h"
|
||||
#include "dsp/dspengine.h"
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include "chanalyzer.h"
|
||||
|
||||
ChannelAnalyzerGUI* ChannelAnalyzerGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel)
|
||||
{
|
||||
ChannelAnalyzerGUI* gui = new ChannelAnalyzerGUI(pluginAPI, deviceUISet, rxChannel);
|
||||
return gui;
|
||||
}
|
||||
|
||||
void ChannelAnalyzerGUI::destroy()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
void ChannelAnalyzerGUI::setName(const QString& name)
|
||||
{
|
||||
setObjectName(name);
|
||||
}
|
||||
|
||||
QString ChannelAnalyzerGUI::getName() const
|
||||
{
|
||||
return objectName();
|
||||
}
|
||||
|
||||
qint64 ChannelAnalyzerGUI::getCenterFrequency() const
|
||||
{
|
||||
return m_channelMarker.getCenterFrequency();
|
||||
}
|
||||
|
||||
void ChannelAnalyzerGUI::setCenterFrequency(qint64 centerFrequency)
|
||||
{
|
||||
m_channelMarker.setCenterFrequency(centerFrequency);
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void ChannelAnalyzerGUI::resetToDefaults()
|
||||
{
|
||||
blockApplySettings(true);
|
||||
|
||||
ui->BW->setValue(30);
|
||||
ui->deltaFrequency->setValue(0);
|
||||
ui->spanLog2->setValue(3);
|
||||
|
||||
blockApplySettings(false);
|
||||
applySettings();
|
||||
}
|
||||
|
||||
QByteArray ChannelAnalyzerGUI::serialize() const
|
||||
{
|
||||
SimpleSerializer s(1);
|
||||
s.writeS32(1, m_channelMarker.getCenterFrequency());
|
||||
s.writeS32(2, ui->BW->value());
|
||||
s.writeBlob(3, ui->spectrumGUI->serialize());
|
||||
s.writeU32(4, m_channelMarker.getColor().rgb());
|
||||
s.writeS32(5, ui->lowCut->value());
|
||||
s.writeS32(6, ui->spanLog2->value());
|
||||
s.writeBool(7, ui->ssb->isChecked());
|
||||
s.writeBlob(8, ui->scopeGUI->serialize());
|
||||
|
||||
return s.final();
|
||||
}
|
||||
|
||||
bool ChannelAnalyzerGUI::deserialize(const QByteArray& data)
|
||||
{
|
||||
SimpleDeserializer d(data);
|
||||
|
||||
if(!d.isValid())
|
||||
{
|
||||
resetToDefaults();
|
||||
return false;
|
||||
}
|
||||
|
||||
if(d.getVersion() == 1)
|
||||
{
|
||||
QByteArray bytetmp;
|
||||
quint32 u32tmp;
|
||||
qint32 tmp, bw, lowCut;
|
||||
bool tmpBool;
|
||||
|
||||
blockApplySettings(true);
|
||||
m_channelMarker.blockSignals(true);
|
||||
|
||||
d.readS32(1, &tmp, 0);
|
||||
m_channelMarker.setCenterFrequency(tmp);
|
||||
d.readS32(2, &bw, 30);
|
||||
ui->BW->setValue(bw);
|
||||
d.readBlob(3, &bytetmp);
|
||||
ui->spectrumGUI->deserialize(bytetmp);
|
||||
|
||||
if(d.readU32(4, &u32tmp))
|
||||
{
|
||||
m_channelMarker.setColor(u32tmp);
|
||||
}
|
||||
|
||||
d.readS32(5, &lowCut, 3);
|
||||
ui->lowCut->setValue(lowCut);
|
||||
d.readS32(6, &tmp, 20);
|
||||
ui->spanLog2->setValue(tmp);
|
||||
setNewRate(tmp);
|
||||
d.readBool(7, &tmpBool, false);
|
||||
ui->ssb->setChecked(tmpBool);
|
||||
d.readBlob(8, &bytetmp);
|
||||
ui->scopeGUI->deserialize(bytetmp);
|
||||
|
||||
blockApplySettings(false);
|
||||
m_channelMarker.blockSignals(false);
|
||||
m_channelMarker.emitChangedByAPI();
|
||||
|
||||
ui->BW->setValue(bw);
|
||||
ui->lowCut->setValue(lowCut); // does applySettings();
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
resetToDefaults();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ChannelAnalyzerGUI::handleMessage(const Message& message)
|
||||
{
|
||||
if (ChannelAnalyzer::MsgReportChannelSampleRateChanged::match(message))
|
||||
{
|
||||
setNewRate(m_spanLog2);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ChannelAnalyzerGUI::handleInputMessages()
|
||||
{
|
||||
Message* message;
|
||||
|
||||
while ((message = getInputMessageQueue()->pop()) != 0)
|
||||
{
|
||||
qDebug("ChannelAnalyzerGUI::handleInputMessages: message: %s", message->getIdentifier());
|
||||
|
||||
if (handleMessage(*message))
|
||||
{
|
||||
delete message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ChannelAnalyzerGUI::channelMarkerChangedByCursor()
|
||||
{
|
||||
ui->deltaFrequency->setValue(abs(m_channelMarker.getCenterFrequency()));
|
||||
ui->deltaMinus->setChecked(m_channelMarker.getCenterFrequency() < 0);
|
||||
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void ChannelAnalyzerGUI::channelMarkerHighlightedByCursor()
|
||||
{
|
||||
setHighlighted(m_channelMarker.getHighlighted());
|
||||
}
|
||||
|
||||
void ChannelAnalyzerGUI::tick()
|
||||
{
|
||||
Real powDb = CalcDb::dbPower(m_channelAnalyzer->getMagSq());
|
||||
m_channelPowerDbAvg(powDb);
|
||||
ui->channelPower->setText(QString::number((Real) m_channelPowerDbAvg, 'f', 1));
|
||||
}
|
||||
|
||||
void ChannelAnalyzerGUI::on_deltaMinus_toggled(bool minus)
|
||||
{
|
||||
int deltaFrequency = m_channelMarker.getCenterFrequency();
|
||||
bool minusDelta = (deltaFrequency < 0);
|
||||
|
||||
if (minus ^ minusDelta) // sign change
|
||||
{
|
||||
m_channelMarker.setCenterFrequency(-deltaFrequency);
|
||||
}
|
||||
}
|
||||
|
||||
void ChannelAnalyzerGUI::on_deltaFrequency_changed(quint64 value)
|
||||
{
|
||||
if (ui->deltaMinus->isChecked()) {
|
||||
m_channelMarker.setCenterFrequency(-value);
|
||||
} else {
|
||||
m_channelMarker.setCenterFrequency(value);
|
||||
}
|
||||
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void ChannelAnalyzerGUI::on_BW_valueChanged(int value)
|
||||
{
|
||||
QString s = QString::number(value/10.0, 'f', 1);
|
||||
ui->BWText->setText(tr("%1k").arg(s));
|
||||
m_channelMarker.setBandwidth(value * 100 * 2);
|
||||
|
||||
if (ui->ssb->isChecked())
|
||||
{
|
||||
if (value < 0) {
|
||||
m_channelMarker.setSidebands(ChannelMarker::lsb);
|
||||
} else {
|
||||
m_channelMarker.setSidebands(ChannelMarker::usb);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_channelMarker.setSidebands(ChannelMarker::dsb);
|
||||
}
|
||||
|
||||
on_lowCut_valueChanged(m_channelMarker.getLowCutoff()/100);
|
||||
}
|
||||
|
||||
int ChannelAnalyzerGUI::getEffectiveLowCutoff(int lowCutoff)
|
||||
{
|
||||
int ssbBW = m_channelMarker.getBandwidth() / 2;
|
||||
int effectiveLowCutoff = lowCutoff;
|
||||
const int guard = 100;
|
||||
|
||||
if (ssbBW < 0) {
|
||||
if (effectiveLowCutoff < ssbBW + guard) {
|
||||
effectiveLowCutoff = ssbBW + guard;
|
||||
}
|
||||
if (effectiveLowCutoff > 0) {
|
||||
effectiveLowCutoff = 0;
|
||||
}
|
||||
} else {
|
||||
if (effectiveLowCutoff > ssbBW - guard) {
|
||||
effectiveLowCutoff = ssbBW - guard;
|
||||
}
|
||||
if (effectiveLowCutoff < 0) {
|
||||
effectiveLowCutoff = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return effectiveLowCutoff;
|
||||
}
|
||||
|
||||
void ChannelAnalyzerGUI::on_lowCut_valueChanged(int value)
|
||||
{
|
||||
int lowCutoff = getEffectiveLowCutoff(value * 100);
|
||||
m_channelMarker.setLowCutoff(lowCutoff);
|
||||
QString s = QString::number(lowCutoff/1000.0, 'f', 1);
|
||||
ui->lowCutText->setText(tr("%1k").arg(s));
|
||||
ui->lowCut->setValue(lowCutoff/100);
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void ChannelAnalyzerGUI::on_spanLog2_valueChanged(int value)
|
||||
{
|
||||
if (setNewRate(value)) {
|
||||
applySettings();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ChannelAnalyzerGUI::on_ssb_toggled(bool checked)
|
||||
{
|
||||
if (checked)
|
||||
{
|
||||
if (ui->BW->value() < 0) {
|
||||
m_channelMarker.setSidebands(ChannelMarker::lsb);
|
||||
} else {
|
||||
m_channelMarker.setSidebands(ChannelMarker::usb);
|
||||
}
|
||||
|
||||
ui->glSpectrum->setCenterFrequency(m_rate/4);
|
||||
ui->glSpectrum->setSampleRate(m_rate/2);
|
||||
ui->glSpectrum->setSsbSpectrum(true);
|
||||
|
||||
on_lowCut_valueChanged(m_channelMarker.getLowCutoff()/100);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_channelMarker.setSidebands(ChannelMarker::dsb);
|
||||
|
||||
ui->glSpectrum->setCenterFrequency(0);
|
||||
ui->glSpectrum->setSampleRate(m_rate);
|
||||
ui->glSpectrum->setSsbSpectrum(false);
|
||||
|
||||
applySettings();
|
||||
}
|
||||
}
|
||||
|
||||
void ChannelAnalyzerGUI::onWidgetRolled(QWidget* widget __attribute__((unused)), bool rollDown __attribute__((unused)))
|
||||
{
|
||||
/*
|
||||
if((widget == ui->spectrumContainer) && (m_ssbDemod != NULL))
|
||||
m_ssbDemod->setSpectrum(m_threadedSampleSink->getMessageQueue(), rollDown);
|
||||
*/
|
||||
}
|
||||
|
||||
ChannelAnalyzerGUI::ChannelAnalyzerGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget* parent) :
|
||||
RollupWidget(parent),
|
||||
ui(new Ui::ChannelAnalyzerGUI),
|
||||
m_pluginAPI(pluginAPI),
|
||||
m_deviceUISet(deviceUISet),
|
||||
m_channelMarker(this),
|
||||
m_doApplySettings(true),
|
||||
m_rate(6000),
|
||||
m_spanLog2(3)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool)));
|
||||
|
||||
m_spectrumVis = new SpectrumVis(SDR_RX_SCALEF, ui->glSpectrum);
|
||||
m_scopeVis = new ScopeVis(SDR_RX_SCALEF, ui->glScope);
|
||||
m_spectrumScopeComboVis = new SpectrumScopeComboVis(m_spectrumVis, m_scopeVis);
|
||||
m_channelAnalyzer = (ChannelAnalyzer*) rxChannel; //new ChannelAnalyzer(m_deviceUISet->m_deviceSourceAPI);
|
||||
m_channelAnalyzer->setSampleSink(m_spectrumScopeComboVis);
|
||||
m_channelAnalyzer->setMessageQueueToGUI(getInputMessageQueue());
|
||||
|
||||
ui->deltaFrequency->setColorMapper(ColorMapper(ColorMapper::ReverseGold));
|
||||
ui->deltaFrequency->setValueRange(7, 0U, 9999999U);
|
||||
|
||||
ui->glSpectrum->setCenterFrequency(m_rate/2);
|
||||
ui->glSpectrum->setSampleRate(m_rate);
|
||||
ui->glSpectrum->setDisplayWaterfall(true);
|
||||
ui->glSpectrum->setDisplayMaxHold(true);
|
||||
ui->glSpectrum->setSsbSpectrum(true);
|
||||
|
||||
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.setColor(Qt::gray);
|
||||
m_channelMarker.setBandwidth(m_rate);
|
||||
m_channelMarker.setSidebands(ChannelMarker::usb);
|
||||
m_channelMarker.setCenterFrequency(0);
|
||||
m_channelMarker.blockSignals(false);
|
||||
m_channelMarker.setVisible(true); // activate signal on the last setting only
|
||||
setTitleColor(m_channelMarker.getColor());
|
||||
|
||||
m_deviceUISet->registerRxChannelInstance(ChannelAnalyzer::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);
|
||||
|
||||
connect(&m_channelMarker, SIGNAL(changedByCursor()), this, SLOT(channelMarkerChangedByCursor()));
|
||||
connect(&m_channelMarker, SIGNAL(highlightedByCursor()), this, SLOT(channelMarkerHighlightedByCursor()));
|
||||
connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
|
||||
|
||||
applySettings();
|
||||
setNewRate(m_spanLog2);
|
||||
}
|
||||
|
||||
ChannelAnalyzerGUI::~ChannelAnalyzerGUI()
|
||||
{
|
||||
m_deviceUISet->removeRxChannelInstance(this);
|
||||
delete m_channelAnalyzer; // TODO: check this: when the GUI closes it has to delete the demodulator
|
||||
delete m_spectrumVis;
|
||||
delete m_scopeVis;
|
||||
delete m_spectrumScopeComboVis;
|
||||
delete ui;
|
||||
}
|
||||
|
||||
bool ChannelAnalyzerGUI::setNewRate(int spanLog2)
|
||||
{
|
||||
qDebug("ChannelAnalyzerGUI::setNewRate");
|
||||
|
||||
if ((spanLog2 < 0) || (spanLog2 > 6)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_spanLog2 = spanLog2;
|
||||
m_rate = m_channelAnalyzer->getSampleRate() / (1<<spanLog2);
|
||||
|
||||
if (ui->BW->value() < -m_rate/200) {
|
||||
ui->BW->setValue(-m_rate/200);
|
||||
m_channelMarker.setBandwidth(-m_rate*2);
|
||||
} else if (ui->BW->value() > m_rate/200) {
|
||||
ui->BW->setValue(m_rate/200);
|
||||
m_channelMarker.setBandwidth(m_rate*2);
|
||||
}
|
||||
|
||||
if (ui->lowCut->value() < -m_rate/200) {
|
||||
ui->lowCut->setValue(-m_rate/200);
|
||||
m_channelMarker.setLowCutoff(-m_rate);
|
||||
} else if (ui->lowCut->value() > m_rate/200) {
|
||||
ui->lowCut->setValue(m_rate/200);
|
||||
m_channelMarker.setLowCutoff(m_rate);
|
||||
}
|
||||
|
||||
ui->BW->setMinimum(-m_rate/200);
|
||||
ui->lowCut->setMinimum(-m_rate/200);
|
||||
ui->BW->setMaximum(m_rate/200);
|
||||
ui->lowCut->setMaximum(m_rate/200);
|
||||
|
||||
QString s = QString::number(m_rate/1000.0, 'f', 1);
|
||||
ui->spanText->setText(tr("%1k").arg(s));
|
||||
|
||||
if (ui->ssb->isChecked())
|
||||
{
|
||||
if (ui->BW->value() < 0) {
|
||||
m_channelMarker.setSidebands(ChannelMarker::lsb);
|
||||
} else {
|
||||
m_channelMarker.setSidebands(ChannelMarker::usb);
|
||||
}
|
||||
|
||||
ui->glSpectrum->setCenterFrequency(m_rate/4);
|
||||
ui->glSpectrum->setSampleRate(m_rate/2);
|
||||
ui->glSpectrum->setSsbSpectrum(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_channelMarker.setSidebands(ChannelMarker::dsb);
|
||||
|
||||
ui->glSpectrum->setCenterFrequency(0);
|
||||
ui->glSpectrum->setSampleRate(m_rate);
|
||||
ui->glSpectrum->setSsbSpectrum(false);
|
||||
}
|
||||
|
||||
ui->glScope->setSampleRate(m_rate);
|
||||
m_scopeVis->setSampleRate(m_rate);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ChannelAnalyzerGUI::blockApplySettings(bool block)
|
||||
{
|
||||
ui->glScope->blockSignals(block);
|
||||
ui->glSpectrum->blockSignals(block);
|
||||
m_doApplySettings = !block;
|
||||
}
|
||||
|
||||
void ChannelAnalyzerGUI::applySettings()
|
||||
{
|
||||
if (m_doApplySettings)
|
||||
{
|
||||
ChannelAnalyzer::MsgConfigureChannelizer *msg = ChannelAnalyzer::MsgConfigureChannelizer::create(m_channelMarker.getCenterFrequency());
|
||||
m_channelAnalyzer->getInputMessageQueue()->push(msg);
|
||||
|
||||
m_channelAnalyzer->configure(m_channelAnalyzer->getInputMessageQueue(),
|
||||
ui->BW->value() * 100.0,
|
||||
ui->lowCut->value() * 100.0,
|
||||
m_spanLog2,
|
||||
ui->ssb->isChecked());
|
||||
}
|
||||
}
|
||||
|
||||
void ChannelAnalyzerGUI::leaveEvent(QEvent*)
|
||||
{
|
||||
m_channelMarker.setHighlighted(false);
|
||||
}
|
||||
|
||||
void ChannelAnalyzerGUI::enterEvent(QEvent*)
|
||||
{
|
||||
m_channelMarker.setHighlighted(true);
|
||||
}
|
||||
|
@ -1,101 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2015 Edouard Griffiths, F4EXB //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INCLUDE_CHANNELANALYZERGUI_H
|
||||
#define INCLUDE_CHANNELANALYZERGUI_H
|
||||
|
||||
#include <plugin/plugininstancegui.h>
|
||||
#include "gui/rollupwidget.h"
|
||||
#include "dsp/channelmarker.h"
|
||||
#include "dsp/dsptypes.h"
|
||||
#include "util/movingaverage.h"
|
||||
#include "util/messagequeue.h"
|
||||
|
||||
class PluginAPI;
|
||||
class DeviceUISet;
|
||||
class BasebandSampleSink;
|
||||
class ChannelAnalyzer;
|
||||
class SpectrumScopeComboVis;
|
||||
class SpectrumVis;
|
||||
class ScopeVis;
|
||||
|
||||
namespace Ui {
|
||||
class ChannelAnalyzerGUI;
|
||||
}
|
||||
|
||||
class ChannelAnalyzerGUI : public RollupWidget, public PluginInstanceGUI {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static ChannelAnalyzerGUI* create(PluginAPI* pluginAPI, DeviceUISet *deviceUIset, BasebandSampleSink *rxChannel);
|
||||
virtual void destroy();
|
||||
|
||||
void setName(const QString& name);
|
||||
QString getName() const;
|
||||
virtual qint64 getCenterFrequency() const;
|
||||
virtual void setCenterFrequency(qint64 centerFrequency);
|
||||
|
||||
void resetToDefaults();
|
||||
QByteArray serialize() const;
|
||||
bool deserialize(const QByteArray& data);
|
||||
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
|
||||
virtual bool handleMessage(const Message& message);
|
||||
|
||||
public slots:
|
||||
void channelMarkerChangedByCursor();
|
||||
void channelMarkerHighlightedByCursor();
|
||||
|
||||
private:
|
||||
Ui::ChannelAnalyzerGUI* ui;
|
||||
PluginAPI* m_pluginAPI;
|
||||
DeviceUISet* m_deviceUISet;
|
||||
ChannelMarker m_channelMarker;
|
||||
bool m_doApplySettings;
|
||||
int m_rate;
|
||||
int m_spanLog2;
|
||||
MovingAverageUtil<Real, double, 40> m_channelPowerDbAvg;
|
||||
|
||||
ChannelAnalyzer* m_channelAnalyzer;
|
||||
SpectrumScopeComboVis* m_spectrumScopeComboVis;
|
||||
SpectrumVis* m_spectrumVis;
|
||||
ScopeVis* m_scopeVis;
|
||||
MessageQueue m_inputMessageQueue;
|
||||
|
||||
explicit ChannelAnalyzerGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget* parent = 0);
|
||||
virtual ~ChannelAnalyzerGUI();
|
||||
|
||||
int getEffectiveLowCutoff(int lowCutoff);
|
||||
bool setNewRate(int spanLog2);
|
||||
|
||||
void blockApplySettings(bool block);
|
||||
void applySettings();
|
||||
|
||||
void leaveEvent(QEvent*);
|
||||
void enterEvent(QEvent*);
|
||||
|
||||
private slots:
|
||||
void on_deltaFrequency_changed(quint64 value);
|
||||
void on_deltaMinus_toggled(bool minus);
|
||||
void on_BW_valueChanged(int value);
|
||||
void on_lowCut_valueChanged(int value);
|
||||
void on_spanLog2_valueChanged(int value);
|
||||
void on_ssb_toggled(bool checked);
|
||||
void onWidgetRolled(QWidget* widget, bool rollDown);
|
||||
void handleInputMessages();
|
||||
void tick();
|
||||
};
|
||||
|
||||
#endif // INCLUDE_CHANNELANALYZERGUI_H
|
@ -1,540 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ChannelAnalyzerGUI</class>
|
||||
<widget class="RollupWidget" name="ChannelAnalyzerGUI">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>640</width>
|
||||
<height>814</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>640</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Liberation Sans</family>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Channel Analyzer</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="settingsContainer" native="true">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>10</y>
|
||||
<width>301</width>
|
||||
<height>131</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Settings</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="DeltaFreqPowLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="DeltaFrequencyLayout">
|
||||
<item>
|
||||
<widget class="QToolButton" name="deltaMinus">
|
||||
<property name="toolTip">
|
||||
<string>Frequency shift direction</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<selectedoff>:/plus.png</selectedoff>
|
||||
<selectedon>:/minus.png</selectedon>
|
||||
</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ValueDial" name="deltaFrequency" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Monospace</family>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>SizeVerCursor</cursorShape>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Demod shift frequency from center in Hz</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="deltaUnits">
|
||||
<property name="palette">
|
||||
<palette>
|
||||
<active>
|
||||
<colorrole role="Text">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>26</red>
|
||||
<green>26</green>
|
||||
<blue>26</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
<colorrole role="BrightText">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>255</red>
|
||||
<green>255</green>
|
||||
<blue>255</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</active>
|
||||
<inactive>
|
||||
<colorrole role="Text">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>26</red>
|
||||
<green>26</green>
|
||||
<blue>26</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
<colorrole role="BrightText">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>255</red>
|
||||
<green>255</green>
|
||||
<blue>255</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</inactive>
|
||||
<disabled>
|
||||
<colorrole role="Text">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>118</red>
|
||||
<green>118</green>
|
||||
<blue>117</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
<colorrole role="BrightText">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>255</red>
|
||||
<green>255</green>
|
||||
<blue>255</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</disabled>
|
||||
</palette>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string> Hz</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="ChannelPowerLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="channelPower">
|
||||
<property name="toolTip">
|
||||
<string>Channel power</string>
|
||||
</property>
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::LeftToRight</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>0.0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="channelPowerUnits">
|
||||
<property name="text">
|
||||
<string> dB</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="SpanLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="spanLabel">
|
||||
<property name="text">
|
||||
<string>Rate</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="spanLog2">
|
||||
<property name="toolTip">
|
||||
<string>Channel sample rate</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="sliderPosition">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="invertedAppearance">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="invertedControls">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="spanText">
|
||||
<property name="text">
|
||||
<string>6.0k</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="ssb">
|
||||
<property name="toolTip">
|
||||
<string>SSB/DSB toggle</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>SSB</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="BWLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="BWLabel">
|
||||
<property name="text">
|
||||
<string>BW</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>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="LowCutLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="lowCutLabel">
|
||||
<property name="text">
|
||||
<string>Low cut.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="lowCut">
|
||||
<property name="toolTip">
|
||||
<string>Highpass filter cutoff frequency (SSB)</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>3</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lowCutText">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>0.3k</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">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>180</y>
|
||||
<width>636</width>
|
||||
<height>284</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>636</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Channel Spectrum</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayoutSpectrum">
|
||||
<property name="spacing">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="GLSpectrum" name="glSpectrum" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>250</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Monospace</family>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="GLSpectrumGUI" name="spectrumGUI" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="scopeContainer" native="true">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>470</y>
|
||||
<width>636</width>
|
||||
<height>284</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>636</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Channel Scope</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayoutScope">
|
||||
<property name="spacing">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="GLScope" name="glScope" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>250</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Monospace</family>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="GLScopeGUI" name="scopeGUI" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>RollupWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>gui/rollupwidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ValueDial</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>gui/valuedial.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>GLSpectrum</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>gui/glspectrum.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>GLSpectrumGUI</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>gui/glspectrumgui.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>GLScope</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>gui/glscope.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>GLScopeGUI</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>gui/glscopegui.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../../../sdrgui/resources/res.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
@ -1,50 +0,0 @@
|
||||
#include "chanalyzerplugin.h"
|
||||
|
||||
#include <QtPlugin>
|
||||
#include "plugin/pluginapi.h"
|
||||
|
||||
#include "chanalyzergui.h"
|
||||
#include "chanalyzer.h"
|
||||
|
||||
const PluginDescriptor ChannelAnalyzerPlugin::m_pluginDescriptor = {
|
||||
QString("Channel Analyzer"),
|
||||
QString("3.14.5"),
|
||||
QString("(c) Edouard Griffiths, F4EXB"),
|
||||
QString("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
QString("https://github.com/f4exb/sdrangel")
|
||||
};
|
||||
|
||||
ChannelAnalyzerPlugin::ChannelAnalyzerPlugin(QObject* parent) :
|
||||
QObject(parent),
|
||||
m_pluginAPI(0)
|
||||
{
|
||||
}
|
||||
|
||||
const PluginDescriptor& ChannelAnalyzerPlugin::getPluginDescriptor() const
|
||||
{
|
||||
return m_pluginDescriptor;
|
||||
}
|
||||
|
||||
void ChannelAnalyzerPlugin::initPlugin(PluginAPI* pluginAPI)
|
||||
{
|
||||
m_pluginAPI = pluginAPI;
|
||||
|
||||
// register demodulator
|
||||
m_pluginAPI->registerRxChannel(ChannelAnalyzer::m_channelIdURI, ChannelAnalyzer::m_channelId, this);
|
||||
}
|
||||
|
||||
PluginInstanceGUI* ChannelAnalyzerPlugin::createRxChannelGUI(DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel)
|
||||
{
|
||||
return ChannelAnalyzerGUI::create(m_pluginAPI, deviceUISet, rxChannel);
|
||||
}
|
||||
|
||||
BasebandSampleSink* ChannelAnalyzerPlugin::createRxChannelBS(DeviceSourceAPI *deviceAPI)
|
||||
{
|
||||
return new ChannelAnalyzer(deviceAPI);
|
||||
}
|
||||
|
||||
ChannelSinkAPI* ChannelAnalyzerPlugin::createRxChannelCS(DeviceSourceAPI *deviceAPI)
|
||||
{
|
||||
return new ChannelAnalyzer(deviceAPI);
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
#ifndef INCLUDE_CHANALYZERPLUGIN_H
|
||||
#define INCLUDE_CHANALYZERPLUGIN_H
|
||||
|
||||
#include <QObject>
|
||||
#include "plugin/plugininterface.h"
|
||||
|
||||
class DeviceUISet;
|
||||
class BasebandSampleSink;
|
||||
class ChannelSinkAPI;
|
||||
|
||||
class ChannelAnalyzerPlugin : public QObject, PluginInterface {
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(PluginInterface)
|
||||
Q_PLUGIN_METADATA(IID "org.f4exb.sdrangelove.channel.chanalyzer")
|
||||
|
||||
public:
|
||||
explicit ChannelAnalyzerPlugin(QObject* parent = NULL);
|
||||
|
||||
const PluginDescriptor& getPluginDescriptor() const;
|
||||
void initPlugin(PluginAPI* pluginAPI);
|
||||
|
||||
virtual PluginInstanceGUI* createRxChannelGUI(DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel);
|
||||
virtual BasebandSampleSink* createRxChannelBS(DeviceSourceAPI *deviceAPI);
|
||||
virtual ChannelSinkAPI* createRxChannelCS(DeviceSourceAPI *deviceAPI);
|
||||
|
||||
private:
|
||||
static const PluginDescriptor m_pluginDescriptor;
|
||||
|
||||
PluginAPI* m_pluginAPI;
|
||||
};
|
||||
|
||||
#endif // INCLUDE_CHANALYZERPLUGIN_H
|
@ -1,48 +0,0 @@
|
||||
project(tcpsrc)
|
||||
|
||||
set(tcpsrc_SOURCES
|
||||
tcpsrc.cpp
|
||||
tcpsrcgui.cpp
|
||||
tcpsrcplugin.cpp
|
||||
tcpsrcsettings.cpp
|
||||
)
|
||||
|
||||
set(tcpsrc_HEADERS
|
||||
tcpsrc.h
|
||||
tcpsrcgui.h
|
||||
tcpsrcplugin.h
|
||||
tcpsrcsettings.h
|
||||
)
|
||||
|
||||
set(tcpsrc_FORMS
|
||||
tcpsrcgui.ui
|
||||
)
|
||||
|
||||
include_directories(
|
||||
.
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
#include(${QT_USE_FILE})
|
||||
add_definitions(${QT_DEFINITIONS})
|
||||
add_definitions(-DQT_PLUGIN)
|
||||
add_definitions(-DQT_SHARED)
|
||||
|
||||
#qt5_wrap_cpp(tcpsrc_HEADERS_MOC ${tcpsrc_HEADERS})
|
||||
qt5_wrap_ui(tcpsrc_FORMS_HEADERS ${tcpsrc_FORMS})
|
||||
|
||||
add_library(demodtcpsrc SHARED
|
||||
${tcpsrc_SOURCES}
|
||||
${tcpsrc_HEADERS_MOC}
|
||||
${tcpsrc_FORMS_HEADERS}
|
||||
)
|
||||
|
||||
target_link_libraries(demodtcpsrc
|
||||
${QT_LIBRARIES}
|
||||
sdrbase
|
||||
sdrgui
|
||||
)
|
||||
|
||||
qt5_use_modules(demodtcpsrc Core Widgets Network)
|
||||
|
||||
install(TARGETS demodtcpsrc DESTINATION lib/plugins/channelrx)
|
@ -1,487 +0,0 @@
|
||||
// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
|
||||
// (C) 2015 John Greb //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "tcpsrc.h"
|
||||
|
||||
#include <QTcpServer>
|
||||
#include <QTcpSocket>
|
||||
|
||||
#include "dsp/downchannelizer.h"
|
||||
#include "dsp/threadedbasebandsamplesink.h"
|
||||
#include "dsp/dspcommands.h"
|
||||
#include "device/devicesourceapi.h"
|
||||
|
||||
#include "tcpsrcgui.h"
|
||||
|
||||
MESSAGE_CLASS_DEFINITION(TCPSrc::MsgConfigureTCPSrc, Message)
|
||||
MESSAGE_CLASS_DEFINITION(TCPSrc::MsgConfigureChannelizer, Message)
|
||||
MESSAGE_CLASS_DEFINITION(TCPSrc::MsgTCPSrcConnection, Message)
|
||||
MESSAGE_CLASS_DEFINITION(TCPSrc::MsgTCPSrcSpectrum, Message)
|
||||
|
||||
const QString TCPSrc::m_channelIdURI = "sdrangel.channel.tcpsrc";
|
||||
const QString TCPSrc::m_channelId = "TCPSrc";
|
||||
|
||||
TCPSrc::TCPSrc(DeviceSourceAPI* deviceAPI) :
|
||||
ChannelSinkAPI(m_channelIdURI),
|
||||
m_deviceAPI(deviceAPI),
|
||||
m_absoluteFrequencyOffset(0),
|
||||
m_settingsMutex(QMutex::Recursive)
|
||||
{
|
||||
setObjectName(m_channelId);
|
||||
|
||||
m_inputSampleRate = 96000;
|
||||
m_sampleFormat = TCPSrcSettings::FormatSSB;
|
||||
m_outputSampleRate = 48000;
|
||||
m_rfBandwidth = 32000;
|
||||
m_tcpServer = 0;
|
||||
m_tcpPort = 9999;
|
||||
m_nco.setFreq(0, m_inputSampleRate);
|
||||
m_interpolator.create(16, m_inputSampleRate, m_rfBandwidth / 2.0);
|
||||
m_sampleDistanceRemain = m_inputSampleRate / m_outputSampleRate;
|
||||
m_spectrum = 0;
|
||||
m_spectrumEnabled = false;
|
||||
m_nextSSBId = 0;
|
||||
m_nextS16leId = 0;
|
||||
|
||||
m_last = 0;
|
||||
m_this = 0;
|
||||
m_scale = 0;
|
||||
m_volume = 0;
|
||||
m_magsq = 0;
|
||||
|
||||
m_sampleBufferSSB.resize(tcpFftLen);
|
||||
TCPFilter = new fftfilt(0.3 / 48.0, 16.0 / 48.0, tcpFftLen);
|
||||
|
||||
m_channelizer = new DownChannelizer(this);
|
||||
m_threadedChannelizer = new ThreadedBasebandSampleSink(m_channelizer, this);
|
||||
m_deviceAPI->addThreadedSink(m_threadedChannelizer);
|
||||
m_deviceAPI->addChannelAPI(this);
|
||||
}
|
||||
|
||||
TCPSrc::~TCPSrc()
|
||||
{
|
||||
m_deviceAPI->removeChannelAPI(this);
|
||||
m_deviceAPI->removeThreadedSink(m_threadedChannelizer);
|
||||
delete m_threadedChannelizer;
|
||||
delete m_channelizer;
|
||||
delete TCPFilter;
|
||||
}
|
||||
|
||||
void TCPSrc::setSpectrum(MessageQueue* messageQueue, bool enabled)
|
||||
{
|
||||
Message* cmd = MsgTCPSrcSpectrum::create(enabled);
|
||||
messageQueue->push(cmd);
|
||||
}
|
||||
|
||||
void TCPSrc::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly)
|
||||
{
|
||||
Complex ci;
|
||||
fftfilt::cmplx* sideband;
|
||||
Real l, r;
|
||||
|
||||
m_sampleBuffer.clear();
|
||||
|
||||
m_settingsMutex.lock();
|
||||
|
||||
// Rtl-Sdr uses full 16-bit scale; FCDPP does not
|
||||
int rescale = (1 << m_volume);
|
||||
|
||||
for(SampleVector::const_iterator it = begin; it < end; ++it) {
|
||||
Complex c(it->real(), it->imag());
|
||||
c *= m_nco.nextIQ();
|
||||
|
||||
if(m_interpolator.decimate(&m_sampleDistanceRemain, c, &ci))
|
||||
{
|
||||
m_magsq = ((ci.real()*ci.real() + ci.imag()*ci.imag())*rescale*rescale) / (SDR_RX_SCALED*SDR_RX_SCALED);
|
||||
m_sampleBuffer.push_back(Sample(ci.real() * rescale, ci.imag() * rescale));
|
||||
m_sampleDistanceRemain += m_inputSampleRate / m_outputSampleRate;
|
||||
}
|
||||
}
|
||||
|
||||
if((m_spectrum != 0) && (m_spectrumEnabled))
|
||||
{
|
||||
m_spectrum->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), positiveOnly);
|
||||
}
|
||||
|
||||
for(int i = 0; i < m_s16leSockets.count(); i++)
|
||||
{
|
||||
m_s16leSockets[i].socket->write((const char*)&m_sampleBuffer[0], m_sampleBuffer.size() * 4);
|
||||
}
|
||||
|
||||
if((m_sampleFormat == TCPSrcSettings::FormatSSB) && (m_ssbSockets.count() > 0)) {
|
||||
for(SampleVector::const_iterator it = m_sampleBuffer.begin(); it != m_sampleBuffer.end(); ++it) {
|
||||
//Complex cj(it->real() / 30000.0, it->imag() / 30000.0);
|
||||
Complex cj(it->real(), it->imag());
|
||||
int n_out = TCPFilter->runSSB(cj, &sideband, true);
|
||||
if (n_out) {
|
||||
for (int i = 0; i < n_out; i+=2) {
|
||||
//l = (sideband[i].real() + sideband[i].imag()) * 0.7 * 32000.0;
|
||||
//r = (sideband[i+1].real() + sideband[i+1].imag()) * 0.7 * 32000.0;
|
||||
l = (sideband[i].real() + sideband[i].imag()) * 0.7;
|
||||
r = (sideband[i+1].real() + sideband[i+1].imag()) * 0.7;
|
||||
m_sampleBufferSSB.push_back(Sample(l, r));
|
||||
}
|
||||
for(int i = 0; i < m_ssbSockets.count(); i++)
|
||||
m_ssbSockets[i].socket->write((const char*)&m_sampleBufferSSB[0], n_out * 2);
|
||||
m_sampleBufferSSB.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if((m_sampleFormat == TCPSrcSettings::FormatNFM) && (m_ssbSockets.count() > 0)) {
|
||||
for(SampleVector::const_iterator it = m_sampleBuffer.begin(); it != m_sampleBuffer.end(); ++it) {
|
||||
Complex cj(it->real() / SDR_RX_SCALEF, it->imag() / SDR_RX_SCALEF);
|
||||
// An FFT filter here is overkill, but was already set up for SSB
|
||||
int n_out = TCPFilter->runFilt(cj, &sideband);
|
||||
if (n_out) {
|
||||
Real sum = 1.0;
|
||||
for (int i = 0; i < n_out; i+=2) {
|
||||
l = m_this.real() * (m_last.imag() - sideband[i].imag())
|
||||
- m_this.imag() * (m_last.real() - sideband[i].real());
|
||||
m_last = sideband[i];
|
||||
r = m_last.real() * (m_this.imag() - sideband[i+1].imag())
|
||||
- m_last.imag() * (m_this.real() - sideband[i+1].real());
|
||||
m_this = sideband[i+1];
|
||||
m_sampleBufferSSB.push_back(Sample(l * m_scale, r * m_scale));
|
||||
sum += m_this.real() * m_this.real() + m_this.imag() * m_this.imag();
|
||||
}
|
||||
// TODO: correct levels
|
||||
m_scale = 24000 * tcpFftLen / sum;
|
||||
for(int i = 0; i < m_ssbSockets.count(); i++)
|
||||
m_ssbSockets[i].socket->write((const char*)&m_sampleBufferSSB[0], n_out * 2);
|
||||
m_sampleBufferSSB.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_settingsMutex.unlock();
|
||||
}
|
||||
|
||||
void TCPSrc::start()
|
||||
{
|
||||
m_tcpServer = new QTcpServer();
|
||||
connect(m_tcpServer, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
|
||||
connect(m_tcpServer, SIGNAL(acceptError(QAbstractSocket::SocketError)), this, SLOT(onTcpServerError(QAbstractSocket::SocketError)));
|
||||
m_tcpServer->listen(QHostAddress::Any, m_tcpPort);
|
||||
}
|
||||
|
||||
void TCPSrc::stop()
|
||||
{
|
||||
closeAllSockets(&m_ssbSockets);
|
||||
closeAllSockets(&m_s16leSockets);
|
||||
|
||||
if(m_tcpServer->isListening())
|
||||
m_tcpServer->close();
|
||||
delete m_tcpServer;
|
||||
}
|
||||
|
||||
bool TCPSrc::handleMessage(const Message& cmd)
|
||||
{
|
||||
if (DownChannelizer::MsgChannelizerNotification::match(cmd))
|
||||
{
|
||||
DownChannelizer::MsgChannelizerNotification& notif = (DownChannelizer::MsgChannelizerNotification&) cmd;
|
||||
|
||||
m_settingsMutex.lock();
|
||||
|
||||
m_inputSampleRate = notif.getSampleRate();
|
||||
m_nco.setFreq(-notif.getFrequencyOffset(), m_inputSampleRate);
|
||||
m_interpolator.create(16, m_inputSampleRate, m_rfBandwidth / 2.0);
|
||||
m_sampleDistanceRemain = m_inputSampleRate / m_outputSampleRate;
|
||||
|
||||
m_settingsMutex.unlock();
|
||||
|
||||
qDebug() << "TCPSrc::handleMessage: MsgChannelizerNotification: m_inputSampleRate: " << m_inputSampleRate
|
||||
<< " frequencyOffset: " << notif.getFrequencyOffset();
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (MsgConfigureChannelizer::match(cmd))
|
||||
{
|
||||
MsgConfigureChannelizer& cfg = (MsgConfigureChannelizer&) cmd;
|
||||
|
||||
m_channelizer->configure(m_channelizer->getInputMessageQueue(),
|
||||
cfg.getSampleRate(),
|
||||
cfg.getCenterFrequency());
|
||||
|
||||
qDebug() << "TCPSrc::handleMessage: MsgConfigureChannelizer:"
|
||||
<< " sampleRate: " << cfg.getSampleRate()
|
||||
<< " centerFrequency: " << cfg.getCenterFrequency();
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (MsgConfigureTCPSrc::match(cmd))
|
||||
{
|
||||
MsgConfigureTCPSrc& cfg = (MsgConfigureTCPSrc&) cmd;
|
||||
|
||||
TCPSrcSettings settings = cfg.getSettings();
|
||||
|
||||
// These settings are set with DownChannelizer::MsgChannelizerNotification
|
||||
m_absoluteFrequencyOffset = settings.m_inputFrequencyOffset;
|
||||
settings.m_inputSampleRate = m_settings.m_inputSampleRate;
|
||||
settings.m_inputFrequencyOffset = m_settings.m_inputFrequencyOffset;
|
||||
|
||||
m_settingsMutex.lock();
|
||||
|
||||
m_sampleFormat = settings.m_sampleFormat;
|
||||
m_outputSampleRate = settings.m_outputSampleRate;
|
||||
m_rfBandwidth = settings.m_rfBandwidth;
|
||||
|
||||
if (settings.m_tcpPort != m_tcpPort)
|
||||
{
|
||||
m_tcpPort = settings.m_tcpPort;
|
||||
|
||||
if(m_tcpServer->isListening())
|
||||
{
|
||||
m_tcpServer->close();
|
||||
}
|
||||
|
||||
m_tcpServer->listen(QHostAddress::Any, m_tcpPort);
|
||||
}
|
||||
|
||||
m_volume = settings.m_volume;
|
||||
m_interpolator.create(16, m_inputSampleRate, m_rfBandwidth / 2.0);
|
||||
m_sampleDistanceRemain = m_inputSampleRate / m_outputSampleRate;
|
||||
|
||||
if (m_sampleFormat == TCPSrcSettings::FormatSSB)
|
||||
{
|
||||
TCPFilter->create_filter(0.3 / 48.0, m_rfBandwidth / 2.0 / m_outputSampleRate);
|
||||
}
|
||||
else
|
||||
{
|
||||
TCPFilter->create_filter(0.0, m_rfBandwidth / 2.0 / m_outputSampleRate);
|
||||
}
|
||||
|
||||
m_settingsMutex.unlock();
|
||||
|
||||
qDebug() << "TCPSrc::handleMessage: MsgConfigureTCPSrc:"
|
||||
<< " m_sampleFormat: " << m_sampleFormat
|
||||
<< " m_outputSampleRate: " << m_outputSampleRate
|
||||
<< " m_rfBandwidth: " << m_rfBandwidth
|
||||
<< " m_volume: " << m_volume;
|
||||
|
||||
m_settings = settings;
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (MsgTCPSrcSpectrum::match(cmd))
|
||||
{
|
||||
MsgTCPSrcSpectrum& spc = (MsgTCPSrcSpectrum&) cmd;
|
||||
|
||||
m_spectrumEnabled = spc.getEnabled();
|
||||
|
||||
qDebug() << "TCPSrc::handleMessage: MsgTCPSrcSpectrum: m_spectrumEnabled: " << m_spectrumEnabled;
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (MsgTCPSrcConnection::match(cmd))
|
||||
{
|
||||
MsgTCPSrcConnection& con = (MsgTCPSrcConnection&) cmd;
|
||||
|
||||
qDebug() << "TCPSrc::handleMessage: MsgTCPSrcConnection"
|
||||
<< " connect: " << con.getConnect()
|
||||
<< " id: " << con.getID()
|
||||
<< " peer address: " << con.getPeerAddress()
|
||||
<< " peer port: " << con.getPeerPort();
|
||||
|
||||
if (con.getConnect())
|
||||
{
|
||||
processNewConnection();
|
||||
}
|
||||
else
|
||||
{
|
||||
processDeconnection();
|
||||
}
|
||||
}
|
||||
else if (DSPSignalNotification::match(cmd))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_spectrum != 0)
|
||||
{
|
||||
return m_spectrum->handleMessage(cmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void TCPSrc::closeAllSockets(Sockets* sockets)
|
||||
{
|
||||
for(int i = 0; i < sockets->count(); ++i)
|
||||
{
|
||||
MsgTCPSrcConnection* msg = MsgTCPSrcConnection::create(false, sockets->at(i).id, QHostAddress(), 0);
|
||||
getInputMessageQueue()->push(msg);
|
||||
|
||||
if (getMessageQueueToGUI()) { // Propagate to GUI
|
||||
getMessageQueueToGUI()->push(msg);
|
||||
}
|
||||
|
||||
sockets->at(i).socket->close();
|
||||
}
|
||||
}
|
||||
|
||||
void TCPSrc::onNewConnection()
|
||||
{
|
||||
qDebug("TCPSrc::onNewConnection");
|
||||
processNewConnection();
|
||||
}
|
||||
|
||||
void TCPSrc::processNewConnection()
|
||||
{
|
||||
qDebug("TCPSrc::processNewConnection");
|
||||
|
||||
while(m_tcpServer->hasPendingConnections())
|
||||
{
|
||||
qDebug("TCPSrc::processNewConnection: has a pending connection");
|
||||
QTcpSocket* connection = m_tcpServer->nextPendingConnection();
|
||||
connection->setSocketOption(QAbstractSocket:: KeepAliveOption, 1);
|
||||
connect(connection, SIGNAL(disconnected()), this, SLOT(onDisconnected()));
|
||||
|
||||
switch(m_sampleFormat) {
|
||||
|
||||
case TCPSrcSettings::FormatNFM:
|
||||
case TCPSrcSettings::FormatSSB:
|
||||
{
|
||||
quint32 id = (TCPSrcSettings::FormatSSB << 24) | m_nextSSBId;
|
||||
m_nextSSBId = (m_nextSSBId + 1) & 0xffffff;
|
||||
m_ssbSockets.push_back(Socket(id, connection));
|
||||
|
||||
if (getMessageQueueToGUI()) // Notify GUI of peer details
|
||||
{
|
||||
MsgTCPSrcConnection* msg = MsgTCPSrcConnection::create(true, id, connection->peerAddress(), connection->peerPort());
|
||||
getMessageQueueToGUI()->push(msg);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TCPSrcSettings::FormatS16LE:
|
||||
{
|
||||
qDebug("TCPSrc::processNewConnection: establish new S16LE connection");
|
||||
quint32 id = (TCPSrcSettings::FormatS16LE << 24) | m_nextS16leId;
|
||||
m_nextS16leId = (m_nextS16leId + 1) & 0xffffff;
|
||||
m_s16leSockets.push_back(Socket(id, connection));
|
||||
|
||||
if (getMessageQueueToGUI()) // Notify GUI of peer details
|
||||
{
|
||||
MsgTCPSrcConnection* msg = MsgTCPSrcConnection::create(true, id, connection->peerAddress(), connection->peerPort());
|
||||
getMessageQueueToGUI()->push(msg);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
delete connection;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TCPSrc::onDisconnected()
|
||||
{
|
||||
qDebug("TCPSrc::onDisconnected");
|
||||
MsgTCPSrcConnection *cmd = MsgTCPSrcConnection::create(false, 0, QHostAddress::Any, 0);
|
||||
getInputMessageQueue()->push(cmd);
|
||||
|
||||
if (getMessageQueueToGUI()) { // Propagate to GUI
|
||||
getMessageQueueToGUI()->push(cmd);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void TCPSrc::processDeconnection()
|
||||
{
|
||||
quint32 id;
|
||||
QTcpSocket* socket = 0;
|
||||
|
||||
qDebug("TCPSrc::processDeconnection");
|
||||
|
||||
for(int i = 0; i < m_ssbSockets.count(); i++)
|
||||
{
|
||||
if(m_ssbSockets[i].socket == sender())
|
||||
{
|
||||
id = m_ssbSockets[i].id;
|
||||
socket = m_ssbSockets[i].socket;
|
||||
socket->close();
|
||||
m_ssbSockets.removeAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(socket == 0)
|
||||
{
|
||||
for(int i = 0; i < m_s16leSockets.count(); i++)
|
||||
{
|
||||
if(m_s16leSockets[i].socket == sender())
|
||||
{
|
||||
qDebug("TCPSrc::processDeconnection: remove S16LE socket #%d", i);
|
||||
|
||||
id = m_s16leSockets[i].id;
|
||||
socket = m_s16leSockets[i].socket;
|
||||
socket->close();
|
||||
m_s16leSockets.removeAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(socket != 0)
|
||||
{
|
||||
MsgTCPSrcConnection* msg = MsgTCPSrcConnection::create(false, id, QHostAddress(), 0);
|
||||
getInputMessageQueue()->push(msg);
|
||||
|
||||
if (getMessageQueueToGUI()) { // Propagate to GUI
|
||||
getMessageQueueToGUI()->push(msg);
|
||||
}
|
||||
|
||||
socket->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
void TCPSrc::onTcpServerError(QAbstractSocket::SocketError socketError __attribute__((unused)))
|
||||
{
|
||||
qDebug("TCPSrc::onTcpServerError: %s", qPrintable(m_tcpServer->errorString()));
|
||||
}
|
||||
|
||||
QByteArray TCPSrc::serialize() const
|
||||
{
|
||||
return m_settings.serialize();
|
||||
}
|
||||
|
||||
bool TCPSrc::deserialize(const QByteArray& data)
|
||||
{
|
||||
if (m_settings.deserialize(data))
|
||||
{
|
||||
MsgConfigureTCPSrc *msg = MsgConfigureTCPSrc::create(m_settings, true);
|
||||
m_inputMessageQueue.push(msg);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_settings.resetToDefaults();
|
||||
MsgConfigureTCPSrc *msg = MsgConfigureTCPSrc::create(m_settings, true);
|
||||
m_inputMessageQueue.push(msg);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1,224 +0,0 @@
|
||||
#ifndef INCLUDE_TCPSRC_H
|
||||
#define INCLUDE_TCPSRC_H
|
||||
|
||||
#include <QMutex>
|
||||
#include <QHostAddress>
|
||||
|
||||
#include "dsp/basebandsamplesink.h"
|
||||
#include "channel/channelsinkapi.h"
|
||||
#include "dsp/nco.h"
|
||||
#include "dsp/fftfilt.h"
|
||||
#include "dsp/interpolator.h"
|
||||
#include "util/message.h"
|
||||
|
||||
#include "tcpsrcsettings.h"
|
||||
|
||||
#define tcpFftLen 2048
|
||||
|
||||
class QTcpServer;
|
||||
class QTcpSocket;
|
||||
class TCPSrcGUI;
|
||||
class DeviceSourceAPI;
|
||||
class ThreadedBasebandSampleSink;
|
||||
class DownChannelizer;
|
||||
|
||||
class TCPSrc : public BasebandSampleSink, public ChannelSinkAPI {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
class MsgConfigureTCPSrc : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
const TCPSrcSettings& getSettings() const { return m_settings; }
|
||||
bool getForce() const { return m_force; }
|
||||
|
||||
static MsgConfigureTCPSrc* create(const TCPSrcSettings& settings, bool force)
|
||||
{
|
||||
return new MsgConfigureTCPSrc(settings, force);
|
||||
}
|
||||
|
||||
private:
|
||||
TCPSrcSettings m_settings;
|
||||
bool m_force;
|
||||
|
||||
MsgConfigureTCPSrc(const TCPSrcSettings& settings, bool force) :
|
||||
Message(),
|
||||
m_settings(settings),
|
||||
m_force(force)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class MsgConfigureChannelizer : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
int getSampleRate() const { return m_sampleRate; }
|
||||
int getCenterFrequency() const { return m_centerFrequency; }
|
||||
|
||||
static MsgConfigureChannelizer* create(int sampleRate, int centerFrequency)
|
||||
{
|
||||
return new MsgConfigureChannelizer(sampleRate, centerFrequency);
|
||||
}
|
||||
|
||||
private:
|
||||
int m_sampleRate;
|
||||
int m_centerFrequency;
|
||||
|
||||
MsgConfigureChannelizer(int sampleRate, int centerFrequency) :
|
||||
Message(),
|
||||
m_sampleRate(sampleRate),
|
||||
m_centerFrequency(centerFrequency)
|
||||
{ }
|
||||
};
|
||||
|
||||
class MsgTCPSrcConnection : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
bool getConnect() const { return m_connect; }
|
||||
quint32 getID() const { return m_id; }
|
||||
const QHostAddress& getPeerAddress() const { return m_peerAddress; }
|
||||
int getPeerPort() const { return m_peerPort; }
|
||||
|
||||
static MsgTCPSrcConnection* create(bool connect, quint32 id, const QHostAddress& peerAddress, int peerPort)
|
||||
{
|
||||
return new MsgTCPSrcConnection(connect, id, peerAddress, peerPort);
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_connect;
|
||||
quint32 m_id;
|
||||
QHostAddress m_peerAddress;
|
||||
int m_peerPort;
|
||||
|
||||
MsgTCPSrcConnection(bool connect, quint32 id, const QHostAddress& peerAddress, int peerPort) :
|
||||
Message(),
|
||||
m_connect(connect),
|
||||
m_id(id),
|
||||
m_peerAddress(peerAddress),
|
||||
m_peerPort(peerPort)
|
||||
{ }
|
||||
};
|
||||
|
||||
TCPSrc(DeviceSourceAPI* m_deviceAPI);
|
||||
virtual ~TCPSrc();
|
||||
virtual void destroy() { delete this; }
|
||||
void setSpectrum(BasebandSampleSink* spectrum) { m_spectrum = spectrum; }
|
||||
|
||||
void setSpectrum(MessageQueue* messageQueue, bool enabled);
|
||||
double getMagSq() const { return m_magsq; }
|
||||
|
||||
virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly);
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual bool handleMessage(const Message& cmd);
|
||||
|
||||
virtual void getIdentifier(QString& id) { id = objectName(); }
|
||||
virtual void getTitle(QString& title) { title = m_settings.m_title; }
|
||||
virtual qint64 getCenterFrequency() const { return m_settings.m_inputFrequencyOffset; }
|
||||
|
||||
virtual QByteArray serialize() const;
|
||||
virtual bool deserialize(const QByteArray& data);
|
||||
|
||||
static const QString m_channelIdURI;
|
||||
static const QString m_channelId;
|
||||
|
||||
protected:
|
||||
class MsgTCPSrcSpectrum : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
bool getEnabled() const { return m_enabled; }
|
||||
|
||||
static MsgTCPSrcSpectrum* create(bool enabled)
|
||||
{
|
||||
return new MsgTCPSrcSpectrum(enabled);
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_enabled;
|
||||
|
||||
MsgTCPSrcSpectrum(bool enabled) :
|
||||
Message(),
|
||||
m_enabled(enabled)
|
||||
{ }
|
||||
};
|
||||
class MsgTCPConnection : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
bool getConnect() const { return m_connect; }
|
||||
|
||||
static MsgTCPConnection* create(bool connect)
|
||||
{
|
||||
return new MsgTCPConnection(connect);
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_connect;
|
||||
|
||||
MsgTCPConnection(bool connect) :
|
||||
Message(),
|
||||
m_connect(connect)
|
||||
{ }
|
||||
};
|
||||
|
||||
DeviceSourceAPI* m_deviceAPI;
|
||||
ThreadedBasebandSampleSink* m_threadedChannelizer;
|
||||
DownChannelizer* m_channelizer;
|
||||
|
||||
TCPSrcSettings m_settings;
|
||||
int m_absoluteFrequencyOffset;
|
||||
|
||||
int m_inputSampleRate;
|
||||
|
||||
int m_sampleFormat;
|
||||
Real m_outputSampleRate;
|
||||
Real m_rfBandwidth;
|
||||
int m_tcpPort;
|
||||
int m_volume;
|
||||
double m_magsq;
|
||||
|
||||
Real m_scale;
|
||||
Complex m_last, m_this;
|
||||
|
||||
NCO m_nco;
|
||||
Interpolator m_interpolator;
|
||||
Real m_sampleDistanceRemain;
|
||||
fftfilt* TCPFilter;
|
||||
|
||||
SampleVector m_sampleBuffer;
|
||||
SampleVector m_sampleBufferSSB;
|
||||
BasebandSampleSink* m_spectrum;
|
||||
bool m_spectrumEnabled;
|
||||
|
||||
QTcpServer* m_tcpServer;
|
||||
struct Socket {
|
||||
quint32 id;
|
||||
QTcpSocket* socket;
|
||||
Socket(quint32 _id, QTcpSocket* _socket) :
|
||||
id(_id),
|
||||
socket(_socket)
|
||||
{ }
|
||||
};
|
||||
typedef QList<Socket> Sockets;
|
||||
Sockets m_ssbSockets;
|
||||
Sockets m_s16leSockets;
|
||||
quint32 m_nextSSBId;
|
||||
quint32 m_nextS16leId;
|
||||
|
||||
QMutex m_settingsMutex;
|
||||
|
||||
void closeAllSockets(Sockets* sockets);
|
||||
void processNewConnection();
|
||||
void processDeconnection();
|
||||
|
||||
protected slots:
|
||||
void onNewConnection();
|
||||
void onDisconnected();
|
||||
void onTcpServerError(QAbstractSocket::SocketError socketError);
|
||||
};
|
||||
|
||||
#endif // INCLUDE_TCPSRC_H
|
@ -1,43 +0,0 @@
|
||||
#--------------------------------------------------------
|
||||
#
|
||||
# Pro file for Android and Windows builds with Qt Creator
|
||||
#
|
||||
#--------------------------------------------------------
|
||||
|
||||
TEMPLATE = lib
|
||||
CONFIG += plugin
|
||||
|
||||
QT += core gui widgets multimedia network opengl
|
||||
|
||||
TARGET = tcpsrc
|
||||
|
||||
DEFINES += USE_SSE2=1
|
||||
QMAKE_CXXFLAGS += -msse2
|
||||
DEFINES += USE_SSE4_1=1
|
||||
QMAKE_CXXFLAGS += -msse4.1
|
||||
QMAKE_CXXFLAGS += -std=c++11
|
||||
|
||||
INCLUDEPATH += $$PWD
|
||||
INCLUDEPATH += ../../../exports
|
||||
INCLUDEPATH += ../../../sdrbase
|
||||
INCLUDEPATH += ../../../sdrgui
|
||||
|
||||
CONFIG(Release):build_subdir = release
|
||||
CONFIG(Debug):build_subdir = debug
|
||||
|
||||
SOURCES += tcpsrc.cpp\
|
||||
tcpsrcgui.cpp\
|
||||
tcpsrcplugin.cpp\
|
||||
tcpsrcsettings.cpp
|
||||
|
||||
HEADERS += tcpsrc.h\
|
||||
tcpsrcgui.h\
|
||||
tcpsrcplugin.h\
|
||||
tcpsrcsettings.h
|
||||
|
||||
FORMS += tcpsrcgui.ui
|
||||
|
||||
LIBS += -L../../../sdrbase/$${build_subdir} -lsdrbase
|
||||
LIBS += -L../../../sdrgui/$${build_subdir} -lsdrgui
|
||||
|
||||
RESOURCES = ../../../sdrgui/resources/res.qrc
|
@ -1,397 +0,0 @@
|
||||
#include "tcpsrcgui.h"
|
||||
|
||||
#include <device/devicesourceapi.h>
|
||||
#include "device/deviceuiset.h"
|
||||
#include "plugin/pluginapi.h"
|
||||
#include "dsp/spectrumvis.h"
|
||||
#include "dsp/dspengine.h"
|
||||
#include "util/simpleserializer.h"
|
||||
#include "util/db.h"
|
||||
#include "ui_tcpsrcgui.h"
|
||||
#include "mainwindow.h"
|
||||
#include "tcpsrc.h"
|
||||
|
||||
TCPSrcGUI* TCPSrcGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel)
|
||||
{
|
||||
TCPSrcGUI* gui = new TCPSrcGUI(pluginAPI, deviceUISet, rxChannel);
|
||||
return gui;
|
||||
}
|
||||
|
||||
void TCPSrcGUI::destroy()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
void TCPSrcGUI::setName(const QString& name)
|
||||
{
|
||||
setObjectName(name);
|
||||
}
|
||||
|
||||
qint64 TCPSrcGUI::getCenterFrequency() const
|
||||
{
|
||||
return m_channelMarker.getCenterFrequency();
|
||||
}
|
||||
|
||||
void TCPSrcGUI::setCenterFrequency(qint64 centerFrequency)
|
||||
{
|
||||
m_channelMarker.setCenterFrequency(centerFrequency);
|
||||
applySettings();
|
||||
}
|
||||
|
||||
QString TCPSrcGUI::getName() const
|
||||
{
|
||||
return objectName();
|
||||
}
|
||||
|
||||
void TCPSrcGUI::resetToDefaults()
|
||||
{
|
||||
m_settings.resetToDefaults();
|
||||
displaySettings();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
QByteArray TCPSrcGUI::serialize() const
|
||||
{
|
||||
return m_settings.serialize();
|
||||
}
|
||||
|
||||
bool TCPSrcGUI::deserialize(const QByteArray& data)
|
||||
{
|
||||
if(m_settings.deserialize(data))
|
||||
{
|
||||
qDebug("TCPSrcGUI::deserialize: m_squelchGate: %d", m_settings.m_squelchGate);
|
||||
displaySettings();
|
||||
applySettings();
|
||||
return true;
|
||||
} else {
|
||||
resetToDefaults();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool TCPSrcGUI::handleMessage(const Message& message)
|
||||
{
|
||||
if (TCPSrc::MsgTCPSrcConnection::match(message))
|
||||
{
|
||||
TCPSrc::MsgTCPSrcConnection& con = (TCPSrc::MsgTCPSrcConnection&) message;
|
||||
|
||||
if(con.getConnect())
|
||||
{
|
||||
addConnection(con.getID(), con.getPeerAddress(), con.getPeerPort());
|
||||
}
|
||||
else
|
||||
{
|
||||
delConnection(con.getID());
|
||||
}
|
||||
|
||||
qDebug() << "TCPSrcGUI::handleMessage: TCPSrc::MsgTCPSrcConnection: " << con.getConnect()
|
||||
<< " ID: " << con.getID()
|
||||
<< " peerAddress: " << con.getPeerAddress()
|
||||
<< " peerPort: " << con.getPeerPort();
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void TCPSrcGUI::channelMarkerChangedByCursor()
|
||||
{
|
||||
ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency());
|
||||
m_settings.m_inputFrequencyOffset = m_channelMarker.getCenterFrequency();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void TCPSrcGUI::channelMarkerHighlightedByCursor()
|
||||
{
|
||||
setHighlighted(m_channelMarker.getHighlighted());
|
||||
}
|
||||
|
||||
void TCPSrcGUI::tick()
|
||||
{
|
||||
double powDb = CalcDb::dbPower(m_tcpSrc->getMagSq());
|
||||
m_channelPowerDbAvg(powDb);
|
||||
ui->channelPower->setText(QString::number(m_channelPowerDbAvg.asDouble(), 'f', 1));
|
||||
}
|
||||
|
||||
TCPSrcGUI::TCPSrcGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget* parent) :
|
||||
RollupWidget(parent),
|
||||
ui(new Ui::TCPSrcGUI),
|
||||
m_pluginAPI(pluginAPI),
|
||||
m_deviceUISet(deviceUISet),
|
||||
m_tcpSrc(0),
|
||||
m_channelMarker(this),
|
||||
m_rfBandwidthChanged(false),
|
||||
m_doApplySettings(true)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->connectedClientsBox->hide();
|
||||
connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool)));
|
||||
setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
|
||||
m_spectrumVis = new SpectrumVis(SDR_RX_SCALEF, ui->glSpectrum);
|
||||
m_tcpSrc = (TCPSrc*) rxChannel; //new TCPSrc(m_deviceUISet->m_deviceSourceAPI);
|
||||
m_tcpSrc->setSpectrum(m_spectrumVis);
|
||||
|
||||
ui->deltaFrequencyLabel->setText(QString("%1f").arg(QChar(0x94, 0x03)));
|
||||
ui->deltaFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
|
||||
ui->deltaFrequency->setValueRange(false, 7, -9999999, 9999999);
|
||||
|
||||
ui->glSpectrum->setCenterFrequency(0);
|
||||
ui->glSpectrum->setSampleRate(ui->sampleRate->text().toInt());
|
||||
ui->glSpectrum->setDisplayWaterfall(true);
|
||||
ui->glSpectrum->setDisplayMaxHold(true);
|
||||
m_spectrumVis->configure(m_spectrumVis->getInputMessageQueue(), 64, 10, FFTWindow::BlackmanHarris);
|
||||
|
||||
ui->glSpectrum->connectTimer(MainWindow::getInstance()->getMasterTimer());
|
||||
connect(&MainWindow::getInstance()->getMasterTimer(), SIGNAL(timeout()), this, SLOT(tick()));
|
||||
|
||||
m_channelMarker.blockSignals(true);
|
||||
m_channelMarker.setBandwidth(16000);
|
||||
m_channelMarker.setCenterFrequency(0);
|
||||
m_channelMarker.setColor(m_settings.m_rgbColor);
|
||||
m_channelMarker.blockSignals(false);
|
||||
m_channelMarker.setVisible(true); // activate signal on the last setting only
|
||||
|
||||
setTitleColor(m_channelMarker.getColor());
|
||||
|
||||
m_deviceUISet->registerRxChannelInstance(TCPSrc::m_channelIdURI, this);
|
||||
m_deviceUISet->addChannelMarker(&m_channelMarker);
|
||||
m_deviceUISet->addRollupWidget(this);
|
||||
|
||||
connect(&m_channelMarker, SIGNAL(changedByCursor()), this, SLOT(channelMarkerChangedByCursor()));
|
||||
connect(&m_channelMarker, SIGNAL(highlightedByCursor()), this, SLOT(channelMarkerHighlightedByCursor()));
|
||||
|
||||
ui->spectrumGUI->setBuddies(m_spectrumVis->getInputMessageQueue(), m_spectrumVis, ui->glSpectrum);
|
||||
|
||||
m_settings.setSpectrumGUI(ui->spectrumGUI);
|
||||
m_settings.setChannelMarker(&m_channelMarker);
|
||||
|
||||
displaySettings();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
TCPSrcGUI::~TCPSrcGUI()
|
||||
{
|
||||
m_deviceUISet->removeRxChannelInstance(this);
|
||||
delete m_tcpSrc; // TODO: check this: when the GUI closes it has to delete the demodulator
|
||||
delete m_spectrumVis;
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void TCPSrcGUI::blockApplySettings(bool block)
|
||||
{
|
||||
m_doApplySettings = !block;
|
||||
}
|
||||
|
||||
void TCPSrcGUI::applySettings()
|
||||
{
|
||||
if (m_doApplySettings)
|
||||
{
|
||||
ui->glSpectrum->setSampleRate(m_settings.m_outputSampleRate);
|
||||
|
||||
TCPSrc::MsgConfigureChannelizer* channelConfigMsg = TCPSrc::MsgConfigureChannelizer::create(
|
||||
m_settings.m_outputSampleRate, m_channelMarker.getCenterFrequency());
|
||||
m_tcpSrc->getInputMessageQueue()->push(channelConfigMsg);
|
||||
|
||||
TCPSrc::MsgConfigureTCPSrc* message = TCPSrc::MsgConfigureTCPSrc::create( m_settings, false);
|
||||
m_tcpSrc->getInputMessageQueue()->push(message);
|
||||
}
|
||||
}
|
||||
|
||||
void TCPSrcGUI::on_deltaFrequency_changed(qint64 value)
|
||||
{
|
||||
m_channelMarker.setCenterFrequency(value);
|
||||
m_settings.m_inputFrequencyOffset = m_channelMarker.getCenterFrequency();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void TCPSrcGUI::on_sampleFormat_currentIndexChanged(int index)
|
||||
{
|
||||
setSampleFormat(index);
|
||||
|
||||
ui->applyBtn->setEnabled(true);
|
||||
ui->applyBtn->setStyleSheet("QPushButton { background-color : green; }");
|
||||
}
|
||||
|
||||
void TCPSrcGUI::on_sampleRate_textEdited(const QString& arg1 __attribute__((unused)))
|
||||
{
|
||||
bool ok;
|
||||
Real outputSampleRate = ui->sampleRate->text().toDouble(&ok);
|
||||
|
||||
if((!ok) || (outputSampleRate < 1000))
|
||||
{
|
||||
m_settings.m_outputSampleRate = 48000;
|
||||
ui->sampleRate->setText(QString("%1").arg(outputSampleRate, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_settings.m_outputSampleRate = outputSampleRate;
|
||||
}
|
||||
|
||||
ui->applyBtn->setEnabled(true);
|
||||
ui->applyBtn->setStyleSheet("QPushButton { background-color : green; }");
|
||||
}
|
||||
|
||||
void TCPSrcGUI::on_rfBandwidth_textEdited(const QString& arg1 __attribute__((unused)))
|
||||
{
|
||||
bool ok;
|
||||
Real rfBandwidth = ui->rfBandwidth->text().toDouble(&ok);
|
||||
|
||||
if((!ok) || (rfBandwidth > m_settings.m_outputSampleRate))
|
||||
{
|
||||
m_settings.m_rfBandwidth = m_settings.m_outputSampleRate;
|
||||
ui->rfBandwidth->setText(QString("%1").arg(m_settings.m_rfBandwidth, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_settings.m_rfBandwidth = rfBandwidth;
|
||||
}
|
||||
|
||||
m_rfBandwidthChanged = true;
|
||||
|
||||
ui->applyBtn->setEnabled(true);
|
||||
ui->applyBtn->setStyleSheet("QPushButton { background-color : green; }");
|
||||
}
|
||||
|
||||
void TCPSrcGUI::on_tcpPort_textEdited(const QString& arg1 __attribute__((unused)))
|
||||
{
|
||||
bool ok;
|
||||
int tcpPort = ui->tcpPort->text().toInt(&ok);
|
||||
|
||||
if((!ok) || (tcpPort < 1) || (tcpPort > 65535))
|
||||
{
|
||||
m_settings.m_tcpPort = 9999;
|
||||
ui->tcpPort->setText(QString("%1").arg(m_settings.m_tcpPort, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_settings.m_tcpPort = tcpPort;
|
||||
}
|
||||
|
||||
ui->applyBtn->setEnabled(true);
|
||||
ui->applyBtn->setStyleSheet("QPushButton { background-color : green; }");
|
||||
}
|
||||
|
||||
void TCPSrcGUI::on_applyBtn_clicked()
|
||||
{
|
||||
if (m_rfBandwidthChanged)
|
||||
{
|
||||
blockApplySettings(true);
|
||||
m_channelMarker.setBandwidth((int) m_settings.m_rfBandwidth);
|
||||
m_rfBandwidthChanged = false;
|
||||
blockApplySettings(false);
|
||||
}
|
||||
|
||||
ui->glSpectrum->setSampleRate(m_settings.m_outputSampleRate);
|
||||
|
||||
ui->applyBtn->setEnabled(false);
|
||||
ui->applyBtn->setStyleSheet("QPushButton { background:rgb(79,79,79); }");
|
||||
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void TCPSrcGUI::displaySettings()
|
||||
{
|
||||
m_channelMarker.blockSignals(true);
|
||||
m_channelMarker.setCenterFrequency(m_settings.m_inputFrequencyOffset);
|
||||
m_channelMarker.setBandwidth(m_settings.m_rfBandwidth);
|
||||
m_channelMarker.setTitle(m_settings.m_title);
|
||||
m_channelMarker.blockSignals(false);
|
||||
m_channelMarker.setColor(m_settings.m_rgbColor); // activate signal on the last setting only
|
||||
|
||||
setTitleColor(m_settings.m_rgbColor);
|
||||
setWindowTitle(m_channelMarker.getTitle());
|
||||
|
||||
blockApplySettings(true);
|
||||
|
||||
ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency());
|
||||
|
||||
ui->sampleRate->setText(QString("%1").arg(m_settings.m_outputSampleRate, 0));
|
||||
setSampleFormatIndex(m_settings.m_sampleFormat);
|
||||
|
||||
ui->rfBandwidth->setText(QString("%1").arg(m_settings.m_rfBandwidth, 0));
|
||||
|
||||
ui->volume->setValue(m_settings.m_volume);
|
||||
ui->volumeText->setText(QString("%1").arg(ui->volume->value()));
|
||||
|
||||
ui->glSpectrum->setSampleRate(m_settings.m_outputSampleRate);
|
||||
|
||||
blockApplySettings(false);
|
||||
}
|
||||
|
||||
void TCPSrcGUI::setSampleFormatIndex(const TCPSrcSettings::SampleFormat& sampleFormat)
|
||||
{
|
||||
switch(sampleFormat)
|
||||
{
|
||||
case TCPSrcSettings::FormatS16LE:
|
||||
ui->sampleFormat->setCurrentIndex(0);
|
||||
break;
|
||||
case TCPSrcSettings::FormatNFM:
|
||||
ui->sampleFormat->setCurrentIndex(1);
|
||||
break;
|
||||
case TCPSrcSettings::FormatSSB:
|
||||
ui->sampleFormat->setCurrentIndex(2);
|
||||
break;
|
||||
default:
|
||||
ui->sampleFormat->setCurrentIndex(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void TCPSrcGUI::setSampleFormat(int index)
|
||||
{
|
||||
switch(index)
|
||||
{
|
||||
case 0:
|
||||
m_settings.m_sampleFormat = TCPSrcSettings::FormatS16LE;
|
||||
break;
|
||||
case 1:
|
||||
m_settings.m_sampleFormat = TCPSrcSettings::FormatNFM;
|
||||
break;
|
||||
case 2:
|
||||
m_settings.m_sampleFormat = TCPSrcSettings::FormatSSB;
|
||||
break;
|
||||
default:
|
||||
m_settings.m_sampleFormat = TCPSrcSettings::FormatS16LE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void TCPSrcGUI::on_volume_valueChanged(int value)
|
||||
{
|
||||
ui->volume->setValue(value);
|
||||
ui->volumeText->setText(QString("%1").arg(value));
|
||||
ui->applyBtn->setEnabled(true);
|
||||
}
|
||||
|
||||
void TCPSrcGUI::onWidgetRolled(QWidget* widget, bool rollDown)
|
||||
{
|
||||
if ((widget == ui->spectrumBox) && (m_tcpSrc != 0))
|
||||
{
|
||||
m_tcpSrc->setSpectrum(m_tcpSrc->getInputMessageQueue(), rollDown);
|
||||
}
|
||||
}
|
||||
|
||||
void TCPSrcGUI::addConnection(quint32 id, const QHostAddress& peerAddress, int peerPort)
|
||||
{
|
||||
QStringList l;
|
||||
l.append(QString("%1:%2").arg(peerAddress.toString()).arg(peerPort));
|
||||
new QTreeWidgetItem(ui->connections, l, id);
|
||||
ui->connectedClientsBox->setWindowTitle(tr("Connected Clients (%1)").arg(ui->connections->topLevelItemCount()));
|
||||
}
|
||||
|
||||
void TCPSrcGUI::delConnection(quint32 id)
|
||||
{
|
||||
for(int i = 0; i < ui->connections->topLevelItemCount(); i++)
|
||||
{
|
||||
if(ui->connections->topLevelItem(i)->type() == (int)id)
|
||||
{
|
||||
delete ui->connections->topLevelItem(i);
|
||||
ui->connectedClientsBox->setWindowTitle(tr("Connected Clients (%1)").arg(ui->connections->topLevelItemCount()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
#ifndef INCLUDE_TCPSRCGUI_H
|
||||
#define INCLUDE_TCPSRCGUI_H
|
||||
|
||||
#include <plugin/plugininstancegui.h>
|
||||
#include <QHostAddress>
|
||||
|
||||
#include "gui/rollupwidget.h"
|
||||
#include "dsp/channelmarker.h"
|
||||
#include "util/movingaverage.h"
|
||||
#include "util/messagequeue.h"
|
||||
|
||||
#include "tcpsrc.h"
|
||||
#include "tcpsrcsettings.h"
|
||||
|
||||
class PluginAPI;
|
||||
class DeviceUISet;
|
||||
class TCPSrc;
|
||||
class SpectrumVis;
|
||||
|
||||
namespace Ui {
|
||||
class TCPSrcGUI;
|
||||
}
|
||||
|
||||
class TCPSrcGUI : public RollupWidget, public PluginInstanceGUI {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static TCPSrcGUI* create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel);
|
||||
virtual void destroy();
|
||||
|
||||
void setName(const QString& name);
|
||||
QString getName() const;
|
||||
virtual qint64 getCenterFrequency() const;
|
||||
virtual void setCenterFrequency(qint64 centerFrequency);
|
||||
|
||||
void resetToDefaults();
|
||||
QByteArray serialize() const;
|
||||
bool deserialize(const QByteArray& data);
|
||||
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
|
||||
virtual bool handleMessage(const Message& message);
|
||||
|
||||
public slots:
|
||||
void channelMarkerChangedByCursor();
|
||||
void channelMarkerHighlightedByCursor();
|
||||
|
||||
private:
|
||||
Ui::TCPSrcGUI* ui;
|
||||
PluginAPI* m_pluginAPI;
|
||||
DeviceUISet* m_deviceUISet;
|
||||
TCPSrc* m_tcpSrc;
|
||||
ChannelMarker m_channelMarker;
|
||||
MovingAverageUtil<Real, double, 40> m_channelPowerDbAvg;
|
||||
|
||||
// settings
|
||||
TCPSrcSettings m_settings;
|
||||
TCPSrcSettings::SampleFormat m_sampleFormat;
|
||||
Real m_outputSampleRate;
|
||||
Real m_rfBandwidth;
|
||||
int m_boost;
|
||||
int m_tcpPort;
|
||||
bool m_rfBandwidthChanged;
|
||||
bool m_doApplySettings;
|
||||
|
||||
// RF path
|
||||
SpectrumVis* m_spectrumVis;
|
||||
MessageQueue m_inputMessageQueue;
|
||||
|
||||
explicit TCPSrcGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget* parent = 0);
|
||||
virtual ~TCPSrcGUI();
|
||||
|
||||
void blockApplySettings(bool block);
|
||||
void applySettings();
|
||||
void displaySettings();
|
||||
void setSampleFormat(int index);
|
||||
void setSampleFormatIndex(const TCPSrcSettings::SampleFormat& sampleFormat);
|
||||
|
||||
void addConnection(quint32 id, const QHostAddress& peerAddress, int peerPort);
|
||||
void delConnection(quint32 id);
|
||||
|
||||
private slots:
|
||||
void on_deltaFrequency_changed(qint64 value);
|
||||
void on_sampleFormat_currentIndexChanged(int index);
|
||||
void on_sampleRate_textEdited(const QString& arg1);
|
||||
void on_rfBandwidth_textEdited(const QString& arg1);
|
||||
void on_tcpPort_textEdited(const QString& arg1);
|
||||
void on_applyBtn_clicked();
|
||||
void onWidgetRolled(QWidget* widget, bool rollDown);
|
||||
void on_volume_valueChanged(int value);
|
||||
void tick();
|
||||
};
|
||||
|
||||
#endif // INCLUDE_TCPSRCGUI_H
|
@ -1,480 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TCPSrcGUI</class>
|
||||
<widget class="RollupWidget" name="TCPSrcGUI">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>443</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Liberation Sans</family>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>TCP Sample Source</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>5</y>
|
||||
<width>201</width>
|
||||
<height>142</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Settings</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Sample Format</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QComboBox" name="sampleFormat">
|
||||
<property name="toolTip">
|
||||
<string>Sample format</string>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>S16LE I/Q</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>S16LE NFM</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>S16LE SSB</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLineEdit" name="rfBandwidth">
|
||||
<property name="toolTip">
|
||||
<string>Channel bandwidth</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>32000</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>RF Bandwidth (Hz)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Samplerate (Hz)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>TCP Port</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="sampleRate">
|
||||
<property name="toolTip">
|
||||
<string>Data stream sample rate</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>48000</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLineEdit" name="tcpPort">
|
||||
<property name="toolTip">
|
||||
<string>TCP port number</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>9999</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QPushButton" name="applyBtn">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Apply changes</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Apply</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<layout class="QHBoxLayout" name="DeltaFrequencyLayout">
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="deltaFrequencyLabel">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Df</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ValueDialZ" name="deltaFrequency" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Liberation Mono</family>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Demod shift frequency from center in Hz</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="deltaUnits">
|
||||
<property name="palette">
|
||||
<palette>
|
||||
<active>
|
||||
<colorrole role="Text">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>26</red>
|
||||
<green>26</green>
|
||||
<blue>26</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
<colorrole role="BrightText">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>255</red>
|
||||
<green>255</green>
|
||||
<blue>255</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</active>
|
||||
<inactive>
|
||||
<colorrole role="Text">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>26</red>
|
||||
<green>26</green>
|
||||
<blue>26</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
<colorrole role="BrightText">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>255</red>
|
||||
<green>255</green>
|
||||
<blue>255</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</inactive>
|
||||
<disabled>
|
||||
<colorrole role="Text">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>118</red>
|
||||
<green>118</green>
|
||||
<blue>117</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
<colorrole role="BrightText">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>255</red>
|
||||
<green>255</green>
|
||||
<blue>255</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</disabled>
|
||||
</palette>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string> Hz</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QHBoxLayout" name="ChannelPowerLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="channelPower">
|
||||
<property name="toolTip">
|
||||
<string>Channel power</string>
|
||||
</property>
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::LeftToRight</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>0.0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="channelPowerUnits">
|
||||
<property name="text">
|
||||
<string> dB</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<layout class="QHBoxLayout" name="BoostLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="volumeLabel">
|
||||
<property name="text">
|
||||
<string>Vol</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="volume">
|
||||
<property name="toolTip">
|
||||
<string>Amplitude boost</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="volumeText">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="spectrumBox" native="true">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>15</x>
|
||||
<y>160</y>
|
||||
<width>231</width>
|
||||
<height>156</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Channel Spectrum</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="GLSpectrum" name="glSpectrum" native="true">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Liberation Mono</family>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="GLSpectrumGUI" name="spectrumGUI" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="connectedClientsBox" native="true">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>15</x>
|
||||
<y>330</y>
|
||||
<width>274</width>
|
||||
<height>101</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Connected Clients (0)</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTreeWidget" name="connections">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="rootIsDecorated">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="itemsExpandable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="headerVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>IP:Port</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>RollupWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>gui/rollupwidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>GLSpectrum</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>gui/glspectrum.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>GLSpectrumGUI</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>gui/glspectrumgui.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ValueDialZ</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>gui/valuedialz.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>sampleFormat</tabstop>
|
||||
<tabstop>tcpPort</tabstop>
|
||||
<tabstop>sampleRate</tabstop>
|
||||
<tabstop>rfBandwidth</tabstop>
|
||||
<tabstop>applyBtn</tabstop>
|
||||
<tabstop>connections</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
@ -1,51 +0,0 @@
|
||||
#include "tcpsrcplugin.h"
|
||||
|
||||
#include <QtPlugin>
|
||||
#include "plugin/pluginapi.h"
|
||||
|
||||
#include "tcpsrcgui.h"
|
||||
#include "tcpsrc.h"
|
||||
|
||||
const PluginDescriptor TCPSrcPlugin::m_pluginDescriptor = {
|
||||
QString("TCP Channel Source"),
|
||||
QString("3.14.5"),
|
||||
QString("(c) Edouard Griffiths, F4EXB"),
|
||||
QString("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
QString("https://github.com/f4exb/sdrangel")
|
||||
};
|
||||
|
||||
TCPSrcPlugin::TCPSrcPlugin(QObject* parent) :
|
||||
QObject(parent),
|
||||
m_pluginAPI(0)
|
||||
{
|
||||
}
|
||||
|
||||
const PluginDescriptor& TCPSrcPlugin::getPluginDescriptor() const
|
||||
{
|
||||
return m_pluginDescriptor;
|
||||
}
|
||||
|
||||
void TCPSrcPlugin::initPlugin(PluginAPI* pluginAPI)
|
||||
{
|
||||
m_pluginAPI = pluginAPI;
|
||||
|
||||
// register TCP Channel Source
|
||||
m_pluginAPI->registerRxChannel(TCPSrc::m_channelIdURI, TCPSrc::m_channelId, this);
|
||||
}
|
||||
|
||||
PluginInstanceGUI* TCPSrcPlugin::createRxChannelGUI(DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel)
|
||||
{
|
||||
return TCPSrcGUI::create(m_pluginAPI, deviceUISet, rxChannel);
|
||||
}
|
||||
|
||||
BasebandSampleSink* TCPSrcPlugin::createRxChannelBS(DeviceSourceAPI *deviceAPI)
|
||||
{
|
||||
return new TCPSrc(deviceAPI);
|
||||
}
|
||||
|
||||
ChannelSinkAPI* TCPSrcPlugin::createRxChannelCS(DeviceSourceAPI *deviceAPI)
|
||||
{
|
||||
return new TCPSrc(deviceAPI);
|
||||
}
|
||||
|
@ -1,31 +0,0 @@
|
||||
#ifndef INCLUDE_TCPSRCPLUGIN_H
|
||||
#define INCLUDE_TCPSRCPLUGIN_H
|
||||
|
||||
#include <QObject>
|
||||
#include "plugin/plugininterface.h"
|
||||
|
||||
class DeviceUISet;
|
||||
class BasebandSampleSink;
|
||||
|
||||
class TCPSrcPlugin : public QObject, PluginInterface {
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(PluginInterface)
|
||||
Q_PLUGIN_METADATA(IID "sdrangel.demod.tcpsrc")
|
||||
|
||||
public:
|
||||
explicit TCPSrcPlugin(QObject* parent = NULL);
|
||||
|
||||
const PluginDescriptor& getPluginDescriptor() const;
|
||||
void initPlugin(PluginAPI* pluginAPI);
|
||||
|
||||
virtual PluginInstanceGUI* createRxChannelGUI(DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel);
|
||||
virtual BasebandSampleSink* createRxChannelBS(DeviceSourceAPI *deviceAPI);
|
||||
virtual ChannelSinkAPI* createRxChannelCS(DeviceSourceAPI *deviceAPI);
|
||||
|
||||
private:
|
||||
static const PluginDescriptor m_pluginDescriptor;
|
||||
|
||||
PluginAPI* m_pluginAPI;
|
||||
};
|
||||
|
||||
#endif // INCLUDE_TCPSRCPLUGIN_H
|
@ -1,150 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2017 Edouard Griffiths, F4EXB //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <QColor>
|
||||
|
||||
#include "dsp/dspengine.h"
|
||||
#include "util/simpleserializer.h"
|
||||
#include "settings/serializable.h"
|
||||
#include "tcpsrcsettings.h"
|
||||
|
||||
TCPSrcSettings::TCPSrcSettings() :
|
||||
m_channelMarker(0),
|
||||
m_spectrumGUI(0)
|
||||
{
|
||||
resetToDefaults();
|
||||
}
|
||||
|
||||
void TCPSrcSettings::resetToDefaults()
|
||||
{
|
||||
m_outputSampleRate = 48000;
|
||||
m_sampleFormat = FormatS16LE;
|
||||
m_inputSampleRate = 48000;
|
||||
m_inputFrequencyOffset = 0;
|
||||
m_rfBandwidth = 12500;
|
||||
m_tcpPort = 9999;
|
||||
m_fmDeviation = 2500;
|
||||
m_channelMute = false;
|
||||
m_gain = 1.0;
|
||||
m_squelchdB = -60;
|
||||
m_squelchGate = 0.0;
|
||||
m_squelchEnabled = true;
|
||||
m_agc = false;
|
||||
m_audioActive = false;
|
||||
m_audioStereo = false;
|
||||
m_volume = 20;
|
||||
m_udpAddress = "127.0.0.1";
|
||||
m_udpPort = 9999;
|
||||
m_audioPort = 9998;
|
||||
m_rgbColor = QColor(225, 25, 99).rgb();
|
||||
m_title = "TCP Source";
|
||||
}
|
||||
|
||||
QByteArray TCPSrcSettings::serialize() const
|
||||
{
|
||||
SimpleSerializer s(1);
|
||||
s.writeS32(2, m_inputFrequencyOffset);
|
||||
s.writeS32(3, (int) m_sampleFormat);
|
||||
s.writeReal(4, m_outputSampleRate);
|
||||
s.writeReal(5, m_rfBandwidth);
|
||||
s.writeS32(6, m_tcpPort);
|
||||
|
||||
if (m_channelMarker) {
|
||||
s.writeBlob(10, m_channelMarker->serialize());
|
||||
}
|
||||
|
||||
if (m_spectrumGUI) {
|
||||
s.writeBlob(7, m_spectrumGUI->serialize());
|
||||
}
|
||||
|
||||
s.writeS32(8, m_gain*10.0);
|
||||
s.writeU32(9, m_rgbColor);
|
||||
s.writeBool(11, m_audioActive);
|
||||
s.writeS32(12, m_volume);
|
||||
s.writeBool(14, m_audioStereo);
|
||||
s.writeS32(15, m_fmDeviation);
|
||||
s.writeS32(16, m_squelchdB);
|
||||
s.writeS32(17, m_squelchGate);
|
||||
s.writeBool(18, m_agc);
|
||||
s.writeString(19, m_title);
|
||||
|
||||
return s.final();
|
||||
|
||||
}
|
||||
|
||||
bool TCPSrcSettings::deserialize(const QByteArray& data)
|
||||
{
|
||||
SimpleDeserializer d(data);
|
||||
|
||||
if (!d.isValid())
|
||||
{
|
||||
resetToDefaults();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (d.getVersion() == 1)
|
||||
{
|
||||
QByteArray bytetmp;
|
||||
QString strtmp;
|
||||
int32_t s32tmp;
|
||||
|
||||
if (m_channelMarker) {
|
||||
d.readBlob(10, &bytetmp);
|
||||
m_channelMarker->deserialize(bytetmp);
|
||||
}
|
||||
|
||||
d.readS32(2, &s32tmp, 0);
|
||||
m_inputFrequencyOffset = s32tmp;
|
||||
|
||||
d.readS32(3, &s32tmp, FormatS16LE);
|
||||
|
||||
if ((s32tmp >= 0) && (s32tmp < (int) FormatNone)) {
|
||||
m_sampleFormat = (SampleFormat) s32tmp;
|
||||
} else {
|
||||
m_sampleFormat = FormatS16LE;
|
||||
}
|
||||
|
||||
d.readReal(4, &m_outputSampleRate, 48000.0);
|
||||
d.readReal(5, &m_rfBandwidth, 32000.0);
|
||||
d.readS32(6, &s32tmp, 10);
|
||||
m_tcpPort = s32tmp < 1024 ? 9999 : s32tmp % (1<<16);
|
||||
|
||||
if (m_spectrumGUI) {
|
||||
d.readBlob(7, &bytetmp);
|
||||
m_spectrumGUI->deserialize(bytetmp);
|
||||
}
|
||||
|
||||
d.readS32(8, &s32tmp, 10);
|
||||
m_gain = s32tmp / 10.0;
|
||||
d.readU32(9, &m_rgbColor);
|
||||
d.readBool(11, &m_audioActive, false);
|
||||
d.readS32(12, &m_volume, 0);
|
||||
d.readBool(14, &m_audioStereo, false);
|
||||
d.readS32(15, &m_fmDeviation, 2500);
|
||||
d.readS32(16, &m_squelchdB, -60);
|
||||
d.readS32(17, &m_squelchGate, 5);
|
||||
d.readBool(18, &m_agc, false);
|
||||
d.readString(19, &m_title, "TCP Source");
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
resetToDefaults();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1,72 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2017 Edouard Griffiths, F4EXB //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef PLUGINS_CHANNELRX_TCPSRC_TCPSRCSETTINGS_H_
|
||||
#define PLUGINS_CHANNELRX_TCPSRC_TCPSRCSETTINGS_H_
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QString>
|
||||
#include <stdint.h>
|
||||
|
||||
class Serializable;
|
||||
|
||||
struct TCPSrcSettings
|
||||
{
|
||||
enum SampleFormat {
|
||||
FormatS16LE,
|
||||
FormatNFM,
|
||||
FormatSSB,
|
||||
FormatNone
|
||||
};
|
||||
|
||||
float m_outputSampleRate;
|
||||
SampleFormat m_sampleFormat;
|
||||
float m_inputSampleRate;
|
||||
int64_t m_inputFrequencyOffset;
|
||||
float m_rfBandwidth;
|
||||
uint16_t m_tcpPort;
|
||||
int m_fmDeviation;
|
||||
bool m_channelMute;
|
||||
float m_gain;
|
||||
int m_squelchdB; //!< power dB
|
||||
int m_squelchGate; //!< 100ths seconds
|
||||
bool m_squelchEnabled;
|
||||
bool m_agc;
|
||||
bool m_audioActive;
|
||||
bool m_audioStereo;
|
||||
int m_volume;
|
||||
quint32 m_rgbColor;
|
||||
|
||||
QString m_udpAddress;
|
||||
uint16_t m_udpPort;
|
||||
uint16_t m_audioPort;
|
||||
|
||||
QString m_title;
|
||||
|
||||
Serializable *m_channelMarker;
|
||||
Serializable *m_spectrumGUI;
|
||||
|
||||
TCPSrcSettings();
|
||||
void resetToDefaults();
|
||||
void setChannelMarker(Serializable *channelMarker) { m_channelMarker = channelMarker; }
|
||||
void setSpectrumGUI(Serializable *spectrumGUI) { m_spectrumGUI = spectrumGUI; }
|
||||
QByteArray serialize() const;
|
||||
bool deserialize(const QByteArray& data);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* PLUGINS_CHANNELRX_TCPSRC_TCPSRCSETTINGS_H_ */
|
Loading…
Reference in New Issue
Block a user