NFMDemod: ported to reworked API - credits go to Dimitri "horizon" Stolnikov

This commit is contained in:
Christian Daniel 2013-11-04 22:01:28 +01:00
parent 221869a898
commit ba220b717a
7 changed files with 290 additions and 216 deletions

View File

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

View File

@ -140,6 +140,8 @@ bool NFMDemod::handleMessage(Message* cmd)
cmd->completed(); cmd->completed();
return true; return true;
} else { } else {
return false; if(m_sampleSink != NULL)
return m_sampleSink->handleMessage(cmd);
else return false;
} }
} }

View File

@ -11,6 +11,7 @@
#include "gui/glspectrum.h" #include "gui/glspectrum.h"
#include "plugin/pluginapi.h" #include "plugin/pluginapi.h"
#include "util/simpleserializer.h" #include "util/simpleserializer.h"
#include "gui/basicchannelsettingswidget.h"
const int NFMDemodGUI::m_rfBW[] = { const int NFMDemodGUI::m_rfBW[] = {
5000, 6250, 8330, 10000, 12500, 15000, 20000, 25000, 40000 5000, 6250, 8330, 10000, 12500, 15000, 20000, 25000, 40000
@ -18,22 +19,18 @@ const int NFMDemodGUI::m_rfBW[] = {
NFMDemodGUI* NFMDemodGUI::create(PluginAPI* pluginAPI) NFMDemodGUI* NFMDemodGUI::create(PluginAPI* pluginAPI)
{ {
QDockWidget* dock = pluginAPI->createMainWindowDock(Qt::RightDockWidgetArea, tr("NFM Demodulator")); NFMDemodGUI* gui = new NFMDemodGUI(pluginAPI);
dock->setObjectName(QString::fromUtf8("NFM Demodulator"));
NFMDemodGUI* gui = new NFMDemodGUI(pluginAPI, dock);
dock->setWidget(gui);
return gui; return gui;
} }
void NFMDemodGUI::destroy() void NFMDemodGUI::destroy()
{ {
delete m_dockWidget; delete this;
} }
void NFMDemodGUI::setWidgetName(const QString& name) void NFMDemodGUI::setName(const QString& name)
{ {
qDebug("NFM: %s", qPrintable(name)); setObjectName(name);
m_dockWidget->setObjectName(name);
} }
void NFMDemodGUI::resetToDefaults() void NFMDemodGUI::resetToDefaults()
@ -42,6 +39,7 @@ void NFMDemodGUI::resetToDefaults()
ui->afBW->setValue(3); ui->afBW->setValue(3);
ui->volume->setValue(20); ui->volume->setValue(20);
ui->squelch->setValue(-40); ui->squelch->setValue(-40);
ui->spectrumGUI->resetToDefaults();
applySettings(); applySettings();
} }
@ -53,6 +51,8 @@ QByteArray NFMDemodGUI::serialize() const
s.writeS32(3, ui->afBW->value()); s.writeS32(3, ui->afBW->value());
s.writeS32(4, ui->volume->value()); s.writeS32(4, ui->volume->value());
s.writeS32(5, ui->squelch->value()); s.writeS32(5, ui->squelch->value());
s.writeBlob(6, ui->spectrumGUI->serialize());
s.writeU32(7, m_channelMarker->getColor().rgb());
return s.final(); return s.final();
} }
@ -66,6 +66,8 @@ bool NFMDemodGUI::deserialize(const QByteArray& data)
} }
if(d.getVersion() == 1) { if(d.getVersion() == 1) {
QByteArray bytetmp;
quint32 u32tmp;
qint32 tmp; qint32 tmp;
d.readS32(1, &tmp, 0); d.readS32(1, &tmp, 0);
m_channelMarker->setCenterFrequency(tmp); m_channelMarker->setCenterFrequency(tmp);
@ -77,6 +79,10 @@ bool NFMDemodGUI::deserialize(const QByteArray& data)
ui->volume->setValue(tmp); ui->volume->setValue(tmp);
d.readS32(5, &tmp, -40); d.readS32(5, &tmp, -40);
ui->squelch->setValue(tmp); ui->squelch->setValue(tmp);
d.readBlob(6, &bytetmp);
ui->spectrumGUI->deserialize(bytetmp);
if(d.readU32(7, &u32tmp))
m_channelMarker->setColor(u32tmp);
applySettings(); applySettings();
return true; return true;
} else { } else {
@ -120,13 +126,34 @@ void NFMDemodGUI::on_squelch_valueChanged(int value)
applySettings(); applySettings();
} }
NFMDemodGUI::NFMDemodGUI(PluginAPI* pluginAPI, QDockWidget* dockWidget, QWidget* parent) :
PluginGUI(parent), void NFMDemodGUI::onWidgetRolled(QWidget* widget, bool rollDown)
{
/*
if((widget == ui->spectrumContainer) && (m_nfmDemod != NULL))
m_nfmDemod->setSpectrum(m_threadedSampleSink->getMessageQueue(), rollDown);
*/
}
void NFMDemodGUI::onMenuDoubleClicked()
{
if(!m_basicSettingsShown) {
m_basicSettingsShown = true;
BasicChannelSettingsWidget* bcsw = new BasicChannelSettingsWidget(m_channelMarker, this);
bcsw->show();
}
}
NFMDemodGUI::NFMDemodGUI(PluginAPI* pluginAPI, QWidget* parent) :
RollupWidget(parent),
ui(new Ui::NFMDemodGUI), ui(new Ui::NFMDemodGUI),
m_pluginAPI(pluginAPI), m_pluginAPI(pluginAPI),
m_dockWidget(dockWidget) m_basicSettingsShown(false)
{ {
ui->setupUi(this); ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose, true);
connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool)));
connect(this, SIGNAL(menuDoubleClickEvent()), this, SLOT(onMenuDoubleClicked()));
m_audioFifo = new AudioFifo(4, 44100 / 4); m_audioFifo = new AudioFifo(4, 44100 / 4);
m_spectrumVis = new SpectrumVis(ui->glSpectrum); m_spectrumVis = new SpectrumVis(ui->glSpectrum);
@ -150,11 +177,14 @@ NFMDemodGUI::NFMDemodGUI(PluginAPI* pluginAPI, QDockWidget* dockWidget, QWidget*
connect(m_channelMarker, SIGNAL(changed()), this, SLOT(viewChanged())); connect(m_channelMarker, SIGNAL(changed()), this, SLOT(viewChanged()));
m_pluginAPI->addChannelMarker(m_channelMarker); m_pluginAPI->addChannelMarker(m_channelMarker);
ui->spectrumGUI->setBuddies(m_threadedSampleSink->getMessageQueue(), m_spectrumVis, ui->glSpectrum);
applySettings(); applySettings();
} }
NFMDemodGUI::~NFMDemodGUI() NFMDemodGUI::~NFMDemodGUI()
{ {
m_pluginAPI->removeChannelInstance(this);
m_pluginAPI->removeAudioSource(m_audioFifo); m_pluginAPI->removeAudioSource(m_audioFifo);
m_pluginAPI->removeSampleSink(m_threadedSampleSink); m_pluginAPI->removeSampleSink(m_threadedSampleSink);
delete m_threadedSampleSink; delete m_threadedSampleSink;
@ -168,6 +198,7 @@ NFMDemodGUI::~NFMDemodGUI()
void NFMDemodGUI::applySettings() void NFMDemodGUI::applySettings()
{ {
setTitleColor(m_channelMarker->getColor());
m_channelizer->configure(m_threadedSampleSink->getMessageQueue(), m_channelizer->configure(m_threadedSampleSink->getMessageQueue(),
44100, 44100,
m_channelMarker->getCenterFrequency()); m_channelMarker->getCenterFrequency());

View File

@ -1,10 +1,9 @@
#ifndef INCLUDE_NFMDEMODGUI_H #ifndef INCLUDE_NFMDEMODGUI_H
#define INCLUDE_NFMDEMODGUI_H #define INCLUDE_NFMDEMODGUI_H
#include "gui/rollupwidget.h"
#include "plugin/plugingui.h" #include "plugin/plugingui.h"
class QDockWidget;
class PluginAPI; class PluginAPI;
class ChannelMarker; class ChannelMarker;
@ -18,14 +17,14 @@ namespace Ui {
class NFMDemodGUI; class NFMDemodGUI;
} }
class NFMDemodGUI : public PluginGUI { class NFMDemodGUI : public RollupWidget, public PluginGUI {
Q_OBJECT Q_OBJECT
public: public:
static NFMDemodGUI* create(PluginAPI* pluginAPI); static NFMDemodGUI* create(PluginAPI* pluginAPI);
void destroy(); void destroy();
void setWidgetName(const QString& name); void setName(const QString& name);
void resetToDefaults(); void resetToDefaults();
QByteArray serialize() const; QByteArray serialize() const;
@ -39,12 +38,14 @@ private slots:
void on_afBW_valueChanged(int value); void on_afBW_valueChanged(int value);
void on_volume_valueChanged(int value); void on_volume_valueChanged(int value);
void on_squelch_valueChanged(int value); void on_squelch_valueChanged(int value);
void onWidgetRolled(QWidget* widget, bool rollDown);
void onMenuDoubleClicked();
private: private:
Ui::NFMDemodGUI* ui; Ui::NFMDemodGUI* ui;
PluginAPI* m_pluginAPI; PluginAPI* m_pluginAPI;
QDockWidget* m_dockWidget;
ChannelMarker* m_channelMarker; ChannelMarker* m_channelMarker;
bool m_basicSettingsShown;
AudioFifo* m_audioFifo; AudioFifo* m_audioFifo;
ThreadedSampleSink* m_threadedSampleSink; ThreadedSampleSink* m_threadedSampleSink;
@ -52,10 +53,9 @@ private:
NFMDemod* m_nfmDemod; NFMDemod* m_nfmDemod;
SpectrumVis* m_spectrumVis; SpectrumVis* m_spectrumVis;
static const QString m_demodName;
static const int m_rfBW[]; static const int m_rfBW[];
explicit NFMDemodGUI(PluginAPI* pluginAPI, QDockWidget* dockWidget, QWidget* parent = NULL); explicit NFMDemodGUI(PluginAPI* pluginAPI, QWidget* parent = NULL);
~NFMDemodGUI(); ~NFMDemodGUI();
void applySettings(); void applySettings();

View File

@ -1,202 +1,229 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"> <ui version="4.0">
<class>NFMDemodGUI</class> <class>NFMDemodGUI</class>
<widget class="QWidget" name="NFMDemodGUI"> <widget class="RollupWidget" name="NFMDemodGUI">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>208</width> <width>302</width>
<height>226</height> <height>410</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Form</string> <string>NFM Demodulator</string>
</property> </property>
<layout class="QVBoxLayout"> <widget class="QWidget" name="settingsContainer" native="true">
<property name="spacing"> <property name="geometry">
<number>3</number> <rect>
<x>35</x>
<y>35</y>
<width>242</width>
<height>96</height>
</rect>
</property> </property>
<property name="margin"> <property name="windowTitle">
<number>0</number> <string>Settings</string>
</property> </property>
<item> <layout class="QGridLayout" name="gridLayout">
<widget class="GLSpectrum" name="glSpectrum" native="true"> <property name="margin">
<property name="minimumSize"> <number>2</number>
<size> </property>
<width>200</width> <property name="spacing">
<height>150</height> <number>3</number>
</size> </property>
</property> <item row="0" column="0">
</widget> <widget class="QLabel" name="label">
</item> <property name="text">
<item> <string>RF Bandwidth</string>
<layout class="QGridLayout" name="gridLayout"> </property>
<property name="margin"> </widget>
<number>2</number> </item>
</property> <item row="0" column="1">
<property name="spacing"> <widget class="QSlider" name="rfBW">
<number>3</number> <property name="maximum">
</property> <number>8</number>
<item row="0" column="1"> </property>
<widget class="QSlider" name="rfBW"> <property name="pageStep">
<property name="maximum"> <number>1</number>
<number>8</number> </property>
</property> <property name="value">
<property name="pageStep"> <number>4</number>
<number>1</number> </property>
</property> <property name="orientation">
<property name="value"> <enum>Qt::Horizontal</enum>
<number>4</number> </property>
</property> </widget>
<property name="orientation"> </item>
<enum>Qt::Horizontal</enum> <item row="0" column="2">
</property> <widget class="QLabel" name="rfBWText">
</widget> <property name="minimumSize">
</item> <size>
<item row="0" column="0"> <width>50</width>
<widget class="QLabel" name="label"> <height>0</height>
<property name="text"> </size>
<string>RF Bandwidth</string> </property>
</property> <property name="text">
</widget> <string>12.5kHz</string>
</item> </property>
<item row="2" column="0"> <property name="alignment">
<widget class="QLabel" name="label_2"> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
<property name="text"> </property>
<string>AF Bandwidth</string> </widget>
</property> </item>
</widget> <item row="1" column="0">
</item> <widget class="QLabel" name="label_2">
<item row="4" column="0"> <property name="text">
<widget class="QLabel" name="label_4"> <string>AF Bandwidth</string>
<property name="text"> </property>
<string>Squelch</string> </widget>
</property> </item>
</widget> <item row="1" column="1">
</item> <widget class="QSlider" name="afBW">
<item row="3" column="0"> <property name="minimum">
<widget class="QLabel" name="label_3"> <number>1</number>
<property name="text"> </property>
<string>Volume</string> <property name="maximum">
</property> <number>20</number>
</widget> </property>
</item> <property name="pageStep">
<item row="0" column="2"> <number>1</number>
<widget class="QLabel" name="rfBWText"> </property>
<property name="minimumSize"> <property name="value">
<size> <number>3</number>
<width>50</width> </property>
<height>0</height> <property name="orientation">
</size> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="text"> </widget>
<string>12.5kHz</string> </item>
</property> <item row="1" column="2">
<property name="alignment"> <widget class="QLabel" name="afBWText">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> <property name="minimumSize">
</property> <size>
</widget> <width>50</width>
</item> <height>0</height>
<item row="2" column="1"> </size>
<widget class="QSlider" name="afBW"> </property>
<property name="minimum"> <property name="text">
<number>1</number> <string>3 kHz</string>
</property> </property>
<property name="maximum"> <property name="alignment">
<number>20</number> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property> </property>
<property name="pageStep"> </widget>
<number>1</number> </item>
</property> <item row="2" column="0">
<property name="value"> <widget class="QLabel" name="label_3">
<number>3</number> <property name="text">
</property> <string>Volume</string>
<property name="orientation"> </property>
<enum>Qt::Horizontal</enum> </widget>
</property> </item>
</widget> <item row="2" column="1">
</item> <widget class="QSlider" name="volume">
<item row="3" column="1"> <property name="maximum">
<widget class="QSlider" name="volume"> <number>100</number>
<property name="maximum"> </property>
<number>100</number> <property name="value">
</property> <number>20</number>
<property name="value"> </property>
<number>20</number> <property name="orientation">
</property> <enum>Qt::Horizontal</enum>
<property name="orientation"> </property>
<enum>Qt::Horizontal</enum> </widget>
</property> </item>
</widget> <item row="2" column="2">
</item> <widget class="QLabel" name="volumeText">
<item row="4" column="1"> <property name="minimumSize">
<widget class="QSlider" name="squelch"> <size>
<property name="minimum"> <width>50</width>
<number>-100</number> <height>0</height>
</property> </size>
<property name="maximum"> </property>
<number>0</number> <property name="text">
</property> <string>2.0</string>
<property name="value"> </property>
<number>-40</number> <property name="alignment">
</property> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
<property name="orientation"> </property>
<enum>Qt::Horizontal</enum> </widget>
</property> </item>
</widget> <item row="3" column="0">
</item> <widget class="QLabel" name="label_4">
<item row="2" column="2"> <property name="text">
<widget class="QLabel" name="afBWText"> <string>Squelch</string>
<property name="minimumSize"> </property>
<size> </widget>
<width>50</width> </item>
<height>0</height> <item row="3" column="1">
</size> <widget class="QSlider" name="squelch">
</property> <property name="minimum">
<property name="text"> <number>-100</number>
<string>3 kHz</string> </property>
</property> <property name="maximum">
<property name="alignment"> <number>0</number>
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> </property>
</property> <property name="value">
</widget> <number>-40</number>
</item> </property>
<item row="3" column="2"> <property name="orientation">
<widget class="QLabel" name="volumeText"> <enum>Qt::Horizontal</enum>
<property name="minimumSize"> </property>
<size> </widget>
<width>50</width> </item>
<height>0</height> <item row="3" column="2">
</size> <widget class="QLabel" name="squelchText">
</property> <property name="minimumSize">
<property name="text"> <size>
<string>2.0</string> <width>50</width>
</property> <height>0</height>
<property name="alignment"> </size>
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> </property>
</property> <property name="text">
</widget> <string>-40dB</string>
</item> </property>
<item row="4" column="2"> <property name="alignment">
<widget class="QLabel" name="squelchText"> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
<property name="minimumSize"> </property>
<size> </widget>
<width>50</width> </item>
<height>0</height> </layout>
</size> </widget>
</property> <widget class="QWidget" name="spectrumContainer" native="true">
<property name="text"> <property name="geometry">
<string>-40dB</string> <rect>
</property> <x>40</x>
<property name="alignment"> <y>140</y>
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> <width>218</width>
</property> <height>184</height>
</widget> </rect>
</item> </property>
</layout> <property name="windowTitle">
</item> <string>Channel Spectrum</string>
</layout> </property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>2</number>
</property>
<property name="margin">
<number>3</number>
</property>
<item>
<widget class="GLSpectrum" name="glSpectrum" native="true">
<property name="minimumSize">
<size>
<width>200</width>
<height>150</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="GLSpectrumGUI" name="spectrumGUI" native="true"/>
</item>
</layout>
</widget>
</widget> </widget>
<customwidgets> <customwidgets>
<customwidget> <customwidget>
@ -205,6 +232,18 @@
<header>gui/glspectrum.h</header> <header>gui/glspectrum.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget>
<class>GLSpectrumGUI</class>
<extends>QWidget</extends>
<header>gui/glspectrumgui.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>RollupWidget</class>
<extends>QWidget</extends>
<header>gui/rollupwidget.h</header>
<container>1</container>
</customwidget>
</customwidgets> </customwidgets>
<resources/> <resources/>
<connections/> <connections/>

View File

@ -28,16 +28,17 @@ void NFMPlugin::initPlugin(PluginAPI* pluginAPI)
m_pluginAPI = pluginAPI; m_pluginAPI = pluginAPI;
// register NFM demodulator // register NFM demodulator
QAction* action = new QAction(tr("&NFM"), this); QAction* action = new QAction(tr("&NFM Demodulator"), this);
connect(action, SIGNAL(triggered()), this, SLOT(createInstanceNFM())); connect(action, SIGNAL(triggered()), this, SLOT(createInstanceNFM()));
m_pluginAPI->registerDemodulator("de.maintech.sdrangelove.demod.nfm", this, action); m_pluginAPI->registerChannel("de.maintech.sdrangelove.channel.nfm", this, action);
} }
PluginGUI* NFMPlugin::createDemod(const QString& demodName) PluginGUI* NFMPlugin::createChannel(const QString& channelName)
{ {
if(demodName == "de.maintech.sdrangelove.demod.nfm") { if(channelName == "de.maintech.sdrangelove.channel.nfm") {
PluginGUI* gui = NFMDemodGUI::create(m_pluginAPI); NFMDemodGUI* gui = NFMDemodGUI::create(m_pluginAPI);
m_pluginAPI->registerDemodulatorInstance("de.maintech.sdrangelove.demod.nfm", gui); m_pluginAPI->registerChannelInstance("de.maintech.sdrangelove.channel.nfm", gui);
m_pluginAPI->addChannelRollup(gui);
return gui; return gui;
} else { } else {
return NULL; return NULL;
@ -46,6 +47,7 @@ PluginGUI* NFMPlugin::createDemod(const QString& demodName)
void NFMPlugin::createInstanceNFM() void NFMPlugin::createInstanceNFM()
{ {
m_pluginAPI->registerDemodulatorInstance("de.maintech.sdrangelove.demod.nfm", NFMDemodGUI::create(m_pluginAPI)); NFMDemodGUI* gui = NFMDemodGUI::create(m_pluginAPI);
m_pluginAPI->registerChannelInstance("de.maintech.sdrangelove.channel.nfm", gui);
m_pluginAPI->addChannelRollup(gui);
} }

View File

@ -7,7 +7,7 @@
class NFMPlugin : public QObject, PluginInterface { class NFMPlugin : public QObject, PluginInterface {
Q_OBJECT Q_OBJECT
Q_INTERFACES(PluginInterface) Q_INTERFACES(PluginInterface)
Q_PLUGIN_METADATA(IID "de.maintech.sdrangelove.demod.nfm") Q_PLUGIN_METADATA(IID "de.maintech.sdrangelove.channel.nfm")
public: public:
explicit NFMPlugin(QObject* parent = NULL); explicit NFMPlugin(QObject* parent = NULL);
@ -15,7 +15,7 @@ public:
const PluginDescriptor& getPluginDescriptor() const; const PluginDescriptor& getPluginDescriptor() const;
void initPlugin(PluginAPI* pluginAPI); void initPlugin(PluginAPI* pluginAPI);
PluginGUI* createDemod(const QString& demodName); PluginGUI* createChannel(const QString& channelName);
private: private:
static const PluginDescriptor m_pluginDescriptor; static const PluginDescriptor m_pluginDescriptor;