major rewrite and changes... far too many to put into individual commits

This commit is contained in:
Christian Daniel 2013-09-23 21:31:54 +02:00
parent 69673c7a64
commit 9fd7152f13
56 changed files with 1456 additions and 295 deletions

View File

@ -3,7 +3,9 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
project(sdrangelove)
set(CMAKE_BUILD_TYPE "Release")
#set(CMAKE_BUILD_TYPE "Release")
#set(CMAKE_BUILD_TYPE "ReleaseWithDebInfo")
set(CMAKE_BUILD_TYPE "Debug")
set(QT_USE_QTOPENGL TRUE)
set(CMAKE_AUTOMOC ON)
@ -24,12 +26,12 @@ find_package(FFTW3F)
add_definitions(${QT_DEFINITIONS})
if(MSVC)
foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES})
string(TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/bin_${OUTPUTCONFIG})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/bin_${OUTPUTCONFIG})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/bin_${OUTPUTCONFIG})
endforeach(OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES)
foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES})
string(TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/bin_${OUTPUTCONFIG})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/bin_${OUTPUTCONFIG})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/bin_${OUTPUTCONFIG})
endforeach(OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES)
endif()
##############################################################################
@ -61,6 +63,8 @@ set(sdrbase_SOURCES
sdrbase/gui/aboutdialog.cpp
sdrbase/gui/addpresetdialog.cpp
sdrbase/gui/buttonswitch.cpp
sdrbase/gui/channelwindow.cpp
sdrbase/gui/glscope.cpp
sdrbase/gui/glspectrum.cpp
sdrbase/gui/glspectrumgui.cpp
@ -68,6 +72,7 @@ set(sdrbase_SOURCES
sdrbase/gui/pluginsdialog.cpp
sdrbase/gui/preferencesdialog.cpp
sdrbase/gui/presetitem.cpp
sdrbase/gui/rollupwidget.cpp
sdrbase/gui/scale.cpp
sdrbase/gui/scaleengine.cpp
sdrbase/gui/scopewindow.cpp
@ -119,6 +124,8 @@ set(sdrbase_HEADERS
include-gpl/gui/aboutdialog.h
include-gpl/gui/addpresetdialog.h
include-gpl/gui/buttonswitch.h
include-gpl/gui/channelwindow.h
include-gpl/gui/glscope.h
include-gpl/gui/glspectrum.h
include-gpl/gui/glspectrumgui.h
@ -127,6 +134,7 @@ set(sdrbase_HEADERS
include-gpl/gui/pluginsdialog.h
include-gpl/gui/preferencesdialog.h
include-gpl/gui/presetitem.h
include/gui/rollupwidget.h
include-gpl/gui/scale.h
include-gpl/gui/scaleengine.h
include-gpl/gui/scopewindow.h

View File

@ -0,0 +1,19 @@
#ifndef INCLUDE_BUTTONSWITCH_H
#define INCLUDE_BUTTONSWITCH_H
#include <QToolButton>
class ButtonSwitch : public QToolButton {
Q_OBJECT
public:
ButtonSwitch(QWidget* parent = NULL);
private slots:
void onToggled(bool checked);
private:
QPalette m_originalPalette;
};
#endif // INCLUDE_BUTTONSWITCH_H

View File

@ -0,0 +1,25 @@
#ifndef INCLUDE_CHANNELWINDOW_H
#define INCLUDE_CHANNELWINDOW_H
#include <QScrollArea>
class QBoxLayout;
class QSpacerItem;
class RollupWidget;
class ChannelWindow : public QScrollArea {
Q_OBJECT
public:
ChannelWindow(QWidget* parent = NULL);
void addRollupWidget(QWidget* rollupWidget);
protected:
QWidget* m_container;
QBoxLayout* m_layout;
void resizeEvent(QResizeEvent* event);
};
#endif // INCLUDE_CHANNELWINDOW_H

View File

@ -37,7 +37,8 @@ public:
ModeIQ,
ModeMagLinPha,
ModeMagdBPha,
ModeDerived12
ModeDerived12,
ModeCyclostationary
};
GLScope(QWidget* parent = NULL);

View File

@ -39,7 +39,7 @@ public:
void setPowerRange(Real powerRange);
void setDisplayWaterfall(bool display);
void setInvertedWaterfall(bool inv);
void setDisplayLiveSpectrum(bool display);
void setDisplayMaxHold(bool display);
void setDisplayHistogram(bool display);
void addChannelMarker(ChannelMarker* channelMarker);
@ -84,9 +84,8 @@ private:
bool m_invertedWaterfall;
std::vector<Real> m_liveSpectrum;
bool m_displayLiveSpectrum;
bool m_liveSpectrumChanged;
std::vector<Real> m_maxHold;
bool m_displayMaxHold;
Real m_waterfallShare;

View File

@ -40,7 +40,7 @@ private:
Real m_powerRange;
bool m_displayWaterfall;
bool m_invertedWaterfall;
bool m_displayLiveSpectrum;
bool m_displayMaxHold;
bool m_displayHistogram;
void applySettings();
@ -53,7 +53,7 @@ private slots:
void on_decay_valueChanged(int value);
void on_waterfall_toggled(bool checked);
void on_histogram_toggled(bool checked);
void on_liveSpectrum_toggled(bool checked);
void on_maxHold_toggled(bool checked);
};
#endif // INCLUDE_GLSPECTRUMGUI_H

View File

@ -53,7 +53,8 @@ public:
MessageQueue* getMessageQueue() { return m_messageQueue; }
void addDemodCreateAction(QAction* action);
void addChannelCreateAction(QAction* action);
void addChannelRollup(QWidget* widget);
void addViewAction(QAction* action);
void addChannelMarker(ChannelMarker* channelMarker);
@ -67,7 +68,7 @@ private:
PItem
};
Ui::MainWindow *ui;
Ui::MainWindow* ui;
AudioDeviceInfo* m_audioDeviceInfo;

View File

@ -37,8 +37,10 @@ public:
const Plugins& getPlugins() const { return m_plugins; }
void registerDemodulator(const QString& demodName, PluginInterface* plugin, QAction* action);
void registerDemodulatorInstance(const QString& demodName, PluginGUI* pluginGUI);
void registerChannel(const QString& channelName, PluginInterface* plugin, QAction* action);
void registerChannelInstance(const QString& channelName, PluginGUI* pluginGUI);
void addChannelRollup(QWidget* pluginGUI);
void removeChannelInstance(PluginGUI* pluginGUI);
void registerSampleSource(const QString& sourceName, PluginInterface* plugin);
@ -54,33 +56,30 @@ public:
int selectSampleSource(int index);
int selectSampleSource(const QString& source);
private slots:
void demodInstanceDestroyed(QObject* object);
private:
struct DemodRegistration {
QString m_demodName;
struct ChannelRegistration {
QString m_channelName;
PluginInterface* m_plugin;
DemodRegistration(const QString& demodName, PluginInterface* plugin) :
m_demodName(demodName),
ChannelRegistration(const QString& channelName, PluginInterface* plugin) :
m_channelName(channelName),
m_plugin(plugin)
{ }
};
typedef QList<DemodRegistration> DemodRegistrations;
typedef QList<ChannelRegistration> ChannelRegistrations;
struct DemodInstanceRegistration {
QString m_demodName;
struct ChannelInstanceRegistration {
QString m_channelName;
PluginGUI* m_gui;
DemodInstanceRegistration() :
m_demodName(),
ChannelInstanceRegistration() :
m_channelName(),
m_gui(NULL)
{ }
DemodInstanceRegistration(const QString& demodName, PluginGUI* pluginGUI) :
m_demodName(demodName),
ChannelInstanceRegistration(const QString& channelName, PluginGUI* pluginGUI) :
m_channelName(channelName),
m_gui(pluginGUI)
{ }
};
typedef QList<DemodInstanceRegistration> DemodInstanceRegistrations;
typedef QList<ChannelInstanceRegistration> ChannelInstanceRegistrations;
struct SampleSourceRegistration {
QString m_sourceName;
@ -112,8 +111,8 @@ private:
DSPEngine* m_dspEngine;
Plugins m_plugins;
DemodRegistrations m_demodRegistrations;
DemodInstanceRegistrations m_demodInstanceRegistrations;
ChannelRegistrations m_channelRegistrations;
ChannelInstanceRegistrations m_channelInstanceRegistrations;
SampleSourceRegistrations m_sampleSourceRegistrations;
SampleSourceDevices m_sampleSourceDevices;
@ -121,7 +120,7 @@ private:
PluginGUI* m_sampleSourceInstance;
void loadPlugins(const QDir& dir);
void renameDemodInstances();
void renameChannelInstances();
};
static inline bool operator<(const PluginManager::Plugin& a, const PluginManager::Plugin& b)

View File

@ -7,16 +7,16 @@
class Preset {
public:
struct DemodConfig {
QString m_demod;
struct ChannelConfig {
QString m_channel;
QByteArray m_config;
DemodConfig(const QString& demod, const QByteArray& config) :
m_demod(demod),
ChannelConfig(const QString& channel, const QByteArray& config) :
m_channel(channel),
m_config(config)
{ }
};
typedef QList<DemodConfig> DemodConfigs;
typedef QList<ChannelConfig> ChannelConfigs;
Preset();
@ -49,10 +49,10 @@ public:
void setScopeConfig(const QByteArray& data) { m_scopeConfig = data; }
const QByteArray& getScopeConfig() const { return m_scopeConfig; }
void clearDemods() { m_demodConfigs.clear(); }
void addDemod(const QString& demod, const QByteArray& config) { m_demodConfigs.append(DemodConfig(demod, config)); }
int getDemodCount() const { return m_demodConfigs.count(); }
const DemodConfig& getDemodConfig(int index) const { return m_demodConfigs.at(index); }
void clearChannels() { m_channelConfigs.clear(); }
void addChannel(const QString& channel, const QByteArray& config) { m_channelConfigs.append(ChannelConfig(channel, config)); }
int getChannelCount() const { return m_channelConfigs.count(); }
const ChannelConfig& getChannelConfig(int index) const { return m_channelConfigs.at(index); }
void setSourceConfig(const QString& source, const QByteArray& generalConfig, const QByteArray& config)
{
@ -86,8 +86,8 @@ protected:
QByteArray m_sourceGeneralConfig;
QByteArray m_sourceConfig;
// demodulators and configurations
DemodConfigs m_demodConfigs;
// channels and configurations
ChannelConfigs m_channelConfigs;
// screen and dock layout
QByteArray m_layout;

View File

@ -0,0 +1,28 @@
#ifndef INCLUDE_DEMODWIDGET_H
#define INCLUDE_DEMODWIDGET_H
#include <QWidget>
class RollupWidget : public QWidget {
Q_OBJECT
public:
RollupWidget(QWidget* parent = NULL);
void addRollup(QWidget* rollup);
protected:
//QWidgetList m_rollups;
int arrangeRollups();
void paintEvent(QPaintEvent*);
int paintRollup(QWidget* rollup, int pos, QPainter* p, bool last, const QColor& frame);
void resizeEvent(QResizeEvent* size);
void mousePressEvent(QMouseEvent* event);
bool eventFilter(QObject* object, QEvent* event);
};
#endif // INCLUDE_DEMODWIDGET_H

View File

@ -25,10 +25,13 @@ public:
// MainWindow access
QDockWidget* createMainWindowDock(Qt::DockWidgetArea dockWidgetArea, const QString& title);
MessageQueue* getMainWindowMessageQueue();
void setInputGUI(QWidget* inputGUI);
// Demodulator stuff
void registerDemodulator(const QString& demodName, PluginInterface* plugin, QAction* action);
void registerDemodulatorInstance(const QString& demodName, PluginGUI* pluginGUI);
// Channel stuff
void registerChannel(const QString& channelName, PluginInterface* plugin, QAction* action);
void registerChannelInstance(const QString& channelName, PluginGUI* pluginGUI);
void addChannelRollup(QWidget* pluginGUI);
void removeChannelInstance(PluginGUI* pluginGUI);
void addChannelMarker(ChannelMarker* channelMarker);
void removeChannelMarker(ChannelMarker* channelMarker);

View File

@ -6,14 +6,12 @@
class Message;
class SDRANGELOVE_API PluginGUI : public QWidget {
Q_OBJECT
class SDRANGELOVE_API PluginGUI {
public:
PluginGUI(QWidget* parent = NULL);
PluginGUI() { };
virtual void destroy() = 0;
virtual void setWidgetName(const QString& name);
virtual void setName(const QString& name) = 0;
virtual void resetToDefaults() = 0;

View File

@ -37,7 +37,7 @@ public:
virtual const PluginDescriptor& getPluginDescriptor() const = 0;
virtual void initPlugin(PluginAPI* pluginAPI) = 0;
virtual PluginGUI* createDemod(const QString& demodName) { return NULL; }
virtual PluginGUI* createChannel(const QString& channelName) { return NULL; }
virtual SampleSourceDevices enumSampleSources() { return SampleSourceDevices(); }
virtual PluginGUI* createSampleSource(const QString& sourceName, const QByteArray& address) { return NULL; }

View File

@ -19,37 +19,73 @@
#include <QTextCodec>
#include <QProxyStyle>
#include <QStyleFactory>
#include <QFontDatabase>
#include "mainwindow.h"
static int runQtApplication(int argc, char* argv[])
{
QApplication a(argc, argv);
/*QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));*/
/*
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
*/
QCoreApplication::setOrganizationName("osmocom");
QCoreApplication::setApplicationName("SDRangelove");
//QApplication::setStyle(new QProxyStyle());
#if 0
#if 1
qApp->setStyle(QStyleFactory::create("fusion"));
QPalette palette;
palette.setColor(QPalette::Window, QColor(53,53,53));
palette.setColor(QPalette::WindowText, Qt::white);
palette.setColor(QPalette::Base, QColor(15,15,15));
palette.setColor(QPalette::Base, QColor(25,25,25));
palette.setColor(QPalette::AlternateBase, QColor(53,53,53));
palette.setColor(QPalette::ToolTipBase, Qt::white);
palette.setColor(QPalette::ToolTipText, Qt::white);
palette.setColor(QPalette::ToolTipText, Qt::black);
palette.setColor(QPalette::Text, Qt::white);
palette.setColor(QPalette::Button, QColor(53,53,53));
palette.setColor(QPalette::Button, QColor(0x40, 0x40, 0x40));
palette.setColor(QPalette::ButtonText, Qt::white);
palette.setColor(QPalette::BrightText, Qt::red);
palette.setColor(QPalette::Highlight, QColor(142,45,197).lighter());
palette.setColor(QPalette::Light, QColor(53,53,53).lighter(125).lighter());
palette.setColor(QPalette::Mid, QColor(53,53,53).lighter(125));
palette.setColor(QPalette::Dark, QColor(53,53,53).lighter(125).darker());
palette.setColor(QPalette::Link, QColor(0,0xa0,0xa0));
palette.setColor(QPalette::LinkVisited, QColor(0,0xa0,0xa0).lighter());
palette.setColor(QPalette::Highlight, QColor(0xff, 0x8c, 0x00));
palette.setColor(QPalette::HighlightedText, Qt::black);
qApp->setPalette(palette);
#if 0
if(QFontDatabase::addApplicationFont("/tmp/Cuprum.otf") >= 0) {
QFont font("CuprumFFU");
font.setPointSize(10);
qApp->setFont(font);
}
#endif
#if 0
if(QFontDatabase::addApplicationFont("/tmp/PTN57F.ttf") >= 0) {
QFont font("PT Sans Narrow");
font.setPointSize(10);
qApp->setFont(font);
}
#endif
#if 0
if(QFontDatabase::addApplicationFont("/tmp/PTS55F.ttf") >= 0) {
QFont font("PT Sans");
font.setPointSize(10);
qApp->setFont(font);
}
#endif
#if 0
{
QFont font("Ubuntu Condensed");
font.setPointSize(10);
qApp->setFont(font);
}
#endif
#endif
MainWindow w;
w.show();
@ -59,5 +95,7 @@ static int runQtApplication(int argc, char* argv[])
int main(int argc, char* argv[])
{
return runQtApplication(argc, argv);
int res = runQtApplication(argc, argv);
qDebug("regular program exit");
return res;
}

View File

@ -1,4 +1,5 @@
project(demod)
add_subdirectory(nfm)
add_subdirectory(tetra)
#add_subdirectory(nfm)
add_subdirectory(tcpsrc)
#add_subdirectory(tetra)

View File

@ -58,8 +58,6 @@ void NFMDemod::configure(MessageQueue* messageQueue, Real rfBandwidth, Real afBa
void NFMDemod::feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool firstOfBurst)
{
size_t count = end - begin;
Complex ci;
bool consumed;
@ -74,7 +72,7 @@ void NFMDemod::feed(SampleVector::const_iterator begin, SampleVector::const_iter
m_movingAverage.feed(ci.real() * ci.real() + ci.imag() * ci.imag());
if(m_movingAverage.average() >= m_squelchLevel)
m_squelchState = m_sampleRate / 100;
m_squelchState = m_sampleRate / 50;
if(m_squelchState > 0) {
m_squelchState--;
@ -89,8 +87,11 @@ void NFMDemod::feed(SampleVector::const_iterator begin, SampleVector::const_iter
m_audioBuffer[m_audioBufferFill].r = sample;
++m_audioBufferFill;
if(m_audioBufferFill >= m_audioBuffer.size()) {
if(m_audioFifo->write((const quint8*)&m_audioBuffer[0], m_audioBufferFill, 0) != m_audioBufferFill)
;//qDebug("lost samples");
uint res = m_audioFifo->write((const quint8*)&m_audioBuffer[0], m_audioBufferFill, 1);
/*
if(res != m_audioBufferFill)
qDebug("lost %u samples", m_audioBufferFill - res);
*/
m_audioBufferFill = 0;
}
}

View File

@ -139,7 +139,7 @@ NFMDemodGUI::NFMDemodGUI(PluginAPI* pluginAPI, QDockWidget* dockWidget, QWidget*
ui->glSpectrum->setCenterFrequency(0);
ui->glSpectrum->setSampleRate(44100);
ui->glSpectrum->setDisplayWaterfall(true);
ui->glSpectrum->setDisplayLiveSpectrum(true);
ui->glSpectrum->setDisplayMaxHold(true);
m_spectrumVis->configure(m_threadedSampleSink->getMessageQueue(), 64, 10, FFTWindow::BlackmanHarris);
m_channelMarker = new ChannelMarker(this);

View File

@ -0,0 +1,47 @@
project(tcpsrc)
set(tcpsrc_SOURCES
tcpsrc.cpp
tcpsrcgui.cpp
tcpsrcplugin.cpp
)
set(tcpsrc_HEADERS
tcpsrc.h
tcpsrcgui.h
tcpsrcplugin.h
)
set(tcpsrc_FORMS
tcpsrcgui.ui
)
include_directories(
.
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/include-gpl
${OPENGL_INCLUDE_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}
${OPENGL_LIBRARIES}
sdrbase
)
qt5_use_modules(demodtcpsrc Core Widgets OpenGL Network)

View File

@ -0,0 +1,82 @@
#include "tcpsrc.h"
#include "dsp/dspcommands.h"
MessageRegistrator TCPSrc::MsgConfigureTCPSrc::ID("MsgConfigureTCPSrc");
TCPSrc::TCPSrc(SampleSink* spectrum)
{
m_inputSampleRate = 100000;
m_sampleFormat = 0;
m_outputSampleRate = 50000;
m_rfBandwidth = 50000;
m_tcpPort = 9999;
m_nco.setFreq(0, m_inputSampleRate);
m_interpolator.create(16, m_inputSampleRate, m_rfBandwidth / 2.1);
m_sampleDistanceRemain = m_inputSampleRate / m_outputSampleRate;
m_spectrum = spectrum;
}
TCPSrc::~TCPSrc()
{
}
void TCPSrc::configure(MessageQueue* messageQueue, int sampleFormat, Real outputSampleRate, Real rfBandwidth, int tcpPort)
{
Message* cmd = MsgConfigureTCPSrc::create(sampleFormat, outputSampleRate, rfBandwidth, tcpPort);
cmd->submit(messageQueue, this);
}
void TCPSrc::feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool firstOfBurst)
{
Complex ci;
bool consumed;
for(SampleVector::const_iterator it = begin; it < end; ++it) {
Complex c(it->real() / 32768.0, it->imag() / 32768.0);
c *= m_nco.nextIQ();
consumed = false;
if(m_interpolator.interpolate(&m_sampleDistanceRemain, c, &consumed, &ci)) {
m_sampleBuffer.push_back(Sample(ci.real() * 32768.0, ci.imag() * 32768.0));
m_sampleDistanceRemain += m_inputSampleRate / m_outputSampleRate;
}
}
if(m_spectrum != NULL)
m_spectrum->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), firstOfBurst);
m_sampleBuffer.clear();
}
void TCPSrc::start()
{
}
void TCPSrc::stop()
{
}
bool TCPSrc::handleMessage(Message* cmd)
{
if(cmd->id() == DSPSignalNotification::ID()) {
DSPSignalNotification* signal = (DSPSignalNotification*)cmd;
qDebug("%d samples/sec, %lld Hz offset", signal->getSampleRate(), signal->getFrequencyOffset());
m_inputSampleRate = signal->getSampleRate();
m_nco.setFreq(-signal->getFrequencyOffset(), m_inputSampleRate);
m_interpolator.create(16, m_inputSampleRate, m_rfBandwidth / 2.1);
m_sampleDistanceRemain = m_inputSampleRate / m_outputSampleRate;
cmd->completed();
return true;
} else if(cmd->id() == MsgConfigureTCPSrc::ID()) {
MsgConfigureTCPSrc* cfg = (MsgConfigureTCPSrc*)cmd;
m_sampleFormat = cfg->getSampleFormat();
m_outputSampleRate = cfg->getOutputSampleRate();
m_rfBandwidth = cfg->getRFBandwidth();
m_tcpPort = cfg->getTCPPort();
m_interpolator.create(16, m_inputSampleRate, m_rfBandwidth / 2.1);
m_sampleDistanceRemain = m_inputSampleRate / m_outputSampleRate;
cmd->completed();
return true;
} else {
return false;
}
}

View File

@ -0,0 +1,66 @@
#ifndef INCLUDE_TCPSRC_H
#define INCLUDE_TCPSRC_H
#include "dsp/samplesink.h"
#include "dsp/nco.h"
#include "dsp/interpolator.h"
#include "util/message.h"
class TCPSrc : public SampleSink {
public:
TCPSrc(SampleSink* spectrum);
~TCPSrc();
void configure(MessageQueue* messageQueue, int sampleFormat, Real outputSampleRate, Real rfBandwidth, int tcpPort);
void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool firstOfBurst);
void start();
void stop();
bool handleMessage(Message* cmd);
protected:
class MsgConfigureTCPSrc : public Message {
public:
static MessageRegistrator ID;
int getSampleFormat() const { return m_sampleFormat; }
Real getOutputSampleRate() const { return m_outputSampleRate; }
Real getRFBandwidth() const { return m_rfBandwidth; }
int getTCPPort() const { return m_tcpPort; }
static MsgConfigureTCPSrc* create(int sampleFormat, Real sampleRate, Real rfBandwidth, int tcpPort)
{
return new MsgConfigureTCPSrc(sampleFormat, sampleRate, rfBandwidth, tcpPort);
}
private:
int m_sampleFormat;
Real m_outputSampleRate;
Real m_rfBandwidth;
int m_tcpPort;
MsgConfigureTCPSrc(int sampleFormat, Real outputSampleRate, Real rfBandwidth, int tcpPort) :
Message(ID()),
m_sampleFormat(sampleFormat),
m_outputSampleRate(outputSampleRate),
m_rfBandwidth(rfBandwidth),
m_tcpPort(tcpPort)
{ }
};
int m_inputSampleRate;
int m_sampleFormat;
Real m_outputSampleRate;
Real m_rfBandwidth;
int m_tcpPort;
NCO m_nco;
Interpolator m_interpolator;
Real m_sampleDistanceRemain;
SampleVector m_sampleBuffer;
SampleSink* m_spectrum;
};
#endif // INCLUDE_TCPSRC_H

View File

@ -0,0 +1,147 @@
#include "tcpsrcgui.h"
#include "plugin/pluginapi.h"
#include "tcpsrc.h"
#include "dsp/channelizer.h"
#include "dsp/spectrumvis.h"
#include "dsp/threadedsamplesink.h"
#include "ui_tcpsrcgui.h"
TCPSrcGUI* TCPSrcGUI::create(PluginAPI* pluginAPI)
{
TCPSrcGUI* gui = new TCPSrcGUI(pluginAPI);
return gui;
}
void TCPSrcGUI::destroy()
{
delete this;
}
void TCPSrcGUI::setName(const QString& name)
{
setObjectName(name);
}
void TCPSrcGUI::resetToDefaults()
{
ui->sampleFormat->setCurrentIndex(0);
ui->sampleRate->setText("25000");
ui->rfBandwidth->setText("20000");
ui->tcpPort->setText("9999");
applySettings();
}
QByteArray TCPSrcGUI::serialize() const
{
return QByteArray();
}
bool TCPSrcGUI::deserialize(const QByteArray& data)
{
return false;
}
bool TCPSrcGUI::handleMessage(Message* message)
{
return false;
}
void TCPSrcGUI::channelMarkerChanged()
{
applySettings();
}
TCPSrcGUI::TCPSrcGUI(PluginAPI* pluginAPI, QWidget* parent) :
RollupWidget(parent),
ui(new Ui::TCPSrcGUI),
m_pluginAPI(pluginAPI)
{
ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose, true);
m_spectrumVis = new SpectrumVis(ui->glSpectrum);
m_tcpSrc = new TCPSrc(m_spectrumVis);
m_channelizer = new Channelizer(m_tcpSrc);
m_threadedSampleSink = new ThreadedSampleSink(m_channelizer);
m_pluginAPI->addSampleSink(m_threadedSampleSink);
ui->glSpectrum->setCenterFrequency(0);
ui->glSpectrum->setSampleRate(ui->sampleRate->text().toInt());
ui->glSpectrum->setDisplayWaterfall(true);
ui->glSpectrum->setDisplayMaxHold(true);
m_spectrumVis->configure(m_threadedSampleSink->getMessageQueue(), 64, 10, FFTWindow::BlackmanHarris);
m_channelMarker = new ChannelMarker(this);
m_channelMarker->setColor(Qt::red);
m_channelMarker->setBandwidth(25000);
m_channelMarker->setCenterFrequency(0);
m_channelMarker->setVisible(true);
connect(m_channelMarker, SIGNAL(changed()), this, SLOT(channelMarkerChanged()));
m_pluginAPI->addChannelMarker(m_channelMarker);
applySettings();
}
TCPSrcGUI::~TCPSrcGUI()
{
m_pluginAPI->removeChannelInstance(this);
delete ui;
}
void TCPSrcGUI::applySettings()
{
bool ok;
Real outputSampleRate = ui->sampleRate->text().toDouble(&ok);
if((!ok) || (outputSampleRate < 100))
outputSampleRate = 25000;
Real rfBandwidth = ui->rfBandwidth->text().toDouble(&ok);
if((!ok) || (rfBandwidth > outputSampleRate))
rfBandwidth = outputSampleRate / 1.05;
int tcpPort = ui->tcpPort->text().toInt(&ok);
if((!ok) || (tcpPort < 1) || (tcpPort > 65535))
tcpPort = 9999;
ui->sampleRate->setText(QString("%1").arg(outputSampleRate, 0));
ui->rfBandwidth->setText(QString("%1").arg(rfBandwidth, 0));
ui->tcpPort->setText(QString("%1").arg(tcpPort));
m_channelMarker->setBandwidth(rfBandwidth);
ui->glSpectrum->setSampleRate(outputSampleRate);
m_channelizer->configure(m_threadedSampleSink->getMessageQueue(),
outputSampleRate,
m_channelMarker->getCenterFrequency());
m_tcpSrc->configure(m_threadedSampleSink->getMessageQueue(),
ui->sampleFormat->currentIndex(),
outputSampleRate,
rfBandwidth,
tcpPort);
ui->applyBtn->setEnabled(false);
}
void TCPSrcGUI::on_sampleFormat_currentIndexChanged(int index)
{
ui->applyBtn->setEnabled(true);
}
void TCPSrcGUI::on_sampleRate_textEdited(const QString& arg1)
{
ui->applyBtn->setEnabled(true);
}
void TCPSrcGUI::on_rfBandwidth_textEdited(const QString& arg1)
{
ui->applyBtn->setEnabled(true);
}
void TCPSrcGUI::on_tcpPort_textEdited(const QString& arg1)
{
ui->applyBtn->setEnabled(true);
}
void TCPSrcGUI::on_applyBtn_clicked()
{
applySettings();
}

View File

@ -0,0 +1,59 @@
#ifndef INCLUDE_TCPSRCGUI_H
#define INCLUDE_TCPSRCGUI_H
#include "gui/rollupwidget.h"
#include "plugin/plugingui.h"
class PluginAPI;
class ChannelMarker;
class ThreadedSampleSink;
class Channelizer;
class TCPSrc;
class SpectrumVis;
namespace Ui {
class TCPSrcGUI;
}
class TCPSrcGUI : public RollupWidget, public PluginGUI {
Q_OBJECT
public:
static TCPSrcGUI* create(PluginAPI* pluginAPI);
void destroy();
void setName(const QString& name);
void resetToDefaults();
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
bool handleMessage(Message* message);
private slots:
void channelMarkerChanged();
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();
private:
Ui::TCPSrcGUI* ui;
PluginAPI* m_pluginAPI;
ChannelMarker* m_channelMarker;
// RF path
ThreadedSampleSink* m_threadedSampleSink;
Channelizer* m_channelizer;
TCPSrc* m_tcpSrc;
SpectrumVis* m_spectrumVis;
explicit TCPSrcGUI(PluginAPI* pluginAPI, QWidget* parent = NULL);
~TCPSrcGUI();
void applySettings();
};
#endif // INCLUDE_TCPSRCGUI_H

View File

@ -0,0 +1,198 @@
<?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="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="margin">
<number>2</number>
</property>
<property name="spacing">
<number>3</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Sample Format</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="tcpPort">
<property name="text">
<string>9999</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>RF Bandwidth</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="sampleRate">
<property name="text">
<string>25000</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="rfBandwidth">
<property name="text">
<string>20000</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Samplerate</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="0" column="1">
<widget class="QComboBox" name="sampleFormat">
<item>
<property name="text">
<string>S8 I/Q</string>
</property>
</item>
<item>
<property name="text">
<string>S16LE I/Q</string>
</property>
</item>
</widget>
</item>
<item row="4" column="1">
<widget class="QPushButton" name="applyBtn">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Apply</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="widget_3" 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="margin">
<number>2</number>
</property>
<item>
<widget class="GLSpectrum" name="glSpectrum" native="true"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="widget_2" 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</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>3</number>
</property>
<property name="margin">
<number>2</number>
</property>
<item>
<widget class="QTreeWidget" name="treeWidget">
<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>
</customwidgets>
<tabstops>
<tabstop>sampleFormat</tabstop>
<tabstop>sampleRate</tabstop>
<tabstop>rfBandwidth</tabstop>
<tabstop>tcpPort</tabstop>
<tabstop>applyBtn</tabstop>
<tabstop>treeWidget</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,55 @@
#include <QtPlugin>
#include <QAction>
#include "plugin/pluginapi.h"
#include "tcpsrcplugin.h"
#include "tcpsrcgui.h"
const PluginDescriptor TCPSrcPlugin::m_pluginDescriptor = {
QString("TCP Channel Source"),
QString("---"),
QString("(c) maintech GmbH (written by Christian Daniel)"),
QString("http://www.maintech.de"),
true,
QString("http://www.maintech.de")
};
TCPSrcPlugin::TCPSrcPlugin(QObject* parent) :
QObject(parent)
{
}
const PluginDescriptor& TCPSrcPlugin::getPluginDescriptor() const
{
return m_pluginDescriptor;
}
void TCPSrcPlugin::initPlugin(PluginAPI* pluginAPI)
{
m_pluginAPI = pluginAPI;
// register TCP Channel Source
QAction* action = new QAction(tr("&TCP Source"), this);
connect(action, SIGNAL(triggered()), this, SLOT(createInstanceTCPSrc()));
m_pluginAPI->registerChannel("de.maintech.sdrangelove.channel.tcpsrc", this, action);
}
PluginGUI* TCPSrcPlugin::createChannel(const QString& channelName)
{
if(channelName == "de.maintech.sdrangelove.channel.tcpsrc") {
TCPSrcGUI* gui = TCPSrcGUI::create(m_pluginAPI);
m_pluginAPI->registerChannelInstance("de.maintech.sdrangelove.channel.tcpsrc", gui);
m_pluginAPI->addChannelRollup(gui);
return gui;
} else {
return NULL;
}
}
void TCPSrcPlugin::createInstanceTCPSrc()
{
TCPSrcGUI* gui = TCPSrcGUI::create(m_pluginAPI);
m_pluginAPI->registerChannelInstance("de.maintech.sdrangelove.channel.tcpsrc", gui);
m_pluginAPI->addChannelRollup(gui);
//m_pluginAPI->registerChannelInstance("de.maintech.sdrangelove.channel.tcpsrc", TCPSrcGUI::create(m_pluginAPI));
}

View File

@ -0,0 +1,29 @@
#ifndef INCLUDE_TCPSRCPLUGIN_H
#define INCLUDE_TCPSRCPLUGIN_H
#include <QObject>
#include "plugin/plugininterface.h"
class TCPSrcPlugin : public QObject, PluginInterface {
Q_OBJECT
Q_INTERFACES(PluginInterface)
Q_PLUGIN_METADATA(IID "de.maintech.sdrangelove.demod.tcpsrc")
public:
explicit TCPSrcPlugin(QObject* parent = NULL);
const PluginDescriptor& getPluginDescriptor() const;
void initPlugin(PluginAPI* pluginAPI);
PluginGUI* createChannel(const QString& channelName);
private:
static const PluginDescriptor m_pluginDescriptor;
PluginAPI* m_pluginAPI;
private slots:
void createInstanceTCPSrc();
};
#endif // INCLUDE_TCPSRCPLUGIN_H

View File

@ -79,7 +79,7 @@ TetraDemodGUI::TetraDemodGUI(PluginAPI* pluginAPI, QDockWidget* dockWidget, QWid
ui->glSpectrum->setCenterFrequency(0);
ui->glSpectrum->setSampleRate(36000);
ui->glSpectrum->setDisplayWaterfall(true);
ui->glSpectrum->setDisplayLiveSpectrum(true);
ui->glSpectrum->setDisplayMaxHold(true);
m_spectrumVis->configure(m_threadedSampleSink->getMessageQueue(), 64, 10, FFTWindow::BlackmanHarris);
m_channelMarker = new ChannelMarker(this);

View File

@ -3,7 +3,7 @@
#include "plugin/pluginapi.h"
OsmoSDRGui::OsmoSDRGui(PluginAPI* pluginAPI, QWidget* parent) :
PluginGUI(parent),
QWidget(parent),
ui(new Ui::OsmoSDRGui),
m_pluginAPI(pluginAPI),
m_settings(),
@ -28,6 +28,11 @@ void OsmoSDRGui::destroy()
delete this;
}
void OsmoSDRGui::setName(const QString& name)
{
setObjectName(name);
}
void OsmoSDRGui::resetToDefaults()
{
m_generalSettings.resetToDefaults();

View File

@ -11,7 +11,7 @@ namespace Ui {
class OsmoSDRGui;
}
class OsmoSDRGui : public PluginGUI {
class OsmoSDRGui : public QWidget, public PluginGUI {
Q_OBJECT
public:
@ -19,6 +19,8 @@ public:
~OsmoSDRGui();
void destroy();
void setName(const QString& name);
void resetToDefaults();
QByteArray serializeGeneral() const;
bool deserializeGeneral(const QByteArray&data);
@ -28,14 +30,6 @@ public:
bool handleMessage(Message* message);
private:
/*
Ui::OsmoSDRGui* ui;
MessageQueue* m_msgQueue;
OsmoSDRInput::Settings m_settings;
QTimer m_updateTimer;
*/
Ui::OsmoSDRGui* ui;
PluginAPI* m_pluginAPI;

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>253</width>
<height>224</height>
<height>229</height>
</rect>
</property>
<property name="sizePolicy">
@ -118,10 +118,7 @@
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksAbove</enum>
</property>
<property name="tickInterval">
<number>1</number>
<enum>QSlider::TicksBelow</enum>
</property>
</widget>
</item>

View File

@ -48,17 +48,21 @@ PluginInterface::SampleSourceDevices OsmoSDRPlugin::enumSampleSources()
if(osmosdr_get_device_usb_strings(i, vendor, product, serial) != 0)
continue;