Removal of ChannelAnalyzer and TCPSrc plugins

This commit is contained in:
f4exb 2018-05-25 09:27:02 +02:00
parent c961fa368d
commit 111b3da5ce
21 changed files with 0 additions and 3788 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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>

View File

@ -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);
}

View File

@ -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

View File

@ -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)

View File

@ -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;
}
}

View File

@ -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

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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>

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}
}

View File

@ -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_ */